File: tk/optionobj.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Tk#12
extends
  Encoding ( Unknown-Module )
  Tk   
includes
  TkCore   
  class: OptionObj#13
includes
  TkUtil   
inherits from
  Hash ( Builtin-Module )
has properties
method: initialize / 1 #16
method: observ_info #22
method: observs #26
method: _remove_win / 1 #36
method: assign / 1 #58
method: unassign / 1 #91
method: notify / 1 #98
alias: apply notify #160
method: + / 1 #162
alias: update_without_notify update #171
method: update / 1 #173
method: configure / 2 #178
method: [] / 1 #186
method: store / 2 #191
method: []= / 2 #196
method: replace / 1 #200
method: default / 1 #205

Class Hierarchy

Object ( Builtin-Module )
Hash ( Builtin-Module )
  OptionObj ( Tk ) #13

Code

   1  #
   2  # tk/optionobj.rb : control options for a group of widgets
   3  #
   4  #  NOTE: If you want to use key-only option (no value), 
   5  #        use Tk::None for the value of the key-only option. 
   6  #
   7  #        e.g. hash_kv({'aaa'=>1, 'bbb'=>Tk::None, 'ccc'=>3}) 
   8  #                 => ["-aaa", 1, "-bbb", "-ccc", 3]
   9  #
  10  require 'tk'
  11 
  12  module Tk
  13    class OptionObj < Hash
  14      include TkUtil
  15 
  16      def initialize(hash = nil)
  17        super()
  18        @observ = []
  19        update_without_notify(_symbolkey2str(hash)) if hash
  20      end
  21 
  22      def observ_info
  23        @observ.dup
  24      end
  25 
  26      def observs
  27        @observ.collect{|win|
  28          if win.kind_of?(Array)
  29            win[0]
  30          else
  31            win
  32          end
  33        }
  34      end
  35 
  36      def _remove_win(win)
  37        if win.kind_of?(Array)
  38          widget, method = win
  39          @observ.delete_if{|x| 
  40            if x.kind_of?(Array)
  41              x[0] == widget
  42            else
  43              x == widget
  44            end
  45          }
  46        else
  47          @observ.delete_if{|x|
  48            if x.kind_of?(Array)
  49              x[0] == win
  50            else
  51              x == win
  52            end
  53          }
  54        end
  55      end
  56      private :_remove_win
  57 
  58      def assign(*wins)
  59        # win := 
  60        #   widget             #==> call widget.configure(hash)
  61        #   [widget]           #==> call widget.configure(hash)
  62        #   [widget, nil, {src=>target, ... }]
  63        #                      #==> call widget.configure(hash) 
  64        #                               with converting hash-key
  65        #   [widget, method]   #==> call widget.method(hash)
  66        #   [widget, method, {src=>target, ... }]
  67        #                      #==> call widget.method(hash) 
  68        #                               with converting hash-key
  69        #   [widget [receiver, method, arg, ... ]]
  70        #                      #==> call receiver.method(arg, ... , hash)
  71        #   [widget [receiver, method, arg, ... ], {src=>target, ... }]
  72        #                      #==> call receiver.method(arg, ... , hash)
  73        #                               with onverting hash-key
  74        #
  75        # src := option_name_on_optobj
  76        #
  77        # target := 
  78        #   nil                #==> not use the src
  79        #   option_name_on_target_widget
  80        #   [ option_name_on_target_widget, ... ]
  81        #                      #==> set all of them
  82        #
  83        wins.each{|win|
  84          _remove_win(win)
  85          @observ << win
  86          notify(win)
  87        }
  88        self
  89      end
  90 
  91      def unassign(*wins)
  92        wins.each{|win|
  93          _remove_win(win)
  94        }
  95        self
  96      end
  97 
  98      def notify(target = nil)
  99        if target
 100          targets = [target]
 101        elsif @observ.empty?
 102          return self
 103        else
 104          targets = @observ.dup
 105        end
 106 
 107        return self if empty?
 108 
 109        org_hash = _symbolkey2str(self)
 110 
 111        targets.each{|win|
 112          widget = receiver = win
 113          hash = org_hash
 114          begin
 115            if win.kind_of?(Array)
 116              widget, method, conv_tbl = win
 117              receiver = widget
 118 
 119              if conv_tbl
 120                hash = {}
 121                org_hash.each{|key, val|
 122                  key = conv_tbl[key] if conv_tbl.key?(key)
 123                  next unless key
 124                  if key.kind_of?(Array)
 125                    key.each{|k| hash[k] = val}
 126                  else              
 127                    hash[key] = val
 128                  end
 129                }
 130              end
 131 
 132              if method.kind_of?(Array)
 133                receiver, method, *args = method
 134                receiver.__send__(method, *(args << hash))
 135              elsif method
 136                widget.__send__(method, hash)
 137              else
 138                widget.configure(hash)
 139              end
 140 
 141            else
 142              widget.configure(self)
 143            end
 144          rescue => e
 145            if ( ( widget.kind_of?(TkObject) \
 146                  && widget.respond_to?('exist?') \
 147                  && ! receiver.exist? ) \
 148              || ( receiver.kind_of?(TkObject) \
 149                  && receiver.respond_to?('exist?') \
 150                  && ! receiver.exist? ) )
 151              @observ.delete(win)
 152            else
 153              fail e
 154            end
 155          end
 156        }
 157 
 158        self
 159      end
 160      alias apply notify
 161 
 162      def +(hash)
 163        unless hash.kind_of?(Hash)
 164          fail ArgumentError, "expect a Hash"
 165        end
 166        new_obj = self.dup
 167        new_obj.update_without_notify(_symbolkey2str(hash))
 168        new_obj
 169      end
 170 
 171      alias update_without_notify update
 172 
 173      def update(hash)
 174        update_without_notify(_symbolkey2str(hash))
 175        notify
 176      end
 177 
 178      def configure(key, value=nil)
 179        if key.kind_of?(Hash)
 180          update(key)
 181        else
 182          store(key,value)
 183        end
 184      end
 185 
 186      def [](key)
 187        super(key.to_s)
 188      end
 189      alias cget []
 190 
 191      def store(key, val)
 192        key = key.to_s
 193        super(key, val)
 194        notify
 195      end
 196      def []=(key, val)
 197        store(key,val)
 198      end
 199 
 200      def replace(hash)
 201        super(_symbolkey2str(hash))
 202        notify
 203      end
 204 
 205      def default(opt)
 206        fail RuntimeError, "unknown option `#{opt}'"
 207      end
 208      private :default
 209 
 210      undef :default=
 211    end
 212  end