lib/glimmer/tk/text_proxy.rb in glimmer-dsl-tk-0.0.33 vs lib/glimmer/tk/text_proxy.rb in glimmer-dsl-tk-0.0.34
- old
+ new
@@ -34,33 +34,35 @@
def handle_listener(listener_name, &listener)
case listener_name.to_s.downcase
when '<<modified>>', '<modified>', 'modified'
modified_listener = Proc.new do |*args|
+ @modified_count ||= 0
+ @modified_count += 1
listener.call(*args)
apply_all_tag
- @insert_mark_moved_proc.call
+ @insert_mark_moved_proc&.call
@tk.modified = false
end
@tk.bind('<Modified>', modified_listener)
when '<<selection>>', '<selection>', 'selection'
@tk.bind('<Selection>', listener)
when 'destroy'
super
when 'insertmarkmove', 'insertmarkmoved', 'insert_mark_move', 'insert_mark_moved'
if @insert_mark_moved_proc.nil?
handle_listener('KeyPress') do |event|
- @insert_mark_moved_proc.call
+ @insert_mark_moved_proc&.call
end
handle_listener('KeyRelease') do |event|
- @insert_mark_moved_proc.call
+ @insert_mark_moved_proc&.call
end
handle_listener('ButtonPress') do |event|
- @insert_mark_moved_proc.call
+ @insert_mark_moved_proc&.call
end
handle_listener('ButtonRelease') do |event|
- @insert_mark_moved_proc.call
+ @insert_mark_moved_proc&.call
end
end
@insert_mark = @tk.index('insert')
@insert_mark_moved_proc = Proc.new do
new_insert_mark = @tk.index('insert')
@@ -70,48 +72,75 @@
end
end
else
apply_all_tag
# TODO make listener pass an event that has a modifiers attribute for easy representation of :shift, :meta, :control, etc... while a letter button is pressed
+ @listeners ||= {}
begin
- @tk.tag_bind(ALL_TAG, listener_name, &listener)
+ @listeners[listener_name] ||= []
+ @tk.tag_bind(ALL_TAG, listener_name) { |event| @listeners[listener_name].each {|l| l.call(event)} } if @listeners[listener_name].empty?
+ @listeners[listener_name] << listener
rescue => e
+ @listeners.delete(listener_name)
Glimmer::Config.logger.debug {"Unable to bind to #{listener_name} .. attempting to surround with <>"}
Glimmer::Config.logger.debug {e.full_message}
listener_name = "<#{listener_name}" if !listener_name.start_with?('<')
listener_name = "#{listener_name}>" if !listener_name.end_with?('>')
- @tk.tag_bind(ALL_TAG, listener_name, &listener)
+ @listeners[listener_name] ||= []
+ @tk.tag_bind(ALL_TAG, listener_name) { |event| @listeners[listener_name].each {|l| l.call(event)} } if @listeners[listener_name].empty?
+ @listeners[listener_name] << listener
end
end
end
- def add_selection_format(option, value)
- process_selection_ranges { |range_start, range_end| add_format(range_start, range_end, option, value) }
+ def edit_undo
+ @tk.edit_undo if @modified_count.to_i > 2 # <Modified> fires twice the first time, which is equivalent to one change.
end
- def remove_selection_format(option, value)
- process_selection_ranges { |range_start, range_end| remove_format(range_start, range_end, option, value) }
+ def edit_redo
+ begin
+ @tk.edit_redo
+ rescue => e
+ # No Op
+ end
end
- def toggle_selection_format(option, value)
- process_selection_ranges { |range_start, range_end| toggle_format(range_start, range_end, option, value) }
+ def add_selection_format(option, value, no_selection_default: :insert_word)
+ process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| add_format(range_start, range_end, option, value) }
end
- def add_selection_font_format(option, value)
- process_selection_ranges { |range_start, range_end| add_font_format(range_start, range_end, option, value) }
+ def remove_selection_format(option, value, no_selection_default: :insert_word)
+ process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| remove_format(range_start, range_end, option, value) }
end
- def remove_selection_font_format(option, value)
- process_selection_ranges { |range_start, range_end| remove_font_format(range_start, range_end, option, value) }
+ def toggle_selection_format(option, value, no_selection_default: :insert_word)
+ process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| toggle_format(range_start, range_end, option, value) }
end
- def toggle_selection_font_format(option, value)
- process_selection_ranges { |range_start, range_end| toggle_font_format(range_start, range_end, option, value) }
+ def add_selection_font_format(option, value, no_selection_default: :insert_word)
+ process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| add_font_format(range_start, range_end, option, value) }
end
- def process_selection_ranges(&processor)
- @tk.tag_ranges('sel').each do |region|
+ def remove_selection_font_format(option, value, no_selection_default: :insert_word)
+ process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| remove_font_format(range_start, range_end, option, value) }
+ end
+
+ def toggle_selection_font_format(option, value, no_selection_default: :insert_word)
+ process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| toggle_font_format(range_start, range_end, option, value) }
+ end
+
+ def process_selection_ranges(no_selection_default: :insert_word, &processor)
+ regions = @tk.tag_ranges('sel')
+ if regions.empty?
+ case no_selection_default
+ when :insert_word
+ regions = [[@tk.index('insert wordstart'), @tk.index('insert wordend + 1 char')]]
+ when :insert_letter
+ regions = [[@tk.index('insert'), @tk.index('insert + 1 char')]]
+ end
+ end
+ regions.each do |region|
range_start = region.first
range_end = region.last
processor.call(range_start, range_end)
end
end
@@ -149,11 +178,11 @@
values.last || (@tk.send(option) rescue FORMAT_DEFAULT_MAP[option])
end
def add_format(region_start, region_end, option, value)
@@tag_number = 0 unless defined?(@@tag_number)
- tag = "tag#{@@tag_number += 1}"
+ tag = "tag_#{option}_#{@@tag_number += 1}"
@tk.tag_configure(tag, {option => value})
@tk.tag_add(tag, region_start, region_end)
tag
end
@@ -200,10 +229,10 @@
end
def applied_font_format_tags_and_regions(region_start, region_end)
lines = value.split("\n")
tags_and_regions = []
- all_tag_names = @tk.tag_names - ['sel', ALL_TAG]
+ all_tag_names = (@tk.tag_names - ['sel', ALL_TAG]).select {|tag_name| tag_name.include?('_font_')}
(region_start.to_i..region_end.to_i).each do |line_number|
start_character_index = 0
start_character_index = region_start.to_s.split('.').last.to_i if line_number == region_start.to_i
end_character_index = lines[line_number - 1].to_s.size
end_character_index = region_end.to_s.split('.').last.to_i if line_number == region_end.to_i