前回までの検証結果を SimpleCapへ反映する。まずはアプリケーションキャプチャ用のメニューの追加。
こんな感じ。
- - - -
アイコンを 32x32にしてみた。チトでかいが視認性は良い。このあたりは今後調整していく。
2008年7月31日木曜日
SimpleCap (30) アプリケーションキャプチャ(1)
2008年7月30日水曜日
2008年7月29日火曜日
起動中のアプリ調査 (5) メニュー表示
次にメニュー。SimpleCapでやりたいのはメニューに起動中のアプリケーション一覧を出して、ユーザに選択させること。前回までのコードをベースにやってみた。NSCollectionView は確認の為だけに使ったので今回は削除してある。
こんな感じ。
いい感じだ。思ったよりも簡単にできた。
ソース:AppList-2.zip
2008年7月28日月曜日
起動中のアプリ調査 (4) アイコン表示(サイズ)
以前紹介したように NSWorkspace#iconForFile で取得できるアイコン画像はサイズが数種類用意されている。
Finderの例。
NSImage 0x180a60 Size={32, 32} Reps=(
NSIconRefBitmapImageRep 0x182530 Size={128, 128} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=128x128 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x182590 Size={256, 256} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=256x256 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x1827e0 Size={512, 512} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=512x512 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x182820 Size={32, 32} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=32x32 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x182860 Size={16, 16} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=16x16 Alpha=YES Planar=NO Format=0
]
前回 NSCollectionImageView で表示されていたサイズは 32x32だった。これを 16x16に変えてみる。アイコン画像生成時に単純に NSImage#setSize でサイズを指定してみた。
icon = [ws iconForFile:[app objectForKey:@"NSApplicationPath"]];
[icon setSize:NSMakeSize(16, 16)];
いい感じだ。
調子にのって 512x512
おお、奇麗に出てている。サイズに合わせて適切な元画像を使用してくれているようだ。なおサンプルでは NSImageView によって縮小されて表示されているの見た目 512x512より小さいのであしからず(ややこしいが)。
2008年7月27日日曜日
起動中のアプリ調査 (3) アイコン表示
起動中のアプリケーションのアイコンを NSCollectionView を使い一覧表示してみる。
NSCollectionView の使い方は過去のブログを参照の事。
こんな感じ。
アイコン画像を用意するコードだけ紹介するとこんな感じ。
NSImage* icon;
_icons = [[NSMutableArray alloc] init];
NSWorkspace* ws = [NSWorkspace sharedWorkspace];
for (NSDictionary* app in [ws launchedApplications]) {
icon = [ws iconForFile:[app objectForKey:@"NSApplicationPath"]];
[_icons addObject:[NSDictionary dictionaryWithObject:icon forKey:@"image"]];
}
上記で用意した _icons へ NSCollectionViewをバインドすれば簡単に表示できる(バインドのパスは長いが。。)。
ソースコード:AppList-1.zip
2008年7月26日土曜日
起動中のアプリ調査 (2) アイコン
アイコン画像は同じく NSWorkspace のメソッドで取得ができる。
NSImage* icon = [[NSWorkspace sharedWorkspace] iconForFile:@"/System/Library/CoreServices/Finder.app"];
上記を実行すると iconの内容は次のようになった。
2008-07-02 21:11:48.169 AppList[1091:10b] (
NSImage 0x1815d0 Size={32, 32} Reps=(
NSIconRefBitmapImageRep 0x181930 Size={128, 128} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=128x128 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x181aa0 Size={256, 256} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=256x256 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x181ae0 Size={512, 512} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=512x512 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x181b20 Size={32, 32} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=32x32 Alpha=YES Planar=NO Format=0,
NSIconRefBitmapImageRep 0x181b60 Size={16, 16} ColorSpace=NSCalibratedRGBColorSpace BPS=8 BPP=32 Pixels=16x16 Alpha=YES Planar=NO Format=0
)
)
複数の画像が用意されているのがわかる。
2008年7月25日金曜日
起動中のアプリ調査 (1)
起動中のアプリケーション情報を元にしたキャプチャを考えている。具体的な内容はこれからおいおい明らかにするとして、まずは現在実行中のアプリケーション情報はどのようなものが取れるかを検証していく。
Cocoaには NSWorkspace が用意されていて #launchedApplications メソッドで実行中のアプリケーション情報を取得することができる。
試しに簡単なコードを書いてみた。
NSWorkspace* ws = [NSWorkspace sharedWorkspace];
NSLog(@"%@", [ws launchedApplications]);
結果は次の通り。
2008-07-02 20:46:42.048 AppList[757:10b] (
{
NSApplicationBundleIdentifier = "com.apple.finder";
NSApplicationName = Finder;
NSApplicationPath = "/System/Library/CoreServices/Finder.app";
NSApplicationProcessIdentifier = 156;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 49164;
},
{
NSApplicationBundleIdentifier = "com.apple.Safari";
NSApplicationName = Safari;
NSApplicationPath = "/Applications/Safari.app";
NSApplicationProcessIdentifier = 284;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 102425;
},
{
NSApplicationBundleIdentifier = "com.apple.mail";
NSApplicationName = Mail;
NSApplicationPath = "/Applications/Mail.app";
NSApplicationProcessIdentifier = 285;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 106522;
},
{
NSApplicationBundleIdentifier = "etd.happy.catsan.programming";
NSApplicationName = EasyToDo;
NSApplicationPath = "/Applications/\U30c4\U30fc\U30eb/EasyToDo.app";
NSApplicationProcessIdentifier = 292;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 110619;
},
{
NSApplicationBundleIdentifier = "com.apple.Preview";
NSApplicationName = "\U30d7\U30ec\U30d3\U30e5\U30fc";
NSApplicationPath = "/Applications/Preview.app";
NSApplicationProcessIdentifier = 343;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 127007;
},
{
NSApplicationBundleIdentifier = "com.apple.iTunes";
NSApplicationName = iTunes;
NSApplicationPath = "/Applications/iTunes.app";
NSApplicationProcessIdentifier = 470;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 196656;
},
{
NSApplicationBundleIdentifier = "com.apple.Xcode";
NSApplicationName = Xcode;
NSApplicationPath = "/Developer/Applications/Xcode.app";
NSApplicationProcessIdentifier = 692;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 381021;
},
{
NSApplicationBundleIdentifier = "com.yourcompany.AppList";
NSApplicationName = AppList;
NSApplicationPath = "/Users/hashi/development/study/AppList/build/Debug/AppList.app";
NSApplicationProcessIdentifier = 757;
NSApplicationProcessSerialNumberHigh = 0;
NSApplicationProcessSerialNumberLow = 389215;
}
)
*
バンドルIdentifier や名前、プログラムパス、プロセスIDなどが取れる。
2008年7月24日木曜日
SimpleCap (29) α2公開
SimpleCap α2版を公開します。
実行ファイル(α2版)SimpleCap-7.zip
**α版につきコピーや配布は禁止とさせて下さい。配布条件は正式リリース時に提示します。**
目玉は?ウィンドウトラッキングモード (Track Window)。
α版を試した奇特な方は是非感想をコメントして下さい。
2008年7月23日水曜日
SimpleCap (28)ウィンドウトラッキング(7)
2008年7月22日火曜日
SimpleCap (27)ウィンドウトラッキング(6)
以前、ウィンドウトラッキングでボタンのマウスオーバーが効かない問題を書いた。コードを見直したところ NSTrackingArea を作る時のオプションを変えることで解決できた。修正個所はボタンのビュークラス ThinButtonBar.m 内の NSTrackingArea生成個所。
ThinButtonBar.m
_tracking_area = [[NSTrackingArea alloc] initWithRect:tracking_rect
options:(NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved | NSTrackingActiveInKeyWindow)
最後のオプションに NSTrackingActiveInKeyWindow を指定していたのをやめて、NSTrackingActiveAlways に変更した。
_tracking_area = [[NSTrackingArea alloc] initWithRect:tracking_rect
options:(NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved | NSTrackingActiveAlways)
オプションの意味は定数名称の通りでウィンドウがアクティブなキーウィンドウの時のみ(NSTrackingActiveInKeyWindow)か、もしくはアクティブ状態に関わらずいつでも(NSTrackingActiveAlways)となる。ヘッダファイルのコメントも見てみよう。
NSTrackingArea.h
/* When tracking area is active. You must specify one of the following in the NSTrackingAreaOptions argument of -initWithRect:options:owner:userInfo: */
enum {
NSTrackingActiveWhenFirstResponder = 0x10, // owner receives mouseEntered/Exited, mouseMoved, or cursorUpdate when view is first responder
NSTrackingActiveInKeyWindow = 0x20, // owner receives mouseEntered/Exited, mouseMoved, or cursorUpdate when view is in key window
NSTrackingActiveInActiveApp = 0x40, // owner receives mouseEntered/Exited, mouseMoved, or cursorUpdate when app is active
NSTrackingActiveAlways = 0x80, // owner receives mouseEntered/Exited or mouseMoved regardless of activation. Not supported for NSTrackingCursorUpdate.
};
- - - - -
これでウィンドウトラッキングができた。さていよいよ最後のアプリケーションキャプチャに取りかかろう。
2008年7月21日月曜日
SimpleCap (26) キャプチャ状態をステータスバーに反映
キャプチャ実行中は一目でわかるようにステータスバー上のアイコンを反転させることにした。
SimpleCapの実装は次のようになっている。
メニュー選択(イベント発生)
|処理開始
↓
AppController ---> StatusBar管理
|
↓
CaptureContoller ---> キャプチャ処理(Handler)管理
|
↓
キャプチャの開始と終了は各レイヤーで処理がしやすいように CaptureControllerが中心となって所定のメソッドを呼出すようになっている。
例えば、
AppController <----CaptureController---->
#startCapture キャプチャ開始 #start
#stopCapture キャプチャ終了 #tearDown
ステータスバーは AppControllerが管理しているので、このコールバックメソッドを使いアイコンを入れ替えている。
こんな感じ。
AppContorller.m- (void)startCapture
{
[self setIconStart];
}
- (void)exitCapture
{
[self setIconStop];
_state = SCStateNormal;
}
2008年7月20日日曜日
SimpleCap (25)ウィンドウトラッキング(5)
続き。
いろいろいじっていたら解決した。結論は NSWindow#canBecomKeyWindow で NOを返す様にした。するとターゲットウィンドウを非アクティブにすることなくボタンを押すことができるようになった。
- (BOOL)canBecomeKeyWindow
{
return NO;
}
他のカスタムウィンドウのコピーをひな形としていたのだが、これが YESになっていたのが原因。おお。解決まで時間が少しかかったのでちょっとうれしい。
調子にのってウィンドウを連写、連写、連写。
まずトラッキングウィンドウを起動しターゲットを定める。
そこでぱちり。
サイズを変えてキャプチャ。
さらにサイズを変えてキャプチャ。この間、トラッキング続行中。
スクロール移動しキャプチャ。
繰り返し。
繰り返し。
おお、思ったよりもいい感じだ。
- - - -
いい事ばかりでなくて不具合も見つかった。ボタンがマウスオーバーで変化しない。うーむ。
2008年7月19日土曜日
SimpleCap (24)ウィンドウトラッキング(4)
ウィンドウトラッキングがだいたいできたのだが大きな問題が一つ。ボタンの載っているウィンドウがアクティブにならないとボタンが押せない。ボタンが 非アクティブでボタンが押せて、さらに非アクティブなままにしたい。現状はこれがうまくできていないので動作が怪しい。ボタンが載っているのは透明なカスタムパネル(NSPanel)で次のように作っている。
ToolWindow.m
- (id)init
{
NSRect frame = NSZeroRect;
self = [super initWithContentRect:frame
styleMask:NSBorderlessWindowMask|NSNonactivatingPanelMask|NSUtilityWindowMask
backing:NSBackingStoreBuffered
defer:NO];
if (self) {
[self setReleasedWhenClosed:YES];
[self setDisplaysWhenScreenProfileChanges:YES];
[self setBackgroundColor:[NSColor clearColor]];
[self setOpaque:NO];
[self setHasShadow:NO];
[self setLevel:NSScreenSaverWindowLevel+2];
[self setIgnoresMouseEvents:NO];
[self setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
}
return self;
}
さて、どうしたものか。以前作ったことのあるカレンダーはそういった動作になっているのだが、何故うまく行っているのだろう?(自問)。
2008年7月18日金曜日
SimpleCap (23)ウィンドウトラッキング(3)
続き)。
単純なトラッキングだとターゲットのウィンドウが下に隠れた場合、ボタン表示だけが残り間抜けな状態になる。
例えば下記の状態で、ウィンドウを下にすると。。
ボタンと点線だけが残ってしまう。
そこでウィンドウトラッキングコード (#updateWindows)の中でウィンドウの表示位置を調べ通常ウィンドウ内で一番上に来ていない場合はボタンを表示しないようにする。
- (BOOL)updateWindows
{
:
for (i=0; i < CFArrayGetCount(window_list); i++) {
window = CFArrayGetValueAtIndex(window_list, i);
:
if ([self isWindow:window normalWindow:YES]) { // 標準的なウィンドウが対象
j++; // 順番を取っておく(j=1, 2, 3...)
}
if (window_id == _tracked_window_id) { // ウィンドウリスト内にターゲットウィンドウが見つかった。
:
if (j == 1) {
[self changeState:STATE_SELECTED]; // j==1すなわち一番上ならボタンを表示に
} else {
[self changeState:STATE_HIDE]; // それ以外はボタンを隠す
}
is_exists = YES;
break;
}
}
CFRelease(window_list);
return is_exists;
}
2008年7月17日木曜日
SimpleCap (22)ウィンドウトラッキング(2)
前回の続き。
新たに "Track Window" をメニューに追加した。
この処理を行なう為に新たに TrackWindowHandler: HandlerBase
キャプチャ開始後にタイマーをしかけ、0.1秒毎にウィンドウの最新位置をチェックしている。
0.1秒毎に呼出されるコールバックメソッド。- (void)callBack:(NSTimer*)timer
{
if ([self updateWindows]) {
[self updateButtonWindow];
CaptureView* view = [_capture_controller view];
[view setNeedsDisplay:YES];
} else {
:
#updateWindows がトラッキング対象のウィンドウ位置の更新。- (BOOL)updateWindows
{
// sort by lastest order
CFArrayRef window_list = [self getWindowListWindowID:[_capture_controller windowID]];
CFDictionaryRef window;
CFIndex i, j=0;
CGWindowID window_id;
BOOL is_exists = NO;
CGRect cgrect = CGRectZero;
for (i=0; i < CFArrayGetCount(window_list); i++) {
window = CFArrayGetValueAtIndex(window_list, i);
CFNumberGetValue(CFDictionaryGetValue(window, kCGWindowNumber),
kCGWindowIDCFNumberType, &window_id);
if ([self isWindow:window normalWindow:YES]) {
j++;
}
if (window_id == _tracked_window_id) {
CGRectMakeWithDictionaryRepresentation(CFDictionaryGetValue(window, kCGWindowBounds), &cgrect);
_tracked_window_rect = NSRectFromCGRect(cgrect);
if (j == 1) {
[self changeState:STATE_SELECTED];
} else {
[self changeState:STATE_HIDE];
}
is_exists = YES;
break;
}
}
CFRelease(window_list);
return is_exists;
}
ウィンドウが閉じられている場合は is_exists == NO が戻る。
ボタンの位置調整 #updateButtonWindow はベタな処理。#define BUTTON_OFFSET 10.0
- (void)updateButtonWindow
{
NSScreen* screen = [NSScreen mainScreen];
NSRect srect = [screen frame];
NSPoint p = _tracked_window_rect.origin;
NSSize wsize = [_tool_window frame].size;
p.x = p.x + _tracked_window_rect.size.width - wsize.width - BUTTON_OFFSET;
p.y = srect.size.height - wsize.height - p.y - BUTTON_OFFSET;
[_tool_window setFrameOrigin:p];
}
2008年7月16日水曜日
SimpleCap (21)ウィンドウトラッキング
仕事などでたまにあるのが Webアプリケーションのスクリーンショットを撮る作業。1枚ならともかく何枚も撮る場合がある。SimpleCapでこれをサポートしよう。よくあるのがショートカットキー(ホットキー)で連続してキャプチャする方法。悪くはないし実装も楽なのだが、あくまでもショートカットキーは補助的なもので慣れた人向けの機能としては良いが、基本は GUIでうまく使える用に実装すべきだというのが私の考え。そこでショートカットキーは後で実装するとして、 SimpleCapではまず GUIでの実現方法を考える。
一つは専用の子ウィンドウを用意してそこのボタンを押してもらう。悪くない。タイマーウィンドウが似た役割を果たしている。ただそれだと普通?なのでもうひとひねり欲しい。
そこで現在のウィンドウキャプチャ同様に右上にボタンを配置するようにする。それならインターフェイスの統一性も保たれる。
で、やってみた。こんな感じ。
キャプチャ起動時に一番上に表示されていたウィンドウをトラッキング対象として、このウィンドウの右上にボタンを配置する。ウィンドウを移動したりサイズを変更した場合はそれに合わせてボタン位置も調整する。
トラッキングは原始的で、0.1秒毎に対象のウィンドウの位置をチェックしそれに合わせてボタンの載っている透明なウィンドウの位置合わせを行っている。ウィンドウをドラッグすると、ボタンが若干遅れて付いてくる感じだがこれで十分。この辺りは以前のウィンドウのタイマーキャプチャと同じ手法。
2008年7月15日火曜日
SimpleCap (20) 連続キャプチャモード
2008年7月14日月曜日
NSMenuItem にチェックを付ける
SimpleCap に連続キャプチャモードを付ける。モードの切り替えをメニューを使うことにした。
"Continuous mode"を選ぶ。
するとチェックが付く。
NSMenuItemを有効にする為に AppControllerに IBActionメソッドを用意し、IBでメニューのアクションをこれに接続する。これでメニューが有効になる。そして IBACtion内で NSMenuItem#setState: を呼出してやれば良い。
こんな感じ。
- (IBAction)switchContinuousMode:(id)sender
{
[_capture_controller switchContinuousMode];
if ([_capture_controller continuousMode]) {
[sender setState:NSOnState];
} else {
[sender setState:NSOffState];
}
}
投稿者 xcatsan 時刻: 6:36
ラベル: cocoa, NSMenuItem
2008年7月13日日曜日
SimpleCap (19) ウィンドウタイマーに点線(2)
2008年7月12日土曜日
SimpleCap (18) ウィンドウタイマーに点線
2008年7月11日金曜日
SimpleCap (17) ウィンドウタイマーでメニュー取り込み
2008年7月10日木曜日
SimpleCap (16) ウィンドウキャプチャにタイマー追加
ウィンドウキャプチャにタイマーを追加する。ボタンやタイマーダイアログなど基本は既にあるので組み合わせるだけで完成。簡単。
(1) ウィンドウキャプチャを起動し目的のウィンドウを選択する
(2) そしてタイマーを起動する
(3) タイマー実行中にウィンドウを動かしたり、重なり順を変えたりする
(4) 時間が来てキャプチャ実行。その時点でのウィンドウ内容がキャプチャされる。
なお、タイマー実行時点とキャプチャ実行時点では選択していたウィンドウの重なり順が変わっていたり、閉じられたりしている場合がある。その辺りの処理も加えてある。
- - - - -
タイマー実行中にどのウィンドウがキャプチャ対象かがわからない。認識できるような視覚効果が出せないものだろうか。
2008年7月9日水曜日
SimpleCap (15) 複数ウィンドウキャプチャ
さていよいよウィンドウキャプチャを複数ウィンドウに対応させる。操作は Shiftキーを押しながらウィンドウを選ぶと複数選択できて最後にこれら全部をキャプチャできる。
やってみるとそれほど面倒ではなかった。
実行ファイル(α1版)SimpleCap-6.zip
**α版につきコピーや配布は禁止とさせて下さい。配布条件は正式リリース時に提示します。**
※今回からそろそろリリースを意識してα版としてみた。
操作感は次のような感じになる。
(1) 初期状態。これからこの中の3つのウィンドウをキャプチャしてみる。
(2) ウィンドウキャプチャを起動する。一番手前に表示されているウィンドウが選択状態になる。
(3) 後ろにあるウィンドウを選択してみる。一番手前に半透明で表示されるようになる。
(4) 続けて Shiftキーを押しながら別のウィンドウを選択に加えていく。
(5) キャプチャ実行。下図の画像が生成される。
コード解説は長いので今回も割愛。ソースは後日公開予定。
2008年7月8日火曜日
isEqual と compare:
ウィンドウを管理する為に WindowNumber という簡単なクラスを作る。
@interface WindowNumber : NSObject {
int _order;
CGWindowID _window_id;
}
-(int)order;
-(CGWindowID)windowID;
@end
メンバ変数としてウィンドウの並び順(_order)と、WindowIDを持つ。このクラスのオブジェクトを NSMutableArrayで管理する。
この時、同じオブジェクトが配列に既に含まれているかといったチェックと、_orderを使った配列のソートを行いたい。前者は NSArray#containsObject: を後者は NSMutableArray#sortUsingSelector: を使えば実現できる。ただし、それぞれ必要なメソッドを用意しておく必要がある。
(1) containsObject: への対応
リファレンス によるとオブジェクトの同値チェックには NSObject#isEqual: が使われるとのこと。WindowNumber でこれをオーバーライドしてやれば良い。
こんな感じ。WindowNumberの同値性は _window_id でのみ判断する(並び順は無視する)。
- (BOOL)isEqual:(id)anObject
{
if (anObject == self) {
return YES;
}
if (!anObject || ![anObject isKindOfClass:[self class]]) {
return NO;
}
if (_window_id != [anObject windowID]) {
return NO;
}
return YES;
}
これで containsObject: が意図通りに動作するようになる。
(2) sortUsingSelector: への対応
リファレンスによるとオブジェクトを比較するメソッドを追加してやれば良いとのこと。戻り値は比較結果に応じて下記のようになる。
NSOrderedAscending、NSOrderedDescending、NSOrderedSame
メソッドは次の様に実装した。_orderで並び順を決定する。
- (NSComparisonResult)compare:(WindowNumber*)wn
{
int order = [wn order];
if (_order < order) {
return NSOrderedAscending;
} else if (_order > order) {
return NSOrderedDescending;
}
return NSOrderedSame;
}
その上で WindowNumberのオブジェクトを格納した NSMutableArray へ sortUsingSelector: を呼出せば良い。
(例)[array sortUsingSelector:@selector(compare:)];
- - - -
現在複数ウィンドウの同時キャプチャを実装していて、その中でこのクラスを使う。
2008年7月7日月曜日
SimpleCap (14) タイマーダイアログ改良
2008年7月6日日曜日
2008年7月5日土曜日
SimpleCap(12)- タイマーダイアログ組み込み(2)
続いて選択範囲キャプチャとメニューキャプチャのタイマー機能へダイアログを組み込んだ。
選択範囲キャプチャのタイマー動作
メニューキャプチャのタイマー動作
最新版 SimpleCap はこちら(ユニバーサルバイナリ)
SimpleCap.4.zip
- - - -
悪くはないのだがもう一つ何かが欠けている気がする。。
2008年7月4日金曜日
SimpleCap(11)- タイマーダイアログ組み込み
2008年7月3日木曜日
2008年7月2日水曜日
タイマーダイアログ(その9)
カウントの増加が1秒単位だけだと1分など長い時間に設定したい時に使いづらい。ボタンを増やしたくないので Shiftキーを押した時には 10秒単位の増減にしよう。
Shiftキーが押されたかどうかは NSEvent#modifierFlags が利用できる。ボタンが押された時にこの値と NSSfhitKeyMask で論理積(AND)をとってやる。
Shiftキーの有無によってカウントの増減量 dc の設定を変えている。
ThimerControllerm.m
-(void)clickedAtTag:(NSNumber*)tag event:(NSEvent*)event
{
BOOL is_shiftkey = ([event modifierFlags] & NSShiftKeyMask) ? YES : NO;
int dc = 1;
if (is_shiftkey) {
dc = 10;
}
:
元々 ThinButtonBar からのコールバックには NSEventは含まれていなかったので今回これも追加した。
[_delegate performSelector:@selector(clickedAtTag:event:)
withObject:[NSNumber numberWithInt:[hitButton tag]]
withObject:theEvent];
幸いなことに performSelector: には引数2個まで対応しているので簡単にできた。
NSObject.h
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
調子に乗って1000秒まで増やしてみた(それだけ)。