Archive for the 'NSView' Category

2015/08/20 ASOCでdate pickerによる日付選択

Shane StanleyのScript Library「BridgePlus」の機能を用いた日付/時刻選択インタフェース「date picker」による日付/時刻選択を行うAppleScriptです。実行には、あらかじめBridgePlusをインストールしておく必要があります。

datepicker1.png
▲ASObjC Explorer 4での実行画面

datepicker2.png
▲Script Editorでの実行画面(Control-Command-R)

そうそう、こういうのが(OS標準で)欲しかったんですよね〜。あと、開始日と終了日の選択とか、休日を選択できないようにできるといいかも。

AppleScript名:ASOCでdate pickerによる日付選択
– Created 2015-08-20 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use script “BridgePlus” – for pre-10.11 compatibility

if not (current application’s NSThread’s isMainThread()) as boolean then
  display alert “This script must be run from the main thread.” buttons {“Cancel”} as critical
  
error number -128
end if

– create a view
set theView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 100, 200))

– create date picker
set datePicker to current application’s NSDatePicker’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 100, 100))

– set style: choices are NSTextFieldAndStepperDatePickerStyle, NSClockAndCalendarDatePickerStyle, or NSTextFieldDatePickerStyle
datePicker’s setDatePickerStyle:(current application’s NSClockAndCalendarDatePickerStyle)

– set elements: choices include NSHourMinuteDatePickerElementFlag, NSHourMinuteSecondDatePickerElementFlag, NSTimeZoneDatePickerElementFlag, NSYearMonthDatePickerElementFlag, and NSEraDatePickerElementFlag
datePicker’s setDatePickerElements:((current application’s NSYearMonthDayDatePickerElementFlag) + (current application’s NSHourMinuteSecondDatePickerElementFlag as integer))

– set initial date
datePicker’s setDateValue:(current application’s NSDate’s |date|())

– get the size it needs
set theSize to datePicker’s fittingSize()

–resize the picker and view accordingly
theView’s setFrameSize:theSize
datePicker’s setFrameSize:theSize

– add the picker to the view
theView’s setSubviews:{datePicker}

– create an alert
set theAlert to current application’s NSAlert’s alloc()’s init()

– set up alert
tell theAlert
  its setMessageText:“Pick a date”
  
its setInformativeText:“Any date”
  
its addButtonWithTitle:“OK”
  
its addButtonWithTitle:“Cancel”
  
its setAccessoryView:theView
end tell

– show alert in modal loop
set returnCode to theAlert’s runModal()
if returnCode = (current application’s NSAlertSecondButtonReturn) then error number -128

– retrieve date
set theDate to ASify from (datePicker’s dateValue()) – or simply coerce to date in 10.11

–>  date “2015年8月20日木曜日 19:43:58″

★Click Here to Open This Script 

2015/08/20 ASOCで動的にWindowを作成

Cocoaの機能を用いて動的にWindowを作成し、メッセージを表示したあとにWindowを消すAppleScriptです。

dispcustomwin.png

Mac OS X登場当時から、こうしたカスタムメッセージ表示用の部品の必要性がひろくscripterに認識されており、さまざまな実装が試されたなか・・・OS Xのnotification center(display notificationでAppleScriptからも表示可能)に集約されていったという歴史があります。

notification.png

オリジナルは、edama2さんの「Okaeri(シンプル版)」のコードで、そこから大幅に機能を簡略化し、当時のCocoa AppleScript Appletから、OS X 10.10上のAppleScriptObjC向けに書き換えたものです。

dispcustomwin2_resized.png

AppleScript側から汎用的にメッセージを表示させるサブルーチンに変更してみました。かなり手軽に使えます。ASOCはARC環境で動いているので、Windowオブジェクトを明示的にReleaseしてあげる必要はないはずですが・・・さて?

# 連続して実行すると3回目に表示がおかしくなるのは、、、何か足りないかも、、、まだ油断できないレベルです

Shaneから「foreground/main threadから実行する必要があるよ」という指摘があり、ASObjC Explorer 4では問題なく連続して何回でも実行できることを確認。Script EditorだとCommand-Control-Rを実行して、表示がすぐに消えたりやっぱり3回目にScript Editorごとクラッシュしたりと不思議な現象が(ーー;;;

AppleScript名:ASOCで動的にWindowを作成
– Created 2012-06-13 by edama2
– Modified 2015-08-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

if not (current application’s NSThread’s isMainThread()) as boolean then
  display alert “This script must be run from the main thread (Command-Control-R in Script Editor).” buttons {“Cancel”} as critical
  
error number -128
end if

set aWin to makeWinWithMessage(“Piyomaru Software”, “Custom Message From Takaaki Naganoya”)
tell current application
  delay 5
end tell
my closeWin:aWin

–ウィンドウを作成
on makeWinWithMessage(aTitle, aMes)
  
  
set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {800, 250}}
  
set aBacking to current application’s NSTitledWindowMask
  
set aDefer to current application’s NSBackingStoreBuffered
  
  
– Window
  
set aWin to current application’s NSWindow’s alloc()
  (
aWin’s initWithContentRect:aFrame styleMask:aBacking backing:aDefer defer:false screen:aScreen) –’s autorelease()
  
aWin’s setBackgroundColor:(current application’s NSColor’s whiteColor())
  
  
aWin’s setTitle:aTitle
  
aWin’s setDelegate:me
  
aWin’s setDisplaysWhenScreenProfileChanges:true
  
aWin’s setHasShadow:true
  
aWin’s setIgnoresMouseEvents:true
  
aWin’s setLevel:(current application’s NSNormalWindowLevel)
  
aWin’s setOpaque:false
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
aWin’s makeKeyAndOrderFront:(me)
  
  
– Custom View
  
set aCustView to current application’s NSView’s alloc()
  
aCustView’s initWithFrame:aFrame
  
aCustView’s setNeedsDisplay:true
  
set {origin:{x:x, y:y}, |size|:{width:w, height:h}} to aCustView’s |bounds|()
  
aWin’s setContentView:aCustView
  
  
– Text View
  
set aTV2 to current application’s NSTextView’s alloc()
  
  
set titleHeight to 26
  
set y2 to h - titleHeight - (titleHeight / 6)
  
set y3 to h - titleHeight
  
set y3 to h - y3 - (y3 / 6)
  
  
aTV2’s initWithFrame:{{0, y3}, {w, y2}}
  
aTV2’s insertText:aMes
  
aTV2’s setAlignment:(current application’s NSCenterTextAlignment)
  
aTV2’s setDrawsBackground:false
  
aTV2’s setEditable:false
  
aTV2’s setFont:(current application’s NSFont’s fontWithName:“HiraMinPro-W3″ |size|:72)
  
aTV2’s setSelectable:false
  
aTV2’s setTextColor:(current application’s NSColor’s blackColor())
  
aCustView’s addSubview:aTV2
  
  
–aWin’s setBackgroundColor:(current application’s NSColor’s clearColor())
  
  
return aWin
  
end makeWinWithMessage

–ウィンドウを閉じる
on closeWin:aWindow
  delay 3
  
repeat with n from 10 to 1 by -1
    (aWindow’s setAlphaValue:n / 10)
    
delay 0.02
  end repeat
  
aWindow’s |close|()
end closeWin:

★Click Here to Open This Script