Archive for the 'NSSplitView' Category

2016/02/01 指定の名称のフォントの見本を表示

指定のPostScript名称のフォントの見本をウィンドウ表示するAppleScriptです。

Script Editor上ではControl+Command+Rで実行する必要があります。

NSFont経由で指定フォントが含む文字セットを取得し、どの文字が含まれているのかをチェックしたい、という目的のために作成したものです。ウィンドウを作成して文字表示しているのは、あくまで「おまけ」です。

font1.png

NSFontにcoveredCharacterSet()で指定フォントが持っている文字セットを取得。この文字セットの中に含まれている文字を、1〜65535の数値で(文字を作ってチェックしたらダメで、数値)存在チェックしています。ここだけ、ループでいちいち調べているので時間がかかります(MacBook Pro Retina 2012で4秒ぐらい)。ここは、もうちょっとなんとかならないかと思っています。

また、OS標準のFont Book.appで調べたグリフ数とNSFont→NSCharacterSet経由で存在確認して得られるCharacter数は異なっているため、自分としてはちょっと肩透かしをくらいました。Font Book.appだと各フォントが含んでいる文字といった細かい情報が取得できないため、NSFont経由で調査してみたのですが・・・フォント内の各文字(コード)が実際にグリフを持っているかどうかは、文字セット中の文字を実際にレンダリングしてみないとダメそうな気配がしています(文字コードだけ宣言しておいて何も割り当てグリフがないというケースとか、同じ文字コードに複数のグリフが割り当てられているケースなど(「高」と「癲廖覆呂靴瓦世)など)、深入りするとトンでもないものがありそう)。

AppleScript中で指定している「TheLittleBirdFONT」は、手書き風日本語文字フォントの傑作「ことり文字ふぉんと」(自分が使っているのは大昔に無償配布されていたバージョン)です。OS標準でインストールされているわけではないため、動作チェックには他のものを指定したほうがよいでしょう。

font2.png

ことり文字ふぉんとの独特の特殊記号がどこに入っているかを忘れてしまったため、とりあえず文字セット中の文字をすべてことり文字ふぉんとで表示して「簡易フォント見本帖」のように使ってみたりもしました。

AppleScript名:ASOCでテキストビュー+ボタンを作成(フォント指定)
– Created 2016-02-01 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “Carbon” – AEInteractWithUser() is in Carbon

property windisp : false

set aFontName to “TheLittleBirdFONT”
set aWidth to 450
set aHeight to 600

if current application’s AEInteractWithUser(-1, missing value, missing value) is not equal to 0 then return

set aTitle to “テキストビューのじっけん/TextView Test” –Window Title
set aButtonMSG to “OK” –Button Title

–表示用テキストの作成
set aRes to checkExistenceOfFont(aFontName) of me
if aRes = false then
  display dialog “There is no < " & aFontName & “> font. Designate another one.” –No font
  
return
end if
set bRes to retDefinedCharactersInFont(aFontName) of me
set dispStr to listToStringUsingTextItemDelimiter(bRes, “, “) of me

dispTextView(aWidth, aHeight, aTitle, dispStr, aButtonMSG, 180, aFontName, 36) of me

on dispTextView(aWidth as integer, aHeight as integer, aTitle as text, dispStr, aButtonMSG as text, timeOutSecs as number, fontID, fontSize)
  
  
set aColor to current application’s NSColor’s colorWithDeviceRed:0.0 green:0.0 blue:0.0 alpha:1.0
  
set (my windisp) to true
  
  
–Text View+Scroll Viewをつくる
  
set aScroll to current application’s NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
set aView to current application’s NSTextView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
aView’s setRichText:true
  
aView’s useAllLigatures:true
  
aView’s setTextColor:(current application’s NSColor’s yellowColor()) –cyanColor
  
aView’s setFont:(current application’s NSFont’s fontWithName:fontID |size|:fontSize) –ヒラギノ明朝Pro W3
  
