Class: VER::WidgetMajorMode
- Inherits:
-
Struct
- Object
- Struct
- VER::WidgetMajorMode
- Includes:
- Keymap::Results
- Defined in:
- lib/ver/widget_major_mode.rb
Overview
The WidgetMajorMode associates a widget with a major mode. It keeps a limited history of the events that arrive at [on_event]. It also maintains a stack of the event sequences and tries to match against the keymaps of the major and minor modes.
This class has its own list of minor modes, which can be modified and may differ from the minor modes of the original major mode.
It is responsible to keep the keymaps of major and minor modes functioning by ensuring that they are actually bound to the tag of the major mode.
Instance Attribute Summary collapse
-
#action_history ⇒ Object
Returns the value of attribute action_history.
-
#event_history ⇒ Object
Returns the value of attribute event_history.
-
#major ⇒ Object
Returns the value of attribute major.
-
#minors ⇒ Object
Returns the value of attribute minors.
-
#read_amount ⇒ Object
Returns the value of attribute read_amount.
-
#reader ⇒ Object
Returns the value of attribute reader.
-
#stack ⇒ Object
Returns the value of attribute stack.
-
#widget ⇒ Object
Returns the value of attribute widget.
Instance Method Summary collapse
- #actions ⇒ Object
-
#bind(sequence, &block) ⇒ Object
Shortcut to bind a sequence on the associated widget.
- #bind_key(key) ⇒ Object
- #bound_keys ⇒ Object
- #establish_tag ⇒ Object
- #forget(*minors) ⇒ Object
-
#handle_reader(event) ⇒ Object
ignore event for now, it might be needed later.
-
#initialize(widget, major) ⇒ WidgetMajorMode
constructor
A new instance of WidgetMajorMode.
- #inspect ⇒ Object
- #listen ⇒ Object
- #name ⇒ Object
- #on_event(event) ⇒ Object
- #read(amount, &reader) ⇒ Object
- #replace_minor(old, new) ⇒ Object
- #replaced_by(other) ⇒ Object
- #replaces(other) ⇒ Object
- #replacing(other) ⇒ Object
- #resolve(sequence) ⇒ Object
- #synchronize ⇒ Object
- #tag ⇒ Object
- #to_camel_case ⇒ Object
- #to_tcl ⇒ Object
- #use(*minors) ⇒ Object
Constructor Details
#initialize(widget, major) ⇒ WidgetMajorMode
Returns a new instance of WidgetMajorMode.
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/ver/widget_major_mode.rb', line 17 def initialize(, major) self. = self.major = MajorMode[major] self.event_history = SizedArray.new(100) self.action_history = SizedArray.new(100) self.stack = [] self.minors = [] establish_tag use(*self.major.minors) listen end |
Instance Attribute Details
#action_history ⇒ Object
Returns the value of attribute action_history
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def action_history @action_history end |
#event_history ⇒ Object
Returns the value of attribute event_history
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def event_history @event_history end |
#major ⇒ Object
Returns the value of attribute major
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def major @major end |
#minors ⇒ Object
Returns the value of attribute minors
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def minors @minors end |
#read_amount ⇒ Object
Returns the value of attribute read_amount
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def read_amount @read_amount end |
#reader ⇒ Object
Returns the value of attribute reader
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def reader @reader end |
#stack ⇒ Object
Returns the value of attribute stack
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def stack @stack end |
#widget ⇒ Object
Returns the value of attribute widget
12 13 14 |
# File 'lib/ver/widget_major_mode.rb', line 12 def @widget end |
Instance Method Details
#actions ⇒ Object
155 156 157 |
# File 'lib/ver/widget_major_mode.rb', line 155 def actions major.actions + minors.map{|minor| minor.actions }.flatten end |
#bind(sequence, &block) ⇒ Object
Shortcut to bind a sequence on the associated widget.
39 40 41 |
# File 'lib/ver/widget_major_mode.rb', line 39 def bind(sequence, &block) .bind(sequence, &block) end |
#bind_key(key) ⇒ Object
43 44 45 |
# File 'lib/ver/widget_major_mode.rb', line 43 def bind_key(key) major.bind_key(key) end |
#bound_keys ⇒ Object
34 35 36 |
# File 'lib/ver/widget_major_mode.rb', line 34 def bound_keys major.bound_keys end |
#establish_tag ⇒ Object
185 186 187 188 189 190 |
# File 'lib/ver/widget_major_mode.rb', line 185 def establish_tag = . specific = [0, 1] general = [-3..-1] .(*specific, major.tag, *general) end |
#forget(*minors) ⇒ Object
57 58 59 |
# File 'lib/ver/widget_major_mode.rb', line 57 def forget(*minors) self.minors -= minors.map{|name| MinorMode[name] } end |
#handle_reader(event) ⇒ Object
ignore event for now, it might be needed later
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ver/widget_major_mode.rb', line 88 def handle_reader(event) if stack.size >= read_amount stack.clear handled = true reader.call(*event_history.last(read_amount)) else handled = false end ensure self.read_amount = self.reader = nil if handled end |
#inspect ⇒ Object
175 176 177 178 179 180 181 182 183 |
# File 'lib/ver/widget_major_mode.rb', line 175 def inspect out = ['#<Ver::WidgetMajorMode'] { major: major.name, minors: minors.map{|m| m.to_sym }, event_history: event_history.map{|h| h[:keysym] }, stack: stack, }.each{|k,v| out << "#{k}=#{v.inspect}" } out.join(' ') << '>' end |
#listen ⇒ Object
30 31 32 |
# File 'lib/ver/widget_major_mode.rb', line 30 def listen VER.root.bind('<<PluginLoaded>>'){|event| synchronize } end |
#name ⇒ Object
159 160 161 |
# File 'lib/ver/widget_major_mode.rb', line 159 def name major.name end |
#on_event(event) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/ver/widget_major_mode.rb', line 61 def on_event(event) stack << event.sequence event_history << { sequence: event.sequence, keysym: event.keysym, unicode: event.unicode } return handle_reader(event) if reader && read_amount case result = resolve(stack) when Incomplete VER. result.to_s # don't do anything yet... when Impossible VER. result.to_s stack.clear else stack.clear mode, action = result = WidgetEvent.new(, event) action.call() action_history << [, *result] end end |
#read(amount, &reader) ⇒ Object
100 101 102 103 104 105 |
# File 'lib/ver/widget_major_mode.rb', line 100 def read(amount, &reader) amount = amount.to_int raise ArgumentError, "amount must be greater than 0" unless amount > 0 self.read_amount = amount self.reader = reader end |
#replace_minor(old, new) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/ver/widget_major_mode.rb', line 129 def replace_minor(old, new) old, new = MinorMode[old], MinorMode[new] minors.dup.each do |minor| if minor == old new.replaces self, old do minors[minors.index(old)] = new end else minor.replace_parent(self, old, new) end end synchronize end |
#replaced_by(other) ⇒ Object
117 118 119 120 121 |
# File 'lib/ver/widget_major_mode.rb', line 117 def replaced_by(other) Tk::Event.generate(, "<<LeaveMode>>", data: name) Tk::Event.generate(, "<<LeaveMajorMode>>", data: name) Tk::Event.generate(, "<<LeaveMajorMode#{to_camel_case}>>", data: name) end |
#replaces(other) ⇒ Object
111 112 113 114 115 |
# File 'lib/ver/widget_major_mode.rb', line 111 def replaces(other) other.replaced_by(self) if other yield if block_given? self.replacing(other) end |
#replacing(other) ⇒ Object
123 124 125 126 127 |
# File 'lib/ver/widget_major_mode.rb', line 123 def replacing(other) Tk::Event.generate(, "<<EnterMajorMode#{to_camel_case}>>", data: name) Tk::Event.generate(, "<<EnterMajorMode>>", data: name) Tk::Event.generate(, "<<EnterMode>>", data: name) end |
#resolve(sequence) ⇒ Object
107 108 109 |
# File 'lib/ver/widget_major_mode.rb', line 107 def resolve(sequence) major.resolve(sequence, minors) end |
#synchronize ⇒ Object
145 146 147 148 149 150 151 152 153 |
# File 'lib/ver/widget_major_mode.rb', line 145 def synchronize major.keymap.keys.each do |key| major.bind_key(key) end minors.each do |minor| minor.synchronize_recursively(self) end end |
#tag ⇒ Object
163 164 165 |
# File 'lib/ver/widget_major_mode.rb', line 163 def tag major.tag end |
#to_camel_case ⇒ Object
171 172 173 |
# File 'lib/ver/widget_major_mode.rb', line 171 def to_camel_case major.name.to_s.split('_').map{|e| e.capitalize}.join end |
#to_tcl ⇒ Object
167 168 169 |
# File 'lib/ver/widget_major_mode.rb', line 167 def to_tcl .tk_pathname end |
#use(*minors) ⇒ Object
47 48 49 50 51 52 53 54 55 |
# File 'lib/ver/widget_major_mode.rb', line 47 def use(*minors) minors.each do |name| minor = MinorMode[name] self.minors << minor end self.minors.uniq! synchronize end |