ホームページ>開発ツール>Xojo / Real Studio Trial and Error・CocoaのDeclareでコントロールのカスタマイズ2題
Xojo / Real Studio Trial and Error
目次
CocoaのDeclareでコントロールのカスタマイズ2題
はじめに
以下は、Xojo Cocoaビルドについての話題です。
コントロール全般のカラー(アピアランス・カラー)と、セグメンテッドコントロールのラベル、のカスタマイズについて少し調べてみました。
なお検証には、Xojo 2016 Release 3を用いています。(Mac mini mid 2010 + macOS 10.13.6 High Sierra)
経緯
アピアランス・カラー
コントロールの中には、チェックボックスのチェック時や、ポップアップメニューの矢印部分のように、カラー(注1)が適用されるものがあります。
注1)正式名称が分からないので、本項では「アピアランス・カラー」と記している。このアピアランス・カラーは、システム環境設定>一般>アピアランス、で指定できますが、選択肢はブルーとグラファイトのみで、おまけにコントロールだけでなく、システム全体(メニューバーやウィンドウのタイトルバーとか)に影響を及ぼすので、おいそれとは変更できません。
一方、OS X Yosemite以降ではフラットデザインが採用され、FinderやOS添付アプリのツールバーアイコン等もフラット&モノトーン化されています。
ツールバーをフラット&モノトーン化するのであれば、ウィンドウ内もそれに合わせた色あいにしたい、という場合も出てくるかと思われます。
(ただし、アップルのガイドラインは未調査のため、アピアランス・カラーの変更は何らかの規定に抵触する可能性がない訳ではありませんが…)
そこで、コントロール個別に設定するる方法がないものか調べてみたところ、以下がヒットしました。チェックボックスに限らず、応用できそうです。
参考サイト(1):Xcode - NSButtonのチェックボックスの色を変える|teratail
問題はコードでどう表現するかですが、CIFilterで調べると写真加工のような事例が多くヒットして、なかなかコントロールにまでは辿り着けませんでした。
ようやくNSViewのsetContentFilters:でセットできるところまでは分かったのですが、これだけ実装しても何も変わりませんでした。
更に調べると、setWantsLayer:が必要なことがわかり、セットしてみたら上手くいきました。
なお、このフィルターは、セットしたViewが内包する全てのViewに適用されるようで、例えばウィンドウ(のView)に設定すると、一発で全コントロールに適用できる反面、キャンバス等に描かれた図像は大変なことになります。
個別指定するにしても、タブパネルは要注意で、キャンバスを内包させたい場合には使えません。セグメンテッドコントロール+グループボックス+ページパネルで自作するとかが必要になりそうです。
ノーマル ウィンドウのViewにCIFilter(CIColorMonochrome、色は赤)を適用
セグメンテッドコントロールのラベル
セグメンテッドコントロールには、他のコントロールにあるフォント関連の設定項目がありません。
これはXojoに限ったことではなく、Xcodeでも同様です。(注:Interface Builderでは可能。なぜできるのかは謎(笑)です。)
理由は分かりませんが、例えば以下のトピックの回答者(1の方)が指摘していることとも関係がありそうです。
参考サイト(2):cocoa - NSSegmentedControl (subclass NSSegmentCell) Text Color - Stack Overflow
という訳で、文字で表現するのは難しいと考えられるものの、アイコンは貼り付けられるという特性を利用して、アイコン代わりに文字を描いたイメージを貼る、という方法は使えそうです。
イメージは、画像ソフトであらかじめ作っておいてセットする方法もありますが、ここではカスタマイズの容易さを優先して、実行時に生成する方法にしてみました。
(具体的には、NSMutableAttributedStringを生成後、NSBitmapImageRep経由で描画し、NSImageに変換後、setImage:forSegment:で各セグメントにセットする、というもの。)
注)フォント種別ことのベースライン調整は行なっていない。また、文字色設定は後述するTemplate設定と排他的なため、以下の実装では行なっていない。
また、パラメータはIDEで設定できるようにしてみます。
やり方はXojoのドキュメント(UserGuide-UserInterface.pdf P115)にあるとおり、「インスペクタ・ビヘイビア...」で表示されるダイアログを使います。
なお、フォントについては、名前とサイズだけでは通常のテキストボックスが表示されるだけですが、ボールド/イタリック/アンダーラインを追加すると、他のコントロールと同様のフォントに特化したものとなる(?)ようです。
あと、ネイティブにフォント設定可能なコントロールと異なり、フォント情報を変更してもIDE上の表示には反映されません。
サンプルの仕様
仕様は、以下の通りとしました。
アピアランス・カラー
セグメンテッドコントロールのラベル
- CIFilterを使う。
- フィルター名は、CIColorMonochrome。
- フィルターにセットするパラメータは、inputColorとinputIntensity。
- カラーはCIColor型なので、Xojo RGB -> NSColor -> CIColorと変換する。
- 通常通りインスタンスにセットしたラベルを、指定の修飾でイメージ化して貼り付ける。
- イメージはTemplate設定を有効にし、ハイライトした際の文字が反転するようにする。(他のコントロールに合わせる。その関係で、文字色は黒に固定。)
- ベースライン調整パラメータは、フォントから計算する方法もあると思われるが、ここでは手動とする。
- パラメータはIDEから設定可能にする。
- クラス化する。
- (特に日本語)フォントには、ボールドやイタリック書体がない場合があるため、指定されても見つからなければ無視する。
- ラベルには無関係だが、フォーカスリングを無効化する処理も入れておく。
Xojoでの実装(アピアランス・カラー)
【ソースコードのコピー&ペーストについて】
ソースコード(グレー背景部分の全文)をコピーし、指定のウィンドウ/クラスにペーストすると、(新規作成して名前等を個別にコピー&ペーストしなくても)復元されます。
ただし、この方法は、メソッドでは問題ないようですが、イベント/アクション/プロパティでは不安定?なので、ペーストできない場合は、各項目のカッコ内を適用して下さい。
実行してみたところ、アピアランス・カラーが変更されることを確認しました。
- Xojoで新規プロジェクトを作成
- Window1に、RadioButton2個(Name:RadioButton1、Name:RadioButton2)、PopupMenu(Name:PopupMenu1)を追加
- 以下をWindow1にペースト(できなければ、Sub - Endの間をOpenイベントに記述)
Sub Open() Handles Open SetContentFilters(RadioButton1.Handle,RGB(148,148,148)) SetContentFilters(RadioButton2.Handle,RGB(148,148,148)) SetContentFilters(PopupMenu1.Handle,RGB(148,148,148)) End Sub
- 以下をWindow1にペースト
Private Sub SetContentFilters(hndl As Integer, rgbc As Color) // 文字列を指定してクラスオブジェクト/セレクタを取得する。最初に一回宣言しておけばよい。 Declare Function NSClassFromString Lib "Cocoa" (aClassName As CFStringRef) As Ptr // CIFilterにCIColorMonochromeをセット Dim filter1 As Ptr = NSClassFromString("CIFilter") Declare Function filterWithName Lib "Cocoa" Selector "filterWithName:" (receiver As Ptr, fnam As CFStringRef) As Ptr filter1 = filterWithName(filter1, "CIColorMonochrome") // カラーをセット Dim clrCI As Ptr = NSClassFromString("CIColor") Declare Function alloc Lib "Cocoa" Selector "alloc" (receiver As Ptr) As Ptr clrCI = alloc(clrCI) Declare Function initWithColor Lib "Cocoa" Selector "initWithColor:" (receiver As Ptr, clr As Ptr) As Ptr clrCI = initWithColor(clrCI, XojColorToNSColor(rgbc)) // Xojo RGB -> NSColor -> CIColor // 実数をNSNumber型に変換 Dim num As Ptr = NSClassFromString("NSNumber") #if Target32Bit Declare Function numberWithReal Lib "Cocoa" Selector "numberWithFloat:" (receiver As Ptr, num As Single) As Ptr #endif #if Target64Bit Declare Function numberWithReal Lib "Cocoa" Selector "numberWithDouble:" (receiver As Ptr, num As Double) As Ptr #endif num = numberWithReal(num, 1.0) // パラメータをセット Declare Sub setValue Lib "Cocoa" Selector "setValue:forKey:" (receiver As Ptr, val As Ptr, key As CFStringRef) setValue(filter1, clrCI, "inputColor") // カラー setValue(filter1, num, "inputIntensity") // 強度 // 名前をセット(参照しないので不要?) Declare Sub setName Lib "Cocoa" Selector "setName:" (receiver As Ptr, nam As CFStringRef) setName(filter1, "filter1") // パラメータをArrayに格納 Dim arr As Ptr = NSClassFromString("NSMutableArray") Declare Function getArray Lib "Cocoa" Selector "array" (receiver As Ptr) As Ptr arr = getArray(arr) Declare Sub addObject Lib "Cocoa" Selector "addObject:" (receiver As Ptr, obj As Ptr) addObject(arr, filter1) // CALayerの使用を有効にする(重要!) Declare Sub wantsLayer Lib "Cocoa" Selector "setWantsLayer:" (receiver As Integer, flg As Boolean) wantsLayer(hndl, true) // コントロール(のView)にCIFilterをセット Declare Sub setContentFilters Lib "Cocoa" Selector "setContentFilters:" (receiver As Integer, arry As Ptr) setContentFilters(hndl, arr) // clean up Declare Sub release Lib "Cocoa" Selector "release" (receiver As Ptr) release(clrCI) End Sub
- 以下をWindow1にペースト
Private Function XojColorToNSColor(clrC As Color) as Ptr Dim r, g, b As CGFloat // 0〜255 を 0.0〜1.0 にマッピング r=clrC.Red/255 g=clrC.Green/255 b=clrC.Blue/255 // 文字列を指定してクラスオブジェクトを取得する。最初に一回宣言しておけばよい。 Declare Function NSClassFromString Lib "Cocoa" (aClassName As CFStringRef) As Ptr // カラーの取得 Dim clr As Ptr = NSClassFromString("NSColor") // RGB値からカラーを生成 Declare Function colorWithCalibrate Lib "Cocoa" Selector "colorWithCalibratedRed:green:blue:alpha:" (receiver As Ptr, red As CGFloat, green As CGFloat, blue As CGFloat, alpha As CGFloat) As Ptr clr = colorWithCalibrate(clr, r, g, b, 1.0) // alpha値は常に1.0 // カラーを返す return clr End Function
Xojoでの実装(セグメンテッドコントロールのラベル)
【ソースコードのコピー&ペーストについて】
ソースコード(グレー背景部分の全文)をコピーし、指定のウィンドウ/クラスにペーストすると、(新規作成して名前等を個別にコピー&ペーストしなくても)復元されます。
ただし、この方法は、メソッドでは問題ないようですが、イベント/アクション/プロパティでは不安定?なので、ペーストできない場合は、各項目のカッコ内を適用して下さい。
実行してみたところ、セグメンテッドコントロールのラベルが変更されることを確認しました。
- Xojoで新規プロジェクトを作成
- 新規クラス(名前は、ここでは「SegmentedControlStyle」)を作成し、Superを「SegmentedControl」にする。
- 以下をSegmentedControlStyleにペースト(できなければイベント定義に、イベント名:Openを追加)
Event Open()
- 以下をSegmentedControlStyleにペースト(できなければ、Sub - Endの間をOpenイベントに記述)
Sub Open() Handles Open // フォーカスリングを無効に Declare Sub setFocusRingType Lib "Cocoa" Selector "setFocusRingType:" (receiver As Integer, type As Integer) setFocusRingType(me.Handle, 1) // セグメント毎のラベルセット InitSegmentTitle() // インスタンスのOpen()に継承 RaiseEvent Open() End Sub
- 以下をSegmentedControlStyleにペースト
Private Function BoolToInt(val As Boolean) as Integer if val then return 1 else return 0 end if End Function
- 以下をSegmentedControlStyleにペースト
Private Function GenAttrText(st As String) as Ptr // 文字列を指定してクラスオブジェクトを取得する。最初に一回宣言しておけばよい。 Declare Function NSClassFromString Lib "Cocoa" (aClassName As CFStringRef) As Ptr Declare Function alloc Lib "Cocoa" Selector "alloc" (receiver As Ptr) As Ptr Declare Function init Lib "Cocoa" selector "init" (obj_id As Ptr) As Ptr Declare Sub addAttribute Lib "Cocoa" Selector "addAttribute:value:range:" (receiver As Ptr, nane As CFStringRef, val As Ptr, range As NSRange) // アトリビュートを持たない、プレーンなスタイル付テキストを生成 Dim attr As Ptr = NSClassFromString("NSMutableAttributedString") attr = alloc(attr) Declare Function initWithString Lib "Cocoa" Selector "initWithString:" (receiver As Ptr, str As CFStringRef) As Ptr attr = initWithString(attr, st) Declare Function length Lib "Cocoa" Selector "length" (receiver As Ptr) As Integer Dim ll As Integer = length(attr) // 文字列長 Declare Sub beginEditing Lib "Cocoa" Selector "beginEditing" (receiver As Ptr) beginEditing(attr) // 編集開始 // フォント(名前、サイズ、ボールド、イタリック) Dim font As Ptr = NSClassFromString("NSFont") Declare Function fontWithName Lib "Cocoa" Selector "fontWithName:size:" (receiver As Ptr, fname As CFStringRef, size As CGFloat) As Ptr font = fontWithName(font, GetFontName(), GetFontSize()) // GetFontName()で、ボールド/イタリック設定を反映したフォント名を取得 addAttribute(attr, "NSFont", font, NSMakeRange(0, ll)) // フォント(アンダーライン) Dim num As Ptr = NSClassFromString("NSNumber") Declare Function numberWithInteger Lib "Cocoa" Selector "numberWithInteger:" (receiver As Ptr, num As Integer) As Ptr num = numberWithInteger(num, BoolToInt(Underline)) addAttribute(attr, "NSUnderline", num, NSMakeRange(0, ll)) // フォント(カラー>Template指定するので、常に黒) Dim clr As Ptr = NSClassFromString("NSColor") Declare Function blackColor Lib "Cocoa" Selector "blackColor" (receiver As Ptr) As Ptr clr = blackColor(clr) addAttribute(attr, "NSColor", clr, NSMakeRange(0, ll)) // 段落(ParagraphStyle)の生成 Dim pgf As Ptr = NSClassFromString("NSMutableParagraphStyle") pgf = init(alloc(pgf)) // 揃えの設定 Declare Sub setAlignment Lib "Cocoa" Selector "setAlignment:" (receiver As Ptr, algn As Integer) setAlignment(pgf, LabelAlign) // 段落設定を適用 addAttribute(attr, "NSParagraphStyle", pgf, NSMakeRange(0, ll)) // clean up Declare Sub release Lib "Cocoa" Selector "release" (receiver As Ptr) release(pgf) Declare Sub endEditing Lib "Cocoa" Selector "endEditing" (receiver As Ptr) endEditing(attr) // 編集終了 // 矛盾の解消(効果ある??) declare sub fixAttributesInRange lib "Cocoa" selector "fixAttributesInRange:" (receiver as Ptr, range As NSRange) fixAttributesInRange(attr, NSMakeRange(0, ll)) return attr End Function
- 以下をSegmentedControlStyleにペースト
Private Function GenTextImage(w As Integer, attr As Ptr) as Ptr // 文字列を指定してクラスオブジェクトを取得する。最初に一回宣言しておけばよい。 Declare Function NSClassFromString Lib "Cocoa" (aClassName As CFStringRef) As Ptr // 描画領域の生成 Dim rect As NSRect = NSMakeRect(0,0,w,GetFontSize()+BaseOffset) // NSBitmapImageRep初期化 Dim bitmapImageRep As Ptr = NSClassFromString("NSBitmapImageRep") Declare Function alloc Lib "Cocoa" Selector "alloc" (receiver As Ptr) As Ptr bitmapImageRep = alloc(bitmapImageRep) Declare Function initWithBitmapDataPlanes Lib "Cocoa" Selector "initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:" _ (receiver As Ptr, planes As Ptr, w As Integer, h As Integer, bps As Integer, spp As Integer, alpha As Boolean, isPlanar As Boolean, colorSpaceName As CFStringRef, bfmt As Integer, rBytes As Integer, pBits As Integer) As Ptr bitmapImageRep = initWithBitmapDataPlanes(bitmapImageRep, nil, rect.w, rect.h, 8, 4, true, false, "NSDeviceRGBColorSpace", 0, 0, 0) // bitmapImageRepからグラフィックコンテキストを取得 Dim context As Ptr = NSClassFromString("NSGraphicsContext") Declare Function graphicsContextWithBitmapImageRep Lib "Cocoa" Selector "graphicsContextWithBitmapImageRep:" (receiver As Ptr, irep As Ptr) As Ptr context = graphicsContextWithBitmapImageRep(context, bitmapImageRep) if context=nil then return nil end if // 現在のグラフィックコンテキストを退避 Dim context1 As Ptr = NSClassFromString("NSGraphicsContext") Declare Sub saveGraphicsState Lib "Cocoa" Selector "saveGraphicsState" (receiver As Ptr) saveGraphicsState(context1) // 現在のグラフィックコンテキストにセット Dim context2 As Ptr = NSClassFromString("NSGraphicsContext") Declare Sub setCurrentContext Lib "Cocoa" Selector "setCurrentContext:" (receiver As Ptr, cntx As Ptr) setCurrentContext(context2, context) // 背景色を指定しての塗りつぶしは行わないので、透明が適用される // テキストの描画 Declare Sub drawInRect Lib "Cocoa" selector "drawInRect:" (class_id As Ptr, rect As NSRect) drawInRect(attr, rect) // 退避したグラフィックコンテキストを戻す Dim context3 As Ptr = NSClassFromString("NSGraphicsContext") Declare Sub restoreGraphicsState Lib "Cocoa" Selector "restoreGraphicsState" (receiver As Ptr) restoreGraphicsState(context3) // bitmapImageRepからサイズを取得 Declare Function mySize Lib "Cocoa" Selector "size" (receiver As Ptr) As NSSize Dim size As NSSize = mySize(bitmapImageRep) // bitmapImageRepのサイズでイメージを生成 Dim image As Ptr = NSClassFromString("NSImage") image = alloc(image) Declare Function initWithSize Lib "Cocoa" Selector "initWithSize:" (receiver As Ptr, size As NSSize) As Ptr image = initWithSize(image, size) // イメージに画像をセット Declare Sub addRepresentation Lib "Cocoa" selector "addRepresentation:" (class_id As Ptr, bmap As Ptr) addRepresentation(image, bitmapImageRep) // clean up Declare Sub release Lib "Cocoa" Selector "release" (receiver As Ptr) release(bitmapImageRep) // イメージを返す return image End Function
- 以下をSegmentedControlStyleにペースト
Private Function GetFontBoldItalic(fname As String, bFlg As Boolean, iFlg As Boolean) as Ptr // NSItalicFontMask = 0x00000001 // NSBoldFontMask = 0x00000002 // マスクをセット Dim flg As Integer = 0 if bFlg then flg=flg+2 end if if iFlg then flg=flg+1 end if // 文字列を指定してクラスオブジェクトを取得する。最初に一回宣言しておけばよい。 Declare Function NSClassFromString Lib "Cocoa" (aClassName As CFStringRef) As Ptr // sharedFontManager取得 Dim fmgr As Ptr = NSClassFromString("NSFontManager") Declare Function sharedFontManager Lib "Cocoa" Selector "sharedFontManager" (receiver As Ptr) As Ptr fmgr = sharedFontManager(fmgr) // フォントの取得 Declare Function fontWithFamily Lib "Cocoa" Selector "fontWithFamily:traits:weight:size:" (receiver As Ptr, fname As CFStringRef, trait As Integer, wait As Integer, size As CGFloat) As Ptr Dim font As Ptr = fontWithFamily(fmgr, fname, flg, 0, 12) // 名前の取得が目的なので、フォントサイズは常に12ポイントとしている // フォントを返す(nilの場合あり) return font End Function
- 以下をSegmentedControlStyleにペースト
Private Function GetFontName() as String Dim font As Ptr Dim fname As String Declare Function fontName Lib "Cocoa" Selector "fontName" (receiver As Ptr) As CFStringRef // フォント名のセット if TextFont="System" then fname=GetFontNameSystem() // Systemに割り当てられているフォントの名前を取得 else fname=TextFont end if // 修飾なし if Bold=false and Italic=false then return fname // 指定フォント名を返す end if // ボールドのみ if Bold and Italic=false then font = GetFontBoldItalic(fname,true,false) if font<>nil then return fontName(font) // ボールド書体が取得できれば書体名を返す else return fname // ボールド書体が取得できなければ指定フォント名を返す end if end if // イタリックのみ if Bold=false and Italic then font = GetFontBoldItalic(fname,false,true) if font<>nil then return fontName(font) // イタリック書体が取得できれば書体名を返す else return fname // イタリック書体が取得できなければ指定フォント名を返す end if end if // ボールド+イタリック if Bold and Italic then font = GetFontBoldItalic(fname,true,true) if font<>nil then return fontName(font) // ボールド+イタリック書体が取得できれば書体名を返す end if font = GetFontBoldItalic(fname,true,false) if font<>nil then return fontName(font) // ボールド書体が取得できれば書体名を返す end if font = GetFontBoldItalic(fname,false,true) if font<>nil then return fontName(font) // イタリック書体が取得できれば書体名を返す end if return fname // ボールドもイタリックも取得できなければ指定フォント名を返す end if End Function
- 以下をSegmentedControlStyleにペースト
Private Function GetFontNameSystem() as String // 文字列を指定してクラスオブジェクトを取得する。最初に一回宣言しておけばよい。 Declare Function NSClassFromString Lib "Cocoa" (aClassName As CFStringRef) As Ptr // システムフォントの取得 Dim font As Ptr = NSClassFromString("NSFont") Declare Function systemFontOfSize Lib "Cocoa" Selector "systemFontOfSize:" (receiver As Ptr, size As CGFloat) As Ptr font = systemFontOfSize(font, 12) // システムフォントを返す Declare Function fontName Lib "Cocoa" Selector "fontName" (receiver As Ptr) As CFStringRef return fontName(font) End Function
- 以下をSegmentedControlStyleにペースト
Private Function GetFontSize() as CGFloat // 単位換算 select case TextUnit case FontUnits.Default // On Macintosh, font units is in points return TextSize case FontUnits.Pixel return TextSize * 0.75 case FontUnits.Point return TextSize case FontUnits.Inches return TextSize * 72 case FontUnits.Millimeter return TextSize * 2.834 end select End Function
- 以下をSegmentedControlStyleにペースト
Private Sub InitSegmentTitle() Dim sItem As SegmentedControlItem Declare Sub setTemplate Lib "Cocoa" Selector "setTemplate:" (receiver As Ptr, flg As Boolean) Declare Sub setImage Lib "Cocoa" Selector "setImage:forSegment:" (receiver As Integer, label As Ptr, no As Integer) Declare Sub release Lib "Cocoa" Selector "release" (receiver As Ptr) // セグメント毎 for i As Integer=0 to me.Items.Ubound // 各セグメントの取得 sItem=me.Items(i) // 属性付テキスト生成 Dim attr As Ptr = GenAttrText(sItem.Title) // 画像化 Dim image As Ptr = GenTextImage(sItem.Width,attr) // 選択時のカラー反転や、ディアクティベート時のグレー化 setTemplate(image, true) // セグメントコントロールにセット setImage(me.Handle, image, i) // clean up release(attr) release(image) // 文字列の方はクリアしておく sItem.Title="" next End Sub
- 以下をWindow1にペースト(できなければプロパティに、名前:BaseOffset、データ型:Integer、標準値:1、を追加)
Public Property BaseOffset as Integer = 1
- 以下をWindow1にペースト(できなければプロパティに、名前:Bold、データ型:Boolean、を追加)
Public Property Bold as Boolean
- 以下をWindow1にペースト(できなければプロパティに、名前:Italic、データ型:Boolean、を追加)
Public Property Italic as Boolean
- 以下をWindow1にペースト(できなければプロパティに、名前:LabelAlign、データ型:Integer、標準値:2、を追加)
Public Property LabelAlign as Integer = 2
- 以下をWindow1にペースト(できなければプロパティに、名前:TextFont、データ型:String、標準値:System、を追加)
Public Property TextFont as String = "System"
- 以下をWindow1にペースト(できなければプロパティに、名前:TextSize、データ型:Single、標準値:12、を追加)
Public Property TextSize as Single = 12
- 以下をWindow1にペースト(できなければプロパティに、名前:TextUnit、データ型:FontUnits、を追加)
Public Property TextUnit as FontUnits
- 以下をWindow1にペースト(できなければプロパティに、名前:Underline、データ型:Boolean、を追加)
Public Property Underline as Boolean
- 他に、NSMakeRange/NSMakeRect(メソッド)、NSRange/NSRect/NSSize(構造体)が必要ですが、それらはmacoslibからコピーさせて頂きました。(上記SegmentedControlStyleにコピーする。)
- SegmentedControlStyleクラスをcontrol+クリック(またはマウスの右クリック)して表示されるメニューの「インスペクタ・ビヘイビア...」を選択
- ダイアログ左下の「+」ボタンを押してHeadingを追加し、ラベルをFontにする
- 追加したプロパティ(リストの最後尾にある)をFontにドラッグ移動する
- OKボタンを押してダイアログを閉じる
- Xojoプロジェクトウィンドウ>ナビゲーターのWindow1をクリックし、SegmentedControlStyleをレイアウトエディタにドラッグ&ドロップ
(レイアウトエディタとナビゲーターのWindow1>Controlsに、SegmentedControlStyleクラスのインスタンス(SegmentedControlStyle1)が生成される)- インスペクタの「編集」ボタンを押してダイアログを表示し、Labelを設定する(ここでは「項目1〜4」)
おわりに
内包するコントロールに、アピアランス・カラーを継承させない方法は、調べてはいるのですが見つかっていません。
ちなみに、setCanDrawSubviewsIntoLayer:は、自身のSubViewに関するもので、内包するコントロールには適用されないようです。
この件につきまして、ご存知の方がいらっしゃいましたら教えて頂けると助かります。
もう一つ、Xojoでの実装(セグメンテッドコントロールのラベル)でのTextSizeプロパティは、本来CGFloat型にしたいところですが、そうするとIDE上に表示できなくなるため、ここでは(他のコントロールに合わせて)Single型にしています。この場合、64bitではSingleからDoubleへのキャストが発生するので、(実行結果を見る限りは問題なさそうですが、安全を期すのであれば)一工夫しておいた方がいいかもしれません。
お世話になったサイト
貴重な情報をご提供頂いている皆様に、お礼申し上げます。(以下、順不同)
参考サイト(1):Xcode - NSButtonのチェックボックスの色を変える|teratail
参考サイト(2):cocoa - NSSegmentedControl (subclass NSSegmentCell) Text Color - Stack Overflow
更新履歴
2018.11.26 新規作成
[Home] [MacSoft] [Donation] [History] [Privacy Policy] [Affiliate Policy]