1# 2# tkextlib/bwidget/listbox.rb 3# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) 4# 5 6require 'tk' 7require 'tk/canvas' 8require 'tkextlib/bwidget.rb' 9 10module Tk 11 module BWidget 12 class ListBox < TkWindow 13 # is NOT a subclass of a listbox widget class. 14 # because it constructed on a canvas widget. 15 16 class Item < TkObject 17 end 18 end 19 end 20end 21 22class Tk::BWidget::ListBox 23 include TkItemConfigMethod 24 include Scrollable 25 26 TkCommandNames = ['ListBox'.freeze].freeze 27 WidgetClassName = 'ListBox'.freeze 28 WidgetClassNames[WidgetClassName] ||= self 29 30 class Event_for_Items < TkEvent::Event 31 def self._get_extra_args_tbl 32 [ 33 TkComm.method(:string) # item idenfier 34 ] 35 end 36 end 37 38 def __boolval_optkeys 39 super() << 'autofocus' << 'dragenabled' << 'dropenabled' << 'selectfill' 40 end 41 private :__boolval_optkeys 42 43 def tagid(tag) 44 if tag.kind_of?(Tk::BWidget::ListBox::Item) 45 tag.id 46 else 47 # tag 48 _get_eval_string(tag) 49 end 50 end 51 52 #def imagebind(*args) 53 # _bind_for_event_class(Event_for_Items, [path, 'bindImage'], *args) 54 # self 55 #end 56 def imagebind(context, *args) 57 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 58 if TkComm._callback_entry?(args[0]) || !block_given? 59 cmd = args.shift 60 else 61 cmd = Proc.new 62 end 63 _bind_for_event_class(Event_for_Items, [path, 'bindImage'], 64 context, cmd, *args) 65 self 66 end 67 68 #def imagebind_append(*args) 69 # _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], *args) 70 # self 71 #end 72 def imagebind_append(context, *args) 73 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 74 if TkComm._callback_entry?(args[0]) || !block_given? 75 cmd = args.shift 76 else 77 cmd = Proc.new 78 end 79 _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], 80 context, cmd, *args) 81 self 82 end 83 84 def imagebind_remove(*args) 85 _bind_remove_for_event_class(Event_for_Items, [path, 'bindImage'], *args) 86 self 87 end 88 89 def imagebindinfo(*args) 90 _bindinfo_for_event_class(Event_for_Items, [path, 'bindImage'], *args) 91 end 92 93 #def textbind(*args) 94 # _bind_for_event_class(Event_for_Items, [path, 'bindText'], *args) 95 # self 96 #end 97 def textbind(context, *args) 98 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 99 if TkComm._callback_entry?(args[0]) || !block_given? 100 cmd = args.shift 101 else 102 cmd = Proc.new 103 end 104 _bind_for_event_class(Event_for_Items, [path, 'bindText'], 105 context, cmd, *args) 106 self 107 end 108 109 #def textbind_append(*args) 110 # _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], *args) 111 # self 112 #end 113 def textbind_append(context, *args) 114 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 115 if TkComm._callback_entry?(args[0]) || !block_given? 116 cmd = args.shift 117 else 118 cmd = Proc.new 119 end 120 _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], 121 context, cmd, *args) 122 self 123 end 124 125 def textbind_remove(*args) 126 _bind_remove_for_event_class(Event_for_Items, [path, 'bindText'], *args) 127 self 128 end 129 130 def textbindinfo(*args) 131 _bindinfo_for_event_class(Event_for_Items, [path, 'bindText'], *args) 132 end 133 134 def delete(*args) 135 tk_send('delete', *args) 136 self 137 end 138 139 def edit(item, text, *args) 140 tk_send('edit', tagid(item), text, *args) 141 self 142 end 143 144 def exist?(item) 145 bool(tk_send('exists', tagid(item))) 146 end 147 148 def index(item) 149 num_or_str(tk_send('index', tagid(item))) 150 end 151 152 def insert(idx, item, keys={}) 153 tk_send('insert', idx, tagid(item), *hash_kv(keys)) 154 self 155 end 156 157 def get_item(idx) 158 tk_send('items', idx) 159 end 160 161 def items(first=None, last=None) 162 list(tk_send('items', first, last)) 163 end 164 165 def move(item, idx) 166 tk_send('move', tagid(item), idx) 167 self 168 end 169 170 def reorder(neworder) 171 tk_send('reorder', neworder) 172 self 173 end 174 175 def see(item) 176 tk_send('see', tagid(item)) 177 self 178 end 179 180 def selection_clear 181 tk_send_without_enc('selection', 'clear') 182 self 183 end 184 185 def selection_set(*args) 186 tk_send_without_enc('selection', 'set', 187 *(args.collect{|item| tagid(item)})) 188 self 189 end 190 191 def selection_add(*args) 192 tk_send_without_enc('selection', 'add', 193 *(args.collect{|item| tagid(item)})) 194 self 195 end 196 197 def selection_remove(*args) 198 tk_send_without_enc('selection', 'remove', 199 *(args.collect{|item| tagid(item)})) 200 self 201 end 202 203 def selection_get(*args) 204 simplelist(tk_send_without_enc('selection', 'get')).collect{|item| 205 Tk::BWidget::ListBox::Item.id2obj(self, item) 206 } 207 end 208end 209 210class Tk::BWidget::ListBox::Item 211 include TkTreatTagFont 212 213 ListItem_TBL = TkCore::INTERP.create_table 214 215 (ListItem_ID = ['bw:item'.freeze, TkUtil.untrust('00000')]).instance_eval{ 216 @mutex = Mutex.new 217 def mutex; @mutex; end 218 freeze 219 } 220 221 TkCore::INTERP.init_ip_env{ 222 ListItem_TBL.mutex.synchronize{ ListItem_TBL.clear } 223 } 224 225 def self.id2obj(lbox, id) 226 lpath = lbox.path 227 ListItem_TBL.mutex.synchronize{ 228 if ListItem_TBL[lpath] 229 ListItem_TBL[lpath][id]? ListItem_TBL[lpath][id]: id 230 else 231 id 232 end 233 } 234 end 235 236 def initialize(lbox, *args) 237 if lbox.kind_of?(Tk::BWidget::ListBox) 238 @listbox = lbox 239 else 240 fail RuntimeError, 241 "expect Tk::BWidget::ListBox or Tk::BWidget::ListBox::Item for 1st argument" 242 end 243 244 if args[-1].kind_of?(Hash) 245 keys = _symbolkey2str(args.pop) 246 else 247 keys = {} 248 end 249 250 index = keys.delete('index') 251 unless args.empty? 252 index = args.shift 253 end 254 index = 'end' unless index 255 256 unless args.empty? 257 fail RuntimeError, 'too much arguments' 258 end 259 260 @lpath = @listbox.path 261 262 if keys.key?('itemname') 263 @path = @id = keys.delete('itemname') 264 else 265 ListItem_ID.mutex.synchronize{ 266 @path = @id = ListItem_ID.join(TkCore::INTERP._ip_id_) 267 ListItem_ID[1].succ! 268 } 269 end 270 271 ListItem_TBL.mutex.synchronize{ 272 ListItem_TBL[@id] = self 273 ListItem_TBL[@lpath] = {} unless ListItem_TBL[@lpath] 274 ListItem_TBL[@lpath][@id] = self 275 } 276 277 @listbox.insert(index, @id, keys) 278 end 279 280 def listbox 281 @listbox 282 end 283 284 def id 285 @id 286 end 287 288 def [](key) 289 cget(key) 290 end 291 292 def []=(key, val) 293 configure(key, val) 294 val 295 end 296 297 def cget_tkstring(key) 298 @listbox.itemcget_tkstring(@id, key) 299 end 300 def cget(key) 301 @listbox.itemcget(@id, key) 302 end 303 def cget_strict(key) 304 @listbox.itemcget_strict(@id, key) 305 end 306 307 def configure(key, val=None) 308 @listbox.itemconfigure(@id, key, val) 309 end 310 311 def configinfo(key=nil) 312 @listbox.itemconfiginfo(@id, key) 313 end 314 315 def current_configinfo(key=nil) 316 @listbox.current_itemconfiginfo(@id, key) 317 end 318 319 def delete 320 @listbox.delete(@id) 321 self 322 end 323 324 def edit(*args) 325 @listbox.edit(@id, *args) 326 self 327 end 328 329 def exist? 330 @listbox.exist?(@id) 331 end 332 333 def index 334 @listbox.index(@id) 335 end 336 337 def move(index) 338 @listbox.move(@id, index) 339 end 340 341 def see 342 @listbox.see(@id) 343 end 344 345 def selection_add 346 @listbox.selection_add(@id) 347 end 348 349 def selection_remove 350 @listbox.selection_remove(@id) 351 end 352 353 def selection_set 354 @listbox.selection_set(@id) 355 end 356 357 def selection_toggle 358 @listbox.selection_toggle(@id) 359 end 360end 361 362