表示するデータ
ここでは、スクリプトからいろいろ設定する方法をメモしてあるけど、ほとんどのことは Array Controller を使ってバインディングで処理すると、こんなことするのがばからしくなるくらいに簡単。Array Controllerのところに少しメモしてあるけど、いずれは Table View と Array Controller に関して、もう少し詳しくメモするつもり。
テキスト表示を設定する
列ごとに表示するテキストの設定を変えたい場合は、tableView_willDisplayCell_forTableColumn_row を使う。これで、cell に対して設定する。ここでは、フォントと文字の色を設定している。フォントの設定には、setFont(NSFont) を使い、文字の色の設定には、setTextColor(NSColor) を使う。
NSFont では、NSFont.fontWithName_size(font name, size) を使っている。まあ、一番手軽だから。font name は文字列で指定する。下の例では "Lucida Grande" にしてあるが、"Times" とか別のフォントでもいい。size は数値で。例では 14.0 にしてあるけど、たぶん整数でも大丈夫なはず。
NSColor はいろいろ設定方法がある。赤、青、緑と透明度を個別に設定する場合は、colorWithCalibratedRed_green_blue_alpha(red,green,blue,alpha) か colorWithDeviceRed_green_blue_alpha(red,green,blue,alpha) を使う。それぞれは、0~1 の値で指定する。赤で不透明の場合は、(1,0,0,1) となる。いずれも、NSColor につけて使う。例えば、
NSColor.colorWithCalibratedRed_green_blue_alpha(1,0,0,1)
これ以外にも、あらかじめ指定してある色を使う事もできる。プリセットの色は次のものがある。
blackColor, blueColor, brownColor, clearColor, cyanColor, darkGrayColor, grayColor, greenColor, lightGrayColor, magentaColor, orangeColor, purpleColor, redColor, whiteColor, yellowColor
次のように使う。
NSColor.blackColor
ここまでをまとめて、tableView_willDisplayCell_forTableColumn_row で設定すると、次のようになる。
これで、フォントが Lucida Grande の14ポイントで、文字は青色になる。
def tableView_willDisplayCell_forTableColumn_row(tableView,cell,col,row)
case col
when @table.tableColumnWithIdentifier('col1')
cell.setFont(NSFont.fontWithName_size("Lucida Grande", 14.0)
cell.setTextColor(NSColor.colorWithCalibratedRed_green_blue_alpha(0,0,1,1))
end
end
列ごとではなく、セルごとに細かく設定したい場合は、addAttribute_value_range を使って tableView_objectValueForTableColumn_row(tableView, col, row) で表示させる文字列自体に属性を付加する。addAttribute_value_range についてのもう少し詳しい使い方は文字列に属性を付加するを参照。
例えば、テーブルにデータを表示するの例にある配列 @output を col2 に表示するときに属性をつけたい場合は、次のようにする。例では、@output に入っているデータは乱数で作った数字なのでまず to_s で文字列に変換して、それから、NSMutableAttributedString オブジェクトを作る。
output = NSMutableAttributedString.alloc.initWithString(@output[row][1].to_s)
これに addAttribute_value_range で属性を付加する。文字列に色を付けるには、NSForegroundColorAttributeName を属性として NSColor で色を指定する。範囲 range は、NSRange を入れる。Ruby の Range オブジェクトでもいけるけど、指定の方法が違うので注意。両方とも、一つ目は、最初の文字列の位置だけど、2つ目は、NSRange の方は文字列の長さ(文字数)で、Ruby の Range は最後の文字列の位置(たぶん文字単位、0から始まる)。ここでの例では、NSRange(0,1) なので、文字列の最初の一文字だけが赤く色付けされる。
NSRange.new(position,length)
Range.new(first,last)
output.addAttribute_value_range(NSForegroundColorAttributeName,NSColor.redColor,NSRange.new(0,1))
追記:NSRange は Ruby の配列で記述できるので、これは、次のように書き換えできる。
output.addAttribute_value_range(NSForegroundColorAttributeName,NSColor.redColor,[0,1])
そして、重要なのが、最後に一行 output を追加する。何をしてるかというと、表示する文字列を指定している。これをしないと何も表示されない。
まとめるとこんな感じ。
def tableView_objectValueForTableColumn_row(tableView, col, row)
case col
when @table.tableColumnWithIdentifier('col2')
output = NSMutableAttributedString.alloc.initWithString(@output[row][1].to_s)
output.addAttribute_value_range(NSForegroundColorAttributeName,NSColor.redColor,NSRange.new(0,1))
output
end
end
チェックボックスを使う
awakeFromNib で、チェックボックスを入れる設定をする。NSButtonCell を使う。
まず、checkCell という NSButtonCell オブジェクトを作る。Objective-C 風に NSButtonCell.alloc.init でも、Ruby 風に NSButtonCell.new でもいけるはず。次に、setButtonType でボタンの形式を指定する。チェックボックスは3なので、3を入れる。タイトルは別にいらないので何もなくてもいい。それから、@table に tableColumnWithIdentifier(col) で col1 を指定して setDataCell メソッドでチェックボックスのオブジェクトを設定する。
def awakeFromNib
checkCell = NSButtonCell.alloc.init
checkCell.setButtonType(3)
checkCell.setTitle("")
@table.tableColumnWithIdentifier("col1").setDataCell(checkCell)
end
これよりも、もっと簡単な方法が見つかった。
Interface Builder で、テーブルのチェックボックスを使いたい列に Check Box Cell を配置するだけ。
つぎに、チェックボックスに反映させるデータの扱い方。
チェックボックスは、データとしては0か1を持つので、tableView_objectValueForTableColumn_row で col1 の表示をする際は、0もしくは1になるように、データを設定する。ふつうは配列を使うので、col1 にあたる部分は、0もしくは1にする。同時にテーブルに表示するデータの配列に加える。チェックボックス専用の配列を作ってもいい。
ここでは、@boxstate という配列を作ってみる。
@boxstate = [0,0,0,0,0]
0なので、最初に表示されるときは、チェックボックスはチェックが入っていない。
次に、チェックボックスがクリックされた際に、チェックボックスの状態が変わるようにする。何も設定しないと、クリックしても何も起きない。ここは、tableView_setObjectValue_forTableColumn_row を使う。@boxstate[row] = object.to_i として、チェックボックスの状態を0、1で@boxstate に入れていく。こうすると、チェックボックスをクリックすると、チェックボックスの状態が反映される。
def tableView_setObjectValue_forTableColumn_row(tableView,object,col,row)
case col
when @table.tableColumnWithIdentifier('col1')
@boxstate[row] = object.to_i
end
end
これで、チェックボックスがチェックされているか確認するためには、@boxstate の対応する列の値を調べればいい。0ならチェックされていなくて、1ならチェックされている。
データと同じ配列に入れたい場合は、それなりに書き換える。例えば、@output という配列にデータが配列に入っていて、0番目の要素にチェックボックスの値を入れる場合は、次のようになる。
@output[row][0] = object.to_i
ポップアップメニューを使う
awakeFromNib で、ポップアップボタンを入れる設定をする。NSButtonCell を使う。
まず、checkCell という NSPopUpButtonCell オブジェクトを NSPopUpButtonCell.alloc.initTextCell_pullsDown(string,true/false) で作る。string はデフォルトで表示するテキスト。項目の 0 にあたる。true でプルダウンメニュー、false でポップアップメニューになる。次に、setButtonType でポップアップボタンのタイプを選ぶ。細かいことは、そのうちまとめる。ここでは、テーブルに入れるので、ボタンの形がでない方が望ましい、ということで、NSSwitchButton にしておく。これだと、テーブルにテキストが表示されるのと同じになる。addItemsWithTitles(array) でポップアップボタンの項目を配列で指定する。Ruby の Array オブジェクトでいい。中身は表示するテキストにする。これをチェックボックスと同じように、@table の行を tableColumnWithIdentifier(col) で指定して setDataCell メソッドでチェックボックスのオブジェクトを設定する。
def awakeFromNib
popup = NSPopUpButtonCell.alloc.initTextCell_pullsDown("default",false)
popup.setButtonType(NSSwitchButton)
items = ["item1,"item2","item3"]
popup.addItemsWithTitles(items)
@table.tableColumnWithIdentifier("col1").setDataCell(popup)
end
ポップアップボタンもチェックボックス同様に、Interface Builder にテーブルに使えるパーツがあって、それで準備すると非常に簡単。
これをテーブルビューの表示したいコラムにドラッグアンドドロップして、あとは、通常のポップアップメニューと同様にメニューアイテムを追加していく。
ポップアップボタンは、データとしては項目のインデックスを持つので、tableView_objectValueForTableColumn_row で col1 の表示をする際は、項目のインデックスを指定することになる。デフォルトでは、配列の要素に 0 を入れておくといいけど、まあ、それはプログラム次第。
ここでは、@buttonstate という配列を作ってみる。
@buttonstate = [0,0,0,0,0]
0なので、最初に表示されるときは、ポップアップボタンの最初の項目が表示される。
次に、ポップアップボタンがクリックされた際に、ポップアップボタンの選ばれた項目が表示されるようにする。この設定をしないと、常にデフォルトの項目が表示される。この設定は、tableView_setObjectValue_forTableColumn_row でする。チェックボックスと同じ。@boxstate[row] = object.to_i として、ポップアップボタンの項目のインデックスを @boxstate に入れていく。こうすると、ポップアップボタンで別の項目を選ぶと、その状態が反映される。
def tableView_setObjectValue_forTableColumn_row(tableView,object,col,row)
case col
when @table.tableColumnWithIdentifier('col1')
@buttonstate[row] = object.to_i
end
end
これで、どの項目が選択されているかを確認するためには、@buttonstate の対応する列の値を調べればいい。
データと同じ配列に入れたい場合は、チェックボックスの時と同様に変更する。それなりに書き換える。例えば、@output という配列にデータが配列に入っていて、1番目の要素にポップアップメニューのの値を入れる場合は、次のようになる。
@output[row][1] = object.to_i