Class: TkEvent::Event

Inherits:
TkUtil::CallbackSubst show all
Defined in:
lib/tk/event.rb

Defined Under Namespace

Modules: Grp, StateMask, TypeNum

Constant Summary collapse

TYPE_NAME_TBL =
Hash.new
TYPE_ID_TBL =
Hash.new
TYPE_GROUP_TBL =
Hash.new
FIELD_FLAG =
{
  # key  =>  flag
  'above'       => Grp::CONFIG,
  'borderwidth' => (Grp::CREATE|Grp::CONFIG),
  'button'      => Grp::BUTTON,
  'count'       => Grp::EXPOSE,
  'data'        => (Grp::VIRTUAL|Grp::STRING_DATA),
  'delta'       => Grp::MWHEEL,
  'detail'      => (Grp::FOCUS|Grp::CROSSING),
  'focus'       => Grp::CROSSING,
  'height'      => (Grp::EXPOSE|Grp::CONFIG),
  'keycode'     => Grp::KEY,
  'keysym'      => Grp::KEY,
  'mode'        => (Grp::CROSSING|Grp::FOCUS),
  'override'    => (Grp::CREATE|Grp::MAP|Grp::REPARENT|Grp::CONFIG),
  'place'       => Grp::CIRC,
  'root'        => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),
  'rootx'       => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),
  'rooty'       => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),
  'sendevent'   => Grp::ALL,
  'serial'      => Grp::ALL,
  'state'       => (Grp::KEY_BUTTON_MOTION_VIRTUAL|
                    Grp::CROSSING|Grp::VISIBILITY),
  'subwindow'   => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),
  'time'        => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING|
                    Grp::PROP),
  'warp'        => Grp::KEY_BUTTON_MOTION_VIRTUAL,
  'width'       => (Grp::EXPOSE|Grp::CREATE|Grp::CONFIG),
  'window'      => (Grp::CREATE|Grp::UNMAP|Grp::MAP|Grp::REPARENT|
                    Grp::CONFIG|Grp::GRAVITY|Grp::CIRC),
  'when'        => Grp::ALL,
  'x'           => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING|
                    Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY|
                    Grp::REPARENT),
  'y'           => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING|
                    Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY|
                    Grp::REPARENT),
}
FIELD_OPERATION =
{
  'root' => proc{|val|
    begin
      Tk.tk_call_without_enc('winfo', 'pathname', val)
      val
    rescue
      nil
    end
  },

  'subwindow' => proc{|val|
    begin
      Tk.tk_call_without_enc('winfo', 'pathname', val)
      val
    rescue
      nil
    end
  },

  'window' => proc{|val| nil}
}
KEY_TBL =
<‘%’ subst-key char>, <proc type char>, <instance var (accessor) name>
[
  [ ?#, ?n, :serial ],
  [ ?a, ?s, :above ],
  [ ?b, ?n, :num ],
  [ ?c, ?n, :count ],
  [ ?d, ?s, :detail ],
  # ?e
  [ ?f, ?b, :focus ],
  # ?g
  [ ?h, ?n, :height ],
  [ ?i, ?s, :win_hex ],
  # ?j
  [ ?k, ?n, :keycode ],
  # ?l
  [ ?m, ?s, :mode ],
  # ?n
  [ ?o, ?b, :override ],
  [ ?p, ?s, :place ],
  # ?q
  # ?r
  [ ?s, ?x, :state ],
  [ ?t, ?n, :time ],
  # ?u
  [ ?v, ?n, :value_mask ],
  [ ?w, ?n, :width ],
  [ ?x, ?n, :x ],
  [ ?y, ?n, :y ],
  # ?z
  [ ?A, ?s, :char ],
  [ ?B, ?n, :borderwidth ],
  # ?C
  [ ?D, ?n, :wheel_delta ],
  [ ?E, ?b, :send_event ],
  # ?F
  # ?G
  # ?H
  # ?I
  # ?J
  [ ?K, ?s, :keysym ],
  # ?L
  # ?M
  [ ?N, ?n, :keysym_num ],
  # ?O
  [ ?P, ?s, :property ],
  # ?Q
  [ ?R, ?s, :rootwin_id ],
  [ ?S, ?s, :subwindow ],
  [ ?T, ?n, :type ],
  # ?U
  # ?V
  [ ?W, ?w, :widget ],
  [ ?X, ?n, :x_root ],
  [ ?Y, ?n, :y_root ],
  # ?Z
  nil
]
LONGKEY_TBL =
<‘%’ subst-key str>, <proc type char>, <instance var (accessor) name>

the subst-key string will be converted to a bytecode (128+idx).

[
  # for example, for %CTT and %CST subst-key on tkdnd-2.0
  # ['CTT', ?l, :drop_target_type],
  # ['CST', ?l, :drop_source_type],
]
PROC_TBL =
<proc type char>, <proc/method to convert tcl-str to ruby-obj>
[
  [ ?n, TkComm.method(:num_or_str) ],
  [ ?s, TkComm.method(:string) ],
  [ ?b, TkComm.method(:bool) ],
  [ ?w, TkComm.method(:window) ],

  [ ?x, proc{|val|
      begin
        TkComm::number(val)
      rescue ArgumentError
        val
      end
    }
  ],

  nil
]
ALIAS_TBL =

alias button num

alias delta  wheel_delta
alias root   rootwin_id
alias rootx  x_root
alias root_x x_root
alias rooty  y_root
alias root_y y_root
alias sendevent send_event
{
  :button    => :num,
  :data      => :detail,
  :delta     => :wheel_delta,
  :root      => :rootwin_id,
  :rootx     => :x_root,
  :root_x    => :x_root,
  :rooty     => :y_root,
  :root_y    => :y_root,
  :sendevent => :send_event,
  :window    => :widget
}

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from TkUtil::CallbackSubst

_define_attribute_aliases, _get_all_subst_keys, _get_extra_args_tbl, _get_subst_key, _setup_subst_table, _sym2subst, #initialize, inspect, ret_val, scan_args, subst_arg

Constructor Details

This class inherits a constructor from TkUtil::CallbackSubst

Class Method Details

.group_flag(id) ⇒ Object



122
123
124
# File 'lib/tk/event.rb', line 122

def self.group_flag(id)
  TYPE_GROUP_TBL[id] || 0
end

.type_id(name) ⇒ Object



114
115
116
# File 'lib/tk/event.rb', line 114

def self.type_id(name)
  TYPE_NAME_TBL[name.to_s]
end

.type_name(id) ⇒ Object



118
119
120
# File 'lib/tk/event.rb', line 118

def self.type_name(id)
  TYPE_ID_TBL[id] && TYPE_ID_TBL[id][0]
end

Instance Method Details

#generate(win, modkeys = {}) ⇒ Object



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/tk/event.rb', line 253

def generate(win, modkeys={})
  klass = self.class

  if modkeys.has_key?(:type) || modkeys.has_key?('type')
    modkeys = TkComm._symbolkey2str(modkeys)
    type_id = modkeys.delete('type')
  else
    type_id = self.type
  end

  type_name  = klass.type_name(type_id)
  unless type_name
    fail RuntimeError, "type_id #{type_id} is invalid"
  end

  group_flag = klass.group_flag(type_id)

  opts = valid_for_generate(group_flag)

  modkeys.each{|key, val|
    if val
      opts[key.to_s] = val
    else
      opts.delete(key.to_s)
    end
  }

  if group_flag != Grp::KEY
    Tk.event_generate(win, type_name, opts)
  else
    # If type is KEY event, focus should be set to target widget.
    # If not set, original widget will get the same event.
    # That will make infinite loop.
    w = Tk.tk_call_without_enc('focus')
    begin
      Tk.tk_call_without_enc('focus', win)
      Tk.event_generate(win, type_name, opts)
    ensure
      Tk.tk_call_without_enc('focus', w)
    end
  end
end

#valid_fields(group_flag = nil) ⇒ Object




218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/tk/event.rb', line 218

def valid_fields(group_flag=nil)
  group_flag = self.class.group_flag(self.type) unless group_flag

  fields = {}
  FIELD_FLAG.each{|key, flag|
    next if (flag & group_flag) == 0
    begin
      val = self.__send__(key)
    rescue
      next
    end
    # next if !val || val == '??'
    next if !val || (val == '??' && (flag & Grp::STRING_DATA))
    fields[key] = val
  }

  fields
end

#valid_for_generate(group_flag = nil) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/tk/event.rb', line 237

def valid_for_generate(group_flag=nil)
  fields = valid_fields(group_flag)

  FIELD_OPERATION.each{|key, cmd|
    next unless fields.has_key?(key)
    val = FIELD_OPERATION[key].call(fields[key])
    if val
      fields[key] = val
    else
      fields.delete(key)
    end
  }

  fields
end