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