OSX Drag Picture
スクリーンショットを対話的にとるとき、マウスでドラッグして選択するのがあるけど、あれってどうやってやるんだろうって考えてた。
マウスイベントをキャプチャーして……とか面倒くさそうだなぁとか思ってたけど全然違う方法で実装できそうだ。
require 'osx/cocoa'
include OSX
class SelectionView < NSView
attr_accessor :delegate
def drawRect(rect)
NSColor.colorWithCalibratedRed(0, :green, 0, :blue, 0, :alpha, 0.1).set
NSRectFill(bounds)
if @start && @end
NSColor.colorWithCalibratedRed(0.5, :green, 0.5, :blue, 0.5, :alpha, 0.5).set
NSRectFill(calc_rect)
end
end
def mouseDown(event)
@start = NSEvent.mouseLocation
end
def mouseDragged(event)
@end = NSEvent.mouseLocation
setNeedsDisplay(true)
end
def mouseUp(event)
@end = NSEvent.mouseLocation
delegate.windowShouldClose(nil)
window.close
end
def calc_rect
x = [@start.x , @end.x].min
y = [@start.y , @end.y].min
w = (@start.x - @end.x).abs
h = (@start.y - @end.y).abs
[x, y, w, h]
end
end
class TEST < NSObject
def applicationDidFinishLaunching(aNotification)
size = NSScreen.mainScreen.frame.size
rect = [0, 0, size.width, size.height]
@window = NSWindow.alloc.initWithContentRect(rect,
:styleMask, NSBorderlessWindowMask,
:backing, NSBackingStoreBuffered,
:defer, 0)
@window.setDelegate(self)
@window.setOpaque(0)
@window.setHasShadow(0)
@window.setLevel(1000) # NSScreenSaverWindowLevel
@view = SelectionView.alloc.initWithFrame(rect)
@view.delegate = self
@window.setContentView(@view)
@window.makeKeyAndOrderFront(nil)
@window.orderFrontRegardless
end
def windowShouldClose(sender)
p @view.calc_rect
exit
true
end
end
$App = NSApplication.sharedApplication
$App.setDelegate(TEST.alloc.init)
$App.run
スクリーンと同じサイズのできるだけ透明なウィンドウを作ってあげてそいつでイベントうけとる。