aView’s setBackgroundColor:aColor
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
–Buttonをつくる
  
set bButton to (current application’s NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, 40)))
  
bButton’s setTitle:aButtonMSG
  
bButton’s setTarget:me
  
bButton’s setAction:(“clicked:”)
  
  
–SplitViewをつくる
  
set aSplitV to current application’s NSSplitView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aHeight, aWidth))
  
aSplitV’s setVertical:false
  
  
aSplitV’s addSubview:aScroll
  
aSplitV’s addSubview:bButton
  
aSplitV’s setNeedsDisplay:true
  
  
–WindowとWindow Controllerをつくる
  
set aWin to makeWinWithView(aSplitV, aWidth, aHeight, aTitle, 0.9)
  
aWin’s makeKeyAndOrderFront:(missing value)
  
set wController to current application’s NSWindowController’s alloc()
  
wController’s initWithWindow:aWin
  
aWin’s makeFirstResponder:aView
  
aView’s setString:dispStr
  
wController’s showWindow:me
  
  
set aCount to timeOutSecs * 10 –timeout seconds * 10
  
repeat aCount times
    if (my windisp) = false then
      exit repeat
    end if
    
delay 0.1
    
set aCount to aCount - 1
  end repeat
  
  
my closeWin:aWin
  
end dispTextView

–Button Clicked Event Handler
on clicked:aSender
  set (my windisp) to false
end clicked:

–make Window for Input
on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle, alphaV)
  set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {aWinWidth, aWinHeight}}
  
set aBacking to current application’s NSTitledWindowMask –NSBorderlessWindowMask
  
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)
  
–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:false
  
aWin’s setLevel:(current application’s NSNormalWindowLevel)
  
aWin’s setOpaque:false
  
aWin’s setAlphaValue:alphaV –append
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
–aWin’s makeKeyAndOrderFront:(me)
  
  
– Set Custom View
  
aWin’s setContentView:aView
  
  
return aWin
  
end makeWinWithView

–close win
on closeWin:aWindow
  repeat with n from 10 to 1 by -1
    (aWindow’s setAlphaValue:n / 10)
    
delay 0.02
  end repeat
  
aWindow’s |close|()
end closeWin:

–指定PostScript名称のフォントがコンピューター上に存在するかどうかチェック
on checkExistenceOfFont(fontName as string)
  if fontName = “” then return false
  
set aFont to current application’s NSFont’s fontWithName:fontName |size|:9.0
  
if aFont = missing value then
    return false
  else
    return true
  end if
end checkExistenceOfFont

–指定Postscript名称のフォントに定義されている文字数を数えて返す
on countDefinedCharactersInFont(fontName as string)
  
  
script spdF
    property aList : {}
  end script
  
  
set aFont to current application’s NSFont’s fontWithName:fontName |size|:9.0
  
if aFont = missing value then return false
  
  
set aSet to aFont’s coveredCharacterSet()
  
  
set aList of spdF to {}
  
  
repeat with i from 1 to 65535
    set aRes to (aSet’s characterIsMember:i) as boolean
    
if aRes = true then
      set the end of aList of spdF to (string id i)
    end if
  end repeat
  
  
return length of (aList of spdF)
  
end countDefinedCharactersInFont

–指定Postscript名称のフォントに定義されている文字を返す
on retDefinedCharactersInFont(fontName as string)
  
  
script spdG
    property aList : {}
  end script
  
  
set aFont to current application’s NSFont’s fontWithName:fontName |size|:24.0
  
set aSet to aFont’s coveredCharacterSet()
  
  
set aList of spdG to {}
  
  
repeat with i from 1 to 65535
    set aRes to (aSet’s characterIsMember:i) as boolean
    
if aRes = true then
      set the end of aList of spdG to (string id i)
    end if
  end repeat
  
  
return (aList of spdG)
  
end retDefinedCharactersInFont

on listToStringUsingTextItemDelimiter(sourceList, textItemDelimiter)
  set the CocoaArray to current application’s NSArray’s arrayWithArray:sourceList
  
set the CocoaString to CocoaArray’s componentsJoinedByString:textItemDelimiter
  
return (CocoaString as string)
end listToStringUsingTextItemDelimiter

★Click Here to Open This Script 

2015/12/10 スライダー+ボタンを動的に生成

Cocoaの機能を用いて、NSSplitViewを作成して、その中にNSSliderとNSButtonを入れてSliderの値を取得するAppleScriptです。

動的にWindow+Split Viewを作成して、SliderとButtonも作成。SliderについてはWindowのタイトル部分に値を表示させ、ボタンを押すとウィンドウを閉じてSliderの値を取得します。

splitv.png

フルセットのWindowを作成するほどではないが、ユーザーにSliderで値を設定してほしいような場合を想定しています。

AppleScript名:ASOCでslider+buttonを作成 v2
– Created 2015-12-10 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property windisp : false
property aSliderValMSG : ""

set aMaxVal to 10
set aButtonMSG to "OK"
set aSliderValMSG to "スライダーの設定値:"
set aVal to getSliderValue(aMaxVal, aButtonMSG, aSliderValMSG) of me

on getSliderValue(aMaxVal, aButtonMSG, aSliderValMSG)
  set (my windisp) to true
  
set (my aSliderValMSG) to aSliderValMSG
  
  
set aView to current application’s NSSplitView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 360, 40))
  
aView’s setVertical:false
  
  
–Sliderをつくる
  
set aSlider to makeSider(aMaxVal) of me
  
  
–Buttonをつくる
  
set bButton to (current application’s NSButton’s alloc()’s init())
  
bButton’s setTitle:aButtonMSG
  
bButton’s setTarget:me
  
bButton’s setAction:("clicked:")
  
  
aView’s addSubview:aSlider
  
aView’s addSubview:bButton
  
aView’s setNeedsDisplay:true
  
  
set aWin to (my makeWinWithView(aView, 400, 80, aSliderValMSG & (aMaxVal div 2) as string))
  
  
set aCount to 1800
  
repeat aCount times
    if (my windisp) = false then
      exit repeat
    end if
    
delay 0.1
    
set aCount to aCount - 1
  end repeat
  
  
my closeWin:aWin
  
  
set sVal to aSlider’s intValue()
  
return sVal
end getSliderValue

on sliderChanged:aSender
  set aVal to aSender’s intValue()
  
set parentWin to aSender’s |window|()
  
parentWin’s setTitle:(my aSliderValMSG & (aVal as text))
end sliderChanged:

on clicked:aSender
  set (my windisp) to false
end clicked:

–make Window for Display
on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle)
  set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {aWinWidth, aWinHeight}}
  
  
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)
  
–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:false
  
aWin’s setLevel:(current application’s NSNormalWindowLevel)
  
aWin’s setOpaque:false
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
aWin’s makeKeyAndOrderFront:(me)
  
  
aWin’s setContentView:aView
  
  
return aWin
  
end makeWinWithView

–close win
on closeWin:aWindow
  repeat with n from 10 to 1 by -1
    (aWindow’s setAlphaValue:n / 10)
    
delay 0.02
  end repeat
  
aWindow’s |close|()
end closeWin:

on makeSider(aMaxNum)
  set aSlider to current application’s NSSlider’s alloc()’s init()
  
aSlider’s setMaxValue:aMaxNum
  
aSlider’s setMinValue:1
  
aSlider’s setNumberOfTickMarks:aMaxNum
  
aSlider’s setKnobThickness:50
  
aSlider’s setAllowsTickMarkValuesOnly:true
  
aSlider’s setTickMarkPosition:(current application’s NSTickMarkBelow)
  
aSlider’s setIntValue:(aMaxNum div 2)
  
aSlider’s setTarget:me
  
aSlider’s setAction:("sliderChanged:")
  
return aSlider
end makeSider

★Click Here to Open This Script