bin/gui/gtkhex.rb in origami-1.2.7 vs bin/gui/gtkhex.rb in origami-2.0.0
- old
+ new
@@ -1,1329 +1,1314 @@
=begin
-= File
- gtkhex.rb
+ This file is part of PDF Walker, a graphical PDF file browser
+ Copyright (C) 2016 Guillaume Delugré.
-= Info
- This file is part of PDF Walker, a graphical PDF file browser
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
- All right reserved.
-
- PDF Walker is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ PDF Walker is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- PDF Walker is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ PDF Walker is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU General Public License
+ along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
- This work has been derived from the GHex project. Thanks to them.
- Original implementation: Jaka Mocnik <jaka@gnu.org>
+ This work has been derived from the GHex project. Thanks to them.
+ Original implementation: Jaka Mocnik <jaka@gnu.org>
=end
require 'gtk2'
module Gtk
-
- class HexEditor < Fixed
- module View
- HEX = 1
- ASCII = 2
- end
- module Group
- BYTE = 1
- WORD = 2
- LONG = 4
- end
+ class HexEditor < Fixed
+ module View
+ HEX = 1
+ ASCII = 2
+ end
- class Highlight
- attr_accessor :start, :end
- attr_accessor :start_line, :end_line
- attr_accessor :style
- attr_accessor :min_select
- attr_accessor :valid
- end
+ module Group
+ BYTE = 1
+ WORD = 2
+ LONG = 4
+ end
- class AutoHighlight
- attr_accessor :search_view
- attr_accessor :search_string
- attr_accessor :search_len
+ class Highlight
+ attr_accessor :start, :end
+ attr_accessor :start_line, :end_line
+ attr_accessor :style
+ attr_accessor :min_select
+ attr_accessor :valid
+ end
- attr_accessor :color
+ class AutoHighlight
+ attr_accessor :search_view
+ attr_accessor :search_string
+ attr_accessor :search_len
- attr_accessor :view_min
- attr_accessor :view_max
+ attr_accessor :color
- attr_accessor :highlights
- end
+ attr_accessor :view_min
+ attr_accessor :view_max
- DEFAULT_FONT = "Monospace 12"
- DEFAULT_CPL = 32
- DEFAULT_LINES = 16
- DISPLAY_BORDER = 4
- SCROLL_TIMEOUT = 100
+ attr_accessor :highlights
+ end
- type_register
+ DEFAULT_FONT = "Monospace 12"
+ DEFAULT_CPL = 32
+ DEFAULT_LINES = 16
+ DISPLAY_BORDER = 4
+ SCROLL_TIMEOUT = 100
- @@primary = Clipboard.get(Gdk::Selection::PRIMARY)
- @@clipboard = Clipboard.get(Gdk::Selection::CLIPBOARD)
+ type_register
- def initialize(data = '')
- super()
+ @@primary = Clipboard.get(Gdk::Selection::PRIMARY)
+ @@clipboard = Clipboard.get(Gdk::Selection::CLIPBOARD)
- @data = data
- if RUBY_VERSION >= '1.9'
- @data.force_encoding('binary')
- end
+ def initialize(data = '')
+ super()
- @scroll_timeout = -1
- @disp_buffer = ""
- @starting_offset = 0
+ @data = data.force_encoding('binary')
- @xdisp_width = @adisp_width = 200
- @xdisp_gc = @adisp_gc = nil
- @active_view = View::HEX
- @group_type = Group::BYTE
- @lines = @vis_lines = @top_line = @cpl = 0
- @cursor_pos = 0
- @lower_nibble = false
- @cursor_shown = false
- @button = 0
- @insert = false
- @selecting = false
+ @scroll_timeout = -1
+ @disp_buffer = ""
+ @starting_offset = 0
- @selection = Highlight.new
- @selection.start = @selection.end = 0
- @selection.style = nil
- @selection.min_select = 1
- @selection.valid = false
+ @xdisp_width = @adisp_width = 200
+ @xdisp_gc = @adisp_gc = nil
+ @active_view = View::HEX
+ @group_type = Group::BYTE
+ @lines = @vis_lines = @top_line = @cpl = 0
+ @cursor_pos = 0
+ @lower_nibble = false
+ @cursor_shown = false
+ @button = 0
+ @insert = false
+ @selecting = false
- @highlights = [ @selection ]
+ @selection = Highlight.new
+ @selection.start = @selection.end = 0
+ @selection.style = nil
+ @selection.min_select = 1
+ @selection.valid = false
- @auto_highlight = nil
+ @highlights = [ @selection ]
- @disp_font_metrics = load_font DEFAULT_FONT
- @font_desc = Pango::FontDescription.new DEFAULT_FONT
+ @auto_highlight = nil
- @char_width = get_max_char_width(@disp_font_metrics)
- @char_height = Pango.pixels(@disp_font_metrics.ascent) + Pango.pixels(@disp_font_metrics.descent) + 2
+ @disp_font_metrics = load_font DEFAULT_FONT
+ @font_desc = Pango::FontDescription.new DEFAULT_FONT
- self.can_focus = true
- self.events = Gdk::Event::KEY_PRESS_MASK
- self.border_width = DISPLAY_BORDER
+ @char_width = get_max_char_width(@disp_font_metrics)
+ @char_height = Pango.pixels(@disp_font_metrics.ascent) + Pango.pixels(@disp_font_metrics.descent) + 2
- mouse_handler = lambda do |widget, event|
- if event.event_type == Gdk::Event::BUTTON_RELEASE and event.button == 1
- if @scroll_timeout
- GLib::Source.remove @scroll_timeout
- @scroll_timeout = nil
- @scroll_dir = 0
- end
+ @show_offsets = false
+ @offsets_gc = nil
- @selecting = false
- Gtk.grab_remove(widget)
- @button = 0
- elsif event.event_type == Gdk::Event::BUTTON_PRESS and event.button == 1
- self.grab_focus unless self.has_focus?
+ self.can_focus = true
+ self.events = Gdk::Event::KEY_PRESS_MASK
+ self.border_width = DISPLAY_BORDER
- Gtk.grab_add(widget)
- @button = event.button
+ mouse_handler = lambda do |widget, event|
+ if event.event_type == Gdk::Event::BUTTON_RELEASE and event.button == 1
+ if @scroll_timeout
+ GLib::Source.remove @scroll_timeout
+ @scroll_timeout = nil
+ @scroll_dir = 0
+ end
- focus_view = (widget == @xdisp) ? View::HEX : View::ASCII
+ @selecting = false
+ Gtk.grab_remove(widget)
+ @button = 0
+ elsif event.event_type == Gdk::Event::BUTTON_PRESS and event.button == 1
+ self.grab_focus unless self.has_focus?
- if @active_view == focus_view
- if @active_view == View::HEX
- hex_to_pointer(event.x, event.y)
- else
- ascii_to_pointer(event.x, event.y)
+ Gtk.grab_add(widget)
+ @button = event.button
+
+ focus_view = (widget == @xdisp) ? View::HEX : View::ASCII
+
+ if @active_view == focus_view
+ if @active_view == View::HEX
+ hex_to_pointer(event.x, event.y)
+ else
+ ascii_to_pointer(event.x, event.y)
+ end
+
+ unless @selecting
+ @selecting = true
+ set_selection(@cursor_pos, @cursor_pos)
+ end
+ else
+ hide_cursor
+ @active_view = focus_view
+ show_cursor
+ end
+ elsif event.event_type == Gdk::Event::BUTTON_PRESS and event.button == 2
+ # TODO
+ else
+ @button = 0
+ end
end
- unless @selecting
- @selecting = true
- set_selection(@cursor_pos, @cursor_pos)
+ @xdisp = DrawingArea.new
+ @xdisp.modify_font @font_desc
+ @xlayout = @xdisp.create_pango_layout('')
+ @xdisp.events =
+ Gdk::Event::EXPOSURE_MASK |
+ Gdk::Event::BUTTON_PRESS_MASK |
+ Gdk::Event::BUTTON_RELEASE_MASK |
+ Gdk::Event::BUTTON_MOTION_MASK |
+ Gdk::Event::SCROLL_MASK
+
+ @xdisp.signal_connect 'realize' do
+ @xdisp_gc = Gdk::GC.new(@xdisp.window)
+ @xdisp_gc.set_exposures(true)
end
- else
- hide_cursor
- @active_view = focus_view
- show_cursor
- end
- elsif event.event_type == Gdk::Event::BUTTON_PRESS and event.button == 2
- # TODO
- else
- @button = 0
- end
- end
- @xdisp = DrawingArea.new
- @xdisp.modify_font @font_desc
- @xlayout = @xdisp.create_pango_layout('')
- @xdisp.events =
- Gdk::Event::EXPOSURE_MASK |
- Gdk::Event::BUTTON_PRESS_MASK |
- Gdk::Event::BUTTON_RELEASE_MASK |
- Gdk::Event::BUTTON_MOTION_MASK |
- Gdk::Event::SCROLL_MASK
+ @xdisp.signal_connect 'expose_event' do |xdisp, event|
+ imin = (event.area.y / @char_height).to_i
+ imax = ((event.area.y + event.area.height) / @char_height).to_i
+ imax += 1 if (event.area.y + event.area.height).to_i % @char_height != 0
- @xdisp.signal_connect 'realize' do
- @xdisp_gc = Gdk::GC.new(@xdisp.window)
- @xdisp_gc.set_exposures(true)
- end
+ imax = [ imax, @vis_lines ].min
- @xdisp.signal_connect 'expose_event' do |xdisp, event|
- imin = (event.area.y / @char_height).to_i
- imax = ((event.area.y + event.area.height) / @char_height).to_i
- imax += 1 if (event.area.y + event.area.height).to_i % @char_height != 0
+ render_hex_lines(imin, imax)
+ end
- imax = [ imax, @vis_lines ].min
+ @xdisp.signal_connect 'scroll_event' do |xdisp, event|
+ @scrollbar.event(event)
+ end
- render_hex_lines(imin, imax)
- end
+ @xdisp.signal_connect 'button_press_event' do |xdisp, event|
+ mouse_handler[xdisp, event]
+ end
- @xdisp.signal_connect 'scroll_event' do |xdisp, event|
- @scrollbar.event(event)
- end
+ @xdisp.signal_connect 'button_release_event' do |xdisp, event|
+ mouse_handler[xdisp, event]
+ end
- @xdisp.signal_connect 'button_press_event' do |xdisp, event|
- mouse_handler[xdisp, event]
- end
+ @xdisp.signal_connect 'motion_notify_event' do |xdisp, event|
+ _w, x, y, _m = xdisp.window.pointer
- @xdisp.signal_connect 'button_release_event' do |xdisp, event|
- mouse_handler[xdisp, event]
- end
+ if y < 0
+ @scroll_dir = -1
+ elsif y >= xdisp.allocation.height
+ @scroll_dir = 1
+ else
+ @scroll_dir = 0
+ end
- @xdisp.signal_connect 'motion_notify_event' do |xdisp, event|
- w, x, y, m = xdisp.window.pointer
+ if @scroll_dir != 0
+ if @scroll_timeout == nil
+ @scroll_timeout = GLib::Timeout.add(SCROLL_TIMEOUT) {
+ if @scroll_dir < 0
+ set_cursor([ 0, @cursor_pos - @cpl ].max)
+ elsif @scroll_dir > 0
+ set_cursor([ @data.size - 1, @cursor_pos + @cpl ].min)
+ end
- if y < 0
- @scroll_dir = -1
- elsif y >= xdisp.allocation.height
- @scroll_dir = 1
- else
- @scroll_dir = 0
- end
+ true
+ }
+ next
+ end
+ else
+ if @scroll_timeout != nil
+ GLib::Source.remove @scroll_timeout
+ @scroll_timeout = nil
+ end
+ end
- if @scroll_dir != 0
- if @scroll_timeout == nil
- @scroll_timeout = GLib::Timeout.add(SCROLL_TIMEOUT) {
- if @scroll_dir < 0
- set_cursor([ 0, @cursor_pos - @cpl ].max)
- elsif @scroll_dir > 0
- set_cursor([ @data.size - 1, @cursor_pos + @cpl ].min)
- end
+ next if event.window != xdisp.window
- true
- }
- next
- end
- else
- if @scroll_timeout != nil
- GLib::Source.remove @scroll_timeout
- @scroll_timeout = nil
- end
- end
+ hex_to_pointer(x,y) if @active_view == View::HEX and @button == 1
+ end
- next if event.window != xdisp.window
+ put @xdisp, 0, 0
+ @xdisp.show
- hex_to_pointer(x,y) if @active_view == View::HEX and @button == 1
- end
-
- put @xdisp, 0, 0
- @xdisp.show
+ @adisp = DrawingArea.new
+ @adisp.modify_font @font_desc
+ @alayout = @adisp.create_pango_layout('')
+ @adisp.events =
+ Gdk::Event::EXPOSURE_MASK |
+ Gdk::Event::BUTTON_PRESS_MASK |
+ Gdk::Event::BUTTON_RELEASE_MASK |
+ Gdk::Event::BUTTON_MOTION_MASK |
+ Gdk::Event::SCROLL_MASK
- @adisp = DrawingArea.new
- @adisp.modify_font @font_desc
- @alayout = @adisp.create_pango_layout('')
- @adisp.events =
- Gdk::Event::EXPOSURE_MASK |
- Gdk::Event::BUTTON_PRESS_MASK |
- Gdk::Event::BUTTON_RELEASE_MASK |
- Gdk::Event::BUTTON_MOTION_MASK |
- Gdk::Event::SCROLL_MASK
+ @adisp.signal_connect 'realize' do
+ @adisp_gc = Gdk::GC.new(@adisp.window)
+ @adisp_gc.set_exposures(true)
+ end
-
- @adisp.signal_connect 'realize' do
- @adisp_gc = Gdk::GC.new(@adisp.window)
- @adisp_gc.set_exposures(true)
- end
+ @adisp.signal_connect 'expose_event' do |adisp, event|
+ imin = (event.area.y / @char_height).to_i
+ imax = ((event.area.y + event.area.height) / @char_height).to_i
+ imax += 1 if (event.area.y + event.area.height).to_i % @char_height != 0
- @adisp.signal_connect 'expose_event' do |adisp, event|
- imin = (event.area.y / @char_height).to_i
- imax = ((event.area.y + event.area.height) / @char_height).to_i
- imax += 1 if (event.area.y + event.area.height).to_i % @char_height != 0
+ imax = [ imax, @vis_lines ].min
+ render_ascii_lines(imin, imax)
+ end
- imax = [ imax, @vis_lines ].min
- render_ascii_lines(imin, imax)
- end
+ @adisp.signal_connect 'scroll_event' do |adisp, event|
+ @scrollbar.event(event)
+ end
- @adisp.signal_connect 'scroll_event' do |adisp, event|
- @scrollbar.event(event)
- end
+ @adisp.signal_connect 'button_press_event' do |adisp, event|
+ mouse_handler[adisp, event]
+ end
- @adisp.signal_connect 'button_press_event' do |adisp, event|
- mouse_handler[adisp, event]
- end
+ @adisp.signal_connect 'button_release_event' do |adisp, event|
+ mouse_handler[adisp, event]
+ end
- @adisp.signal_connect 'button_release_event' do |adisp, event|
- mouse_handler[adisp, event]
- end
+ @adisp.signal_connect 'motion_notify_event' do |adisp, event|
+ _w, x, y, _m = adisp.window.pointer
- @adisp.signal_connect 'motion_notify_event' do |adisp, event|
- w, x, y, m = adisp.window.pointer
+ if y < 0
+ @scroll_dir = -1
+ elsif y >= adisp.allocation.height
+ @scroll_dir = 1
+ else
+ @scroll_dir = 0
+ end
- if y < 0
- @scroll_dir = -1
- elsif y >= adisp.allocation.height
- @scroll_dir = 1
- else
- @scroll_dir = 0
- end
+ if @scroll_dir != 0
+ if @scroll_timeout == nil
+ @scroll_timeout = GLib::Timeout.add(SCROLL_TIMEOUT) {
+ if @scroll_dir < 0
+ set_cursor([ 0, @cursor_pos - @cpl ].max)
+ elsif @scroll_dir > 0
+ set_cursor([ @data.size - 1, @cursor_pos + @cpl ].min)
+ end
- if @scroll_dir != 0
- if @scroll_timeout == nil
- @scroll_timeout = GLib::Timeout.add(SCROLL_TIMEOUT) {
- if @scroll_dir < 0
- set_cursor([ 0, @cursor_pos - @cpl ].max)
- elsif @scroll_dir > 0
- set_cursor([ @data.size - 1, @cursor_pos + @cpl ].min)
- end
+ true
+ }
+ next
+ end
+ else
+ if @scroll_timeout != nil
+ GLib::Source.remove @scroll_timeout
+ @scroll_timeout = nil
+ end
+ end
- true
- }
- next
- end
- else
- if @scroll_timeout != nil
- GLib::Source.remove @scroll_timeout
- @scroll_timeout = nil
- end
- end
+ next if event.window != adisp.window
- next if event.window != adisp.window
+ ascii_to_pointer(x,y) if @active_view == View::ASCII and @button == 1
+ end
- ascii_to_pointer(x,y) if @active_view == View::ASCII and @button == 1
- end
-
- put @adisp, 0, 0
- @adisp.show
+ put @adisp, 0, 0
+ @adisp.show
- @adj = Gtk::Adjustment.new(0, 0, 0, 0, 0, 0)
- @scrollbar = Gtk::VScrollbar.new(@adj)
- @adj.signal_connect 'value_changed' do |adj|
- unless @xdisp_gc.nil? or @adisp_gc.nil? or not @xdisp.drawable? or not @adisp.drawable?
-
- source_min = (adj.value.to_i - @top_line) * @char_height
- source_max = source_min + @xdisp.allocation.height
- dest_min = 0
- dest_max = @xdisp.allocation.height
+ @adj = Gtk::Adjustment.new(0, 0, 0, 0, 0, 0)
+ @scrollbar = Gtk::VScrollbar.new(@adj)
+ @adj.signal_connect 'value_changed' do |adj|
+ unless @xdisp_gc.nil? or @adisp_gc.nil? or not @xdisp.drawable? or not @adisp.drawable?
+ source_min = (adj.value.to_i - @top_line) * @char_height
+ source_max = source_min + @xdisp.allocation.height
+ dest_min = 0
+ dest_max = @xdisp.allocation.height
- rect = Gdk::Rectangle.new(0, 0, 0, 0)
- @top_line = adj.value.to_i
- if source_min < 0
- rect.y = 0
- rect.height = -source_min
- rect_height = [ rect.height, @xdisp.allocation.height ].min
- source_min = 0
- dest_min = rect.height
- else
- rect.y = 2 * @xdisp.allocation.height - source_max
- rect.y = 0 if rect.y < 0
- rect.height = @xdisp.allocation.height - rect.y
- source_max = @xdisp.allocation.height
- dest_max = rect.y
- end
+ rect = Gdk::Rectangle.new(0, 0, 0, 0)
+ @top_line = adj.value.to_i
+ if source_min < 0
+ rect.y = 0
+ rect.height = -source_min
+ rect_height = [ rect.height, @xdisp.allocation.height ].min
+ source_min = 0
+ dest_min = rect.height
+ else
+ rect.y = 2 * @xdisp.allocation.height - source_max
+ rect.y = 0 if rect.y < 0
+ rect.height = @xdisp.allocation.height - rect.y
+ source_max = @xdisp.allocation.height
+ dest_max = rect.y
+ end
- if source_min != source_max
- @xdisp.window.draw_drawable(
- @xdisp_gc,
- @xdisp.window,
- 0, source_min,
- 0, dest_min,
- @xdisp.allocation.width,
- source_max - source_min
- )
- @adisp.window.draw_drawable(
- @adisp_gc,
- @adisp.window,
- 0, source_min,
- 0, dest_min,
- @adisp.allocation.width,
- source_max - source_min
- )
+ if source_min != source_max
+ @xdisp.window.draw_drawable(
+ @xdisp_gc,
+ @xdisp.window,
+ 0, source_min,
+ 0, dest_min,
+ @xdisp.allocation.width,
+ source_max - source_min
+ )
+ @adisp.window.draw_drawable(
+ @adisp_gc,
+ @adisp.window,
+ 0, source_min,
+ 0, dest_min,
+ @adisp.allocation.width,
+ source_max - source_min
+ )
- if @offsets
- if @offsets_gc.nil?
- @offsets_gc = Gdk::GC.new(@offsets.window)
- @offsets_gc.set_exposures(true)
- end
+ if @offsets
+ if @offsets_gc.nil?
+ @offsets_gc = Gdk::GC.new(@offsets.window)
+ @offsets_gc.set_exposures(true)
+ end
- @offsets.window.draw_drawable(
- @offsets_gc,
- @offsets.window,
- 0, source_min,
- 0, dest_min,
- @offsets.allocation.width,
- source_max - source_min
- )
- end
+ @offsets.window.draw_drawable(
+ @offsets_gc,
+ @offsets.window,
+ 0, source_min,
+ 0, dest_min,
+ @offsets.allocation.width,
+ source_max - source_min
+ )
+ end
- # TODO update_all_auto_highlights(true, true)
- invalidate_all_highlights
-
- rect.width = @xdisp.allocation.width
- @xdisp.window.invalidate(rect, false)
- rect.width = @adisp.allocation.width
- @adisp.window.invalidate(rect, false)
+ # TODO update_all_auto_highlights(true, true)
+ invalidate_all_highlights
- if @offsets
- rect.width = @offsets.allocation.width
- @offsets.window.invalidate(rect, false)
+ rect.width = @xdisp.allocation.width
+ @xdisp.window.invalidate(rect, false)
+ rect.width = @adisp.allocation.width
+ @adisp.window.invalidate(rect, false)
+
+ if @offsets
+ rect.width = @offsets.allocation.width
+ @offsets.window.invalidate(rect, false)
+ end
+ end
+ end
end
- end
+
+ put @scrollbar, 0, 0
+ @scrollbar.show
end
- end
- put @scrollbar, 0, 0
- @scrollbar.show
- end
+ def set_selection(s, e)
+ e = [ e, @data.size ].min
- def set_selection(s, e)
- e = [ e, @data.size ].min
+ @@primary.clear if @selection.start != @selection.end
- @@primary.clear if @selection.start != @selection.end
+ os, oe = [ @selection.start, @selection.end ].sort
- os, oe = [ @selection.start, @selection.end ].sort
+ @selection.start = [ 0, s ].max
+ @selection.start = [ @selection.start, @data.size ].min
+ @selection.end = [ e, @data.size ].min
- @selection.start = [ 0, s ].max
- @selection.start = [ @selection.start, @data.size ].min
- @selection.end = [ e, @data.size ].min
+ invalidate_highlight(@selection)
- invalidate_highlight(@selection)
+ ns, ne = [ @selection.start, @selection.end ].sort
- ns, ne = [ @selection.start, @selection.end ].sort
+ if ns != os and ne != oe
+ bytes_changed([ns, os].min, [ne, oe].max)
+ elsif ne != oe
+ bytes_changed(*[ne, oe].sort)
+ elsif ns != os
+ bytes_changed(*[ns, os].sort)
+ end
- if ns != os and ne != oe
- bytes_changed([ns, os].min, [ne, oe].max)
- elsif ne != oe
- bytes_changed(*[ne, oe].sort)
- elsif ns != os
- bytes_changed(*[ns, os].sort)
- end
+ if @selection.start != @selection.end
+ if @active_view == View::HEX
+ brk_len = 2 * @cpl + @cpl / @group_type
+ format_xblock(s,e)
+ (@disp_buffer.size / brk_len + 1).times do |i| @disp_buffer.insert(i * (brk_len + 1), $/) end
+ else
+ brk_len = @cpl
+ format_ablock(s,e)
+ end
- if @selection.start != @selection.end
- if @active_view == View::HEX
- brk_len = 2 * @cpl + @cpl / @group_type
- format_xblock(s,e)
- (@disp_buffer.size / brk_len + 1).times do |i| @disp_buffer.insert(i * (brk_len + 1), $/) end
- else
- brk_len = @cpl
- format_ablock(s,e)
+ @@primary.set_text(@disp_buffer)
+ end
end
- @@primary.set_text(@disp_buffer)
- end
- end
+ def get_selection
+ [ @selection.start, @selection.end ].sort
+ end
- def get_selection
- [ @selection.start, @selection.end ].sort
- end
+ def clear_selection
+ set_selection(0, 0)
+ end
- def clear_selection
- set_selection(0, 0)
- end
+ def cursor
+ @cursor_pos
+ end
- def cursor
- @cursor_pos
- end
+ def set_cursor(index)
+ return if index < 0 or index > @data.size
- def set_cursor(index)
- return if index < 0 or index > @data.size
+ old_pos = @cursor_pos
+ index -= 1 if @insert and index == @data.size
+ index = [ 0, index ].max
- old_pos = @cursor_pos
- index -= 1 if @insert and index == @data.size
- index = [ 0, index ].max
+ hide_cursor
- hide_cursor
-
- @cursor_pos = index
- return if @cpl == 0
+ @cursor_pos = index
+ return if @cpl == 0
- y = index / @cpl
- if y >= @top_line + @vis_lines
- @adj.value = [ y - @vis_lines + 1, @lines - @vis_lines ].min
- @adj.value = [ 0, @adj.value ].max
- @adj.signal_emit 'value_changed'
- elsif y < @top_line
- @adj.value = y
- @adj.signal_emit 'value_changed'
- end
+ y = index / @cpl
+ if y >= @top_line + @vis_lines
+ @adj.value = [ y - @vis_lines + 1, @lines - @vis_lines ].min
+ @adj.value = [ 0, @adj.value ].max
+ @adj.signal_emit 'value_changed'
+ elsif y < @top_line
+ @adj.value = y
+ @adj.signal_emit 'value_changed'
+ end
- @lower_nibble = false if index == @data.size
+ @lower_nibble = false if index == @data.size
- if @selecting
- set_selection(@selection.start, @cursor_pos)
- bytes_changed(*[@cursor_pos, old_pos].sort)
- else# @selection.start != @selection.end
- s, e = [@selection.start, @selection.end].sort
- @selection.end = @selection.start = @cursor_pos
- bytes_changed(s, e)
- end
+ if @selecting
+ set_selection(@selection.start, @cursor_pos)
+ bytes_changed(*[@cursor_pos, old_pos].sort)
+ else# @selection.start != @selection.end
+ s, e = [@selection.start, @selection.end].sort
+ @selection.end = @selection.start = @cursor_pos
+ bytes_changed(s, e)
+ end
- self.signal_emit 'cursor_moved'
+ self.signal_emit 'cursor_moved'
- bytes_changed(old_pos, old_pos)
- show_cursor
- end
+ bytes_changed(old_pos, old_pos)
+ show_cursor
+ end
- def set_cursor_xy(x, y)
- pos = y.to_i * @cpl + x.to_i
- return if y < 0 or y >= @lines or x < 0 or x >= @cpl or pos > @data.size
+ def set_cursor_xy(x, y)
+ pos = y.to_i * @cpl + x.to_i
+ return if y < 0 or y >= @lines or x < 0 or x >= @cpl or pos > @data.size
- set_cursor(pos)
- end
+ set_cursor(pos)
+ end
- def set_cursor_on_lower_nibble(bool)
- if @selecting
- bytes_changed(@cursor_pos, @cursor_pos)
- @lower_nibble = bool
- elsif @selection.start != @selection.end
- s, e = [ @selection.start, @selection.end ].sort
+ def set_cursor_on_lower_nibble(bool)
+ if @selecting
+ bytes_changed(@cursor_pos, @cursor_pos)
+ @lower_nibble = bool
+ elsif @selection.start != @selection.end
+ s, e = [ @selection.start, @selection.end ].sort
- @selection.start = @selection.end = 0
- bytes_changed(s, e)
- @lower_nibble = bool
- else
- hide_cursor
- @lower_nibble = bool
- show_cursor
- end
- end
+ @selection.start = @selection.end = 0
+ bytes_changed(s, e)
+ @lower_nibble = bool
+ else
+ hide_cursor
+ @lower_nibble = bool
+ show_cursor
+ end
+ end
- def set_group_type(type)
- hide_cursor
- @group_type = type
- recalc_displays(self.allocation.width, self.allocation.height)
- self.queue_resize
- show_cursor
- end
+ def set_group_type(type)
+ hide_cursor
+ @group_type = type
+ recalc_displays(self.allocation.width, self.allocation.height)
+ self.queue_resize
+ show_cursor
+ end
- def show_offsets(bool)
- return unless @show_offsets ^ bool
+ def show_offsets(bool)
+ return unless @show_offsets ^ bool
- @show_offsets = bool
- if bool
- show_offsets_widget
- else
- hide_offsets_widget
- end
- end
+ @show_offsets = bool
+ if bool
+ show_offsets_widget
+ else
+ hide_offsets_widget
+ end
+ end
- def set_font(fontname)
- @font_desc = Pango::FontDescription.new(fontname)
- @disp_font_metrics = load_font(fontname)
+ def set_font(fontname)
+ @font_desc = Pango::FontDescription.new(fontname)
+ @disp_font_metrics = load_font(fontname)
- @xdisp.modify_font(@font_desc) if @xdisp
- @adisp.modify_font(@font_desc) if @adisp
- @offsets.modify_font(@font_desc) if @offsets
+ @xdisp.modify_font(@font_desc) if @xdisp
+ @adisp.modify_font(@font_desc) if @adisp
+ @offsets.modify_font(@font_desc) if @offsets
- @char_width = get_max_char_width(@disp_font_metrics)
- @char_height = Pango.pixels(@disp_font_metrics.ascent) + Pango.pixels(@disp_font_metrics.descent) + 2
- recalc_displays(self.allocation.width, self.allocation.height)
+ @char_width = get_max_char_width(@disp_font_metrics)
+ @char_height = Pango.pixels(@disp_font_metrics.ascent) + Pango.pixels(@disp_font_metrics.descent) + 2
+ recalc_displays(self.allocation.width, self.allocation.height)
- redraw_widget
- end
+ redraw_widget
+ end
- def set_data(data)
- prev_data_size = @data.size
- @data = data.dup
+ def set_data(data)
+ prev_data_size = @data.size
+ @data = data.dup
- recalc_displays(self.allocation.width, self.allocation.height)
-
- set_cursor 0
- bytes_changed(0, [ prev_data_size, @data.size ].max)
- redraw_widget
- end
+ recalc_displays(self.allocation.width, self.allocation.height)
- def validate_highlight(hl)
- unless hl.valid
- hl.start_line = [ hl.start, hl.end ].min / @cpl - @top_line
- hl.end_line = [ hl.start, hl.end ].max / @cpl - @top_line
- hl.valid = true
- end
- end
+ set_cursor 0
+ bytes_changed(0, [ prev_data_size, @data.size ].max)
+ redraw_widget
+ end
- def invalidate_highlight(hl)
- hl.valid = false
- end
+ def validate_highlight(hl)
+ unless hl.valid
+ hl.start_line = [ hl.start, hl.end ].min / @cpl - @top_line
+ hl.end_line = [ hl.start, hl.end ].max / @cpl - @top_line
+ hl.valid = true
+ end
+ end
- def invalidate_all_highlights
- @highlights.each do |hl| invalidate_highlight(hl) end
- end
+ def invalidate_highlight(hl)
+ hl.valid = false
+ end
- private
+ def invalidate_all_highlights
+ @highlights.each do |hl| invalidate_highlight(hl) end
+ end
- signal_new(
- 'data_changed',
- GLib::Signal::RUN_FIRST,
- nil,
- nil,
- String
- )
+ private
- signal_new(
- 'cursor_moved',
- GLib::Signal::RUN_FIRST,
- nil,
- nil
- )
+ signal_new(
+ 'data_changed',
+ GLib::Signal::RUN_FIRST,
+ nil,
+ nil,
+ String
+ )
- def signal_do_cursor_moved
- end
+ signal_new(
+ 'cursor_moved',
+ GLib::Signal::RUN_FIRST,
+ nil,
+ nil
+ )
- def signal_do_data_changed(data)
- # TODO
- end
+ def signal_do_cursor_moved
+ end
- def signal_do_realize
- super
+ def signal_do_data_changed(data)
+ # TODO
+ end
- self.window.set_back_pixmap(nil, true)
- end
+ def signal_do_realize
+ super
- def signal_do_size_allocate(alloc)
- hide_cursor
+ self.window.set_back_pixmap(nil, true)
+ end
- recalc_displays(alloc.width, alloc.height)
+ def signal_do_size_allocate(alloc)
+ hide_cursor
- self.set_allocation(alloc.x, alloc.y, alloc.width, alloc.height)
- self.window.move_resize(
- alloc.x, alloc.y,
- alloc.width, alloc.height
- ) if self.realized?
+ recalc_displays(alloc.width, alloc.height)
- bw = self.border_width
- xt = widget_get_xt
- yt = widget_get_yt
+ self.set_allocation(alloc.x, alloc.y, alloc.width, alloc.height)
+ self.window.move_resize(
+ alloc.x, alloc.y,
+ alloc.width, alloc.height
+ ) if self.realized?
- my_alloc = Gtk::Allocation.new(0, 0, 0, 0)
- my_alloc.x = bw + xt
- my_alloc.y = bw + yt
- my_alloc.height = [ alloc.height - 2*bw - 2*yt, 1 ].max
- if @show_offsets
- my_alloc.width = 8 * @char_width
- @offsets.size_allocate(my_alloc)
- @offsets.queue_draw
- my_alloc.x += 2*xt + my_alloc.width
- end
+ bw = self.border_width
+ xt = widget_get_xt
+ yt = widget_get_yt
- my_alloc.width = @xdisp_width
- @xdisp.size_allocate(my_alloc)
+ my_alloc = Gtk::Allocation.new(0, 0, 0, 0)
+ my_alloc.x = bw + xt
+ my_alloc.y = bw + yt
+ my_alloc.height = [ alloc.height - 2*bw - 2*yt, 1 ].max
+ if @show_offsets
+ my_alloc.width = 8 * @char_width
+ @offsets.size_allocate(my_alloc)
+ @offsets.queue_draw
+ my_alloc.x += 2*xt + my_alloc.width
+ end
- my_alloc.x = alloc.width - bw - @scrollbar.requisition[0]
- my_alloc.y = bw
- my_alloc.width = @scrollbar.requisition[0]
- my_alloc.height = [ alloc.height - 2*bw, 1 ].max
- @scrollbar.size_allocate(my_alloc)
+ my_alloc.width = @xdisp_width
+ @xdisp.size_allocate(my_alloc)
- my_alloc.x -= @adisp_width + xt
- my_alloc.y = bw + yt
- my_alloc.width = @adisp_width
- my_alloc.height = [ alloc.height - 2*bw - 2*yt, 1 ].max
- @adisp.size_allocate(my_alloc)
+ my_alloc.x = alloc.width - bw - @scrollbar.requisition[0]
+ my_alloc.y = bw
+ my_alloc.width = @scrollbar.requisition[0]
+ my_alloc.height = [ alloc.height - 2*bw, 1 ].max
+ @scrollbar.size_allocate(my_alloc)
- show_cursor
- end
+ my_alloc.x -= @adisp_width + xt
+ my_alloc.y = bw + yt
+ my_alloc.width = @adisp_width
+ my_alloc.height = [ alloc.height - 2*bw - 2*yt, 1 ].max
+ @adisp.size_allocate(my_alloc)
- def signal_do_size_request(req)
- sb_width, sb_height = @scrollbar.size_request
- bw = self.border_width
- xt, yt = widget_get_xt, widget_get_yt
+ show_cursor
+ end
- width = 4*xt + 2*bw + sb_width +
- @char_width*(DEFAULT_CPL + (DEFAULT_CPL-1)/@group_type)
+ def signal_do_size_request(req)
+ sb_width, _sb_height = @scrollbar.size_request
+ bw = self.border_width
+ xt, yt = widget_get_xt, widget_get_yt
- width += 2*xt + 8*@char_width if @show_offsets
+ width = 4*xt + 2*bw + sb_width +
+ @char_width*(DEFAULT_CPL + (DEFAULT_CPL-1)/@group_type)
- height = DEFAULT_LINES * @char_height + 2*yt + 2*bw
-
- req[0] = width
- req[1] = height
- end
+ width += 2*xt + 8*@char_width if @show_offsets
- def signal_do_expose_event(event)
- draw_shadow(event.area)
- super(event)
+ height = DEFAULT_LINES * @char_height + 2*yt + 2*bw
- true
- end
+ req[0] = width
+ req[1] = height
+ end
- def signal_do_key_press_event(event)
- old_cp = @cursor_pos
+ def signal_do_expose_event(event)
+ draw_shadow(event.area)
+ super(event)
- hide_cursor
- @selecting = (event.state & Gdk::Window::SHIFT_MASK) != 0
- ret = true
+ true
+ end
- case event.keyval
- when Gdk::Keyval::GDK_KP_Tab, Gdk::Keyval::GDK_Tab
- @active_view = (@active_view == View::HEX) ? View::ASCII : View::HEX
-
- when Gdk::Keyval::GDK_Up
- set_cursor(@cursor_pos - @cpl)
+ def signal_do_key_press_event(event)
- when Gdk::Keyval::GDK_Down
- set_cursor(@cursor_pos + @cpl)
+ hide_cursor
+ @selecting = (event.state & Gdk::Window::SHIFT_MASK) != 0
+ ret = true
- when Gdk::Keyval::GDK_Page_Up
- set_cursor([0, @cursor_pos - @vis_lines * @cpl].max)
+ case event.keyval
+ when Gdk::Keyval::GDK_KP_Tab, Gdk::Keyval::GDK_Tab
+ @active_view = (@active_view == View::HEX) ? View::ASCII : View::HEX
- when Gdk::Keyval::GDK_Page_Down
- set_cursor([@cursor_pos + @vis_lines * @cpl, @data.size].min)
+ when Gdk::Keyval::GDK_Up
+ set_cursor(@cursor_pos - @cpl)
- when Gdk::Keyval::GDK_Left
- if @active_view == View::HEX
- if @selecting
- set_cursor(@cursor_pos - 1)
- else
- @lower_nibble ^= 1
- set_cursor(@cursor_pos - 1) if @lower_nibble
- end
- else
- set_cursor(@cursor_pos - 1)
- end
+ when Gdk::Keyval::GDK_Down
+ set_cursor(@cursor_pos + @cpl)
- when Gdk::Keyval::GDK_Right
- if @active_view == View::HEX
- if @selecting
- set_cursor(@cursor_pos + 1)
- else
- @lower_nibble ^= 1
- set_cursor(@cursor_pos + 1) unless @lower_nibble
- end
- else
- set_cursor(@cursor_pos + 1)
- end
+ when Gdk::Keyval::GDK_Page_Up
+ set_cursor([0, @cursor_pos - @vis_lines * @cpl].max)
- when Gdk::Keyval::GDK_c, Gdk::Keyval::GDK_C
- if event.state & Gdk::Window::CONTROL_MASK != 0
- s,e = @selection.start, @selection.end + 1
- if @active_view == View::HEX
- brk_len = 2 * @cpl + @cpl / @group_type
- format_xblock(s,e)
- (@disp_buffer.size / brk_len + 1).times do |i| @disp_buffer.insert(i * (brk_len + 1), $/) end
+ when Gdk::Keyval::GDK_Page_Down
+ set_cursor([@cursor_pos + @vis_lines * @cpl, @data.size].min)
+
+ when Gdk::Keyval::GDK_Left
+ if @active_view == View::HEX
+ if @selecting
+ set_cursor(@cursor_pos - 1)
+ else
+ @lower_nibble ^= 1
+ set_cursor(@cursor_pos - 1) if @lower_nibble
+ end
+ else
+ set_cursor(@cursor_pos - 1)
+ end
+
+ when Gdk::Keyval::GDK_Right
+ if @active_view == View::HEX
+ if @selecting
+ set_cursor(@cursor_pos + 1)
+ else
+ @lower_nibble ^= 1
+ set_cursor(@cursor_pos + 1) unless @lower_nibble
+ end
+ else
+ set_cursor(@cursor_pos + 1)
+ end
+
+ when Gdk::Keyval::GDK_c, Gdk::Keyval::GDK_C
+ if event.state & Gdk::Window::CONTROL_MASK != 0
+ s,e = @selection.start, @selection.end + 1
+ if @active_view == View::HEX
+ brk_len = 2 * @cpl + @cpl / @group_type
+ format_xblock(s,e)
+ (@disp_buffer.size / brk_len + 1).times do |i| @disp_buffer.insert(i * (brk_len + 1), $/) end
+ else
+ brk_len = @cpl
+ format_ablock(s,e)
+ end
+
+ @@clipboard.set_text(@disp_buffer)
+ end
else
- brk_len = @cpl
- format_ablock(s,e)
+ ret = false
end
- @@clipboard.set_text(@disp_buffer)
- end
- else
- ret = false
- end
+ show_cursor
- show_cursor
-
- ret
- end
+ ret
+ end
- def hex_to_pointer(mx, my)
- cy = @top_line + my.to_i / @char_height
-
- cx = x = 0
- while cx < 2 * @cpl
- x += @char_width
+ def hex_to_pointer(mx, my)
+ cy = @top_line + my.to_i / @char_height
- if x > mx
- set_cursor_xy(cx / 2, cy)
- set_cursor_on_lower_nibble(cx % 2 != 0)
+ cx = x = 0
+ while cx < 2 * @cpl
+ x += @char_width
- cx = 2 * @cpl
- end
+ if x > mx
+ set_cursor_xy(cx / 2, cy)
+ set_cursor_on_lower_nibble(cx % 2 != 0)
- cx += 1
- x += @char_width if ( cx % (2 * @group_type) == 0 )
- end
- end
+ cx = 2 * @cpl
+ end
- def ascii_to_pointer(mx, my)
- cx = mx / @char_width
- cy = @top_line + my / @char_height
+ cx += 1
+ x += @char_width if ( cx % (2 * @group_type) == 0 )
+ end
+ end
- set_cursor_xy(cx, cy)
- end
+ def ascii_to_pointer(mx, my)
+ cx = mx / @char_width
+ cy = @top_line + my / @char_height
- def load_font(fontname)
- desc = Pango::FontDescription.new(fontname)
- context = Gdk::Pango.context
- context.set_language(Gtk.default_language)
-
- font = context.load_font(desc)
-
- font.metrics(context.language)
- end
+ set_cursor_xy(cx, cy)
+ end
- def draw_shadow(area)
- bw = self.border_width
- x = bw
- xt = widget_get_xt
+ def load_font(fontname)
+ desc = Pango::FontDescription.new(fontname)
+ context = Gdk::Pango.context
+ context.set_language(Gtk.default_language)
- if @show_offsets
- self.style.paint_shadow(
- self.window,
- Gtk::STATE_NORMAL, Gtk::SHADOW_IN,
- nil, self, nil,
- bw, bw,
- 8*@char_width + 2*xt, self.allocation.height - 2*bw
- )
+ font = context.load_font(desc)
- x += 8*@char_width + 2*xt
- end
+ font.metrics(context.language)
+ end
- self.style.paint_shadow(
- self.window,
- Gtk::STATE_NORMAL, Gtk::SHADOW_IN,
- nil, self, nil,
- x, bw,
- @xdisp_width + 2*xt, self.allocation.height - 2*bw
- )
+ def draw_shadow(area)
+ bw = self.border_width
+ x = bw
+ xt = widget_get_xt
- self.style.paint_shadow(
- self.window,
- Gtk::STATE_NORMAL, Gtk::SHADOW_IN,
- nil, self, nil,
- self.allocation.width - bw - @adisp_width - @scrollbar.requisition[0] - 2*xt, bw,
- @adisp_width + 2*xt, self.allocation.height - 2*bw
- )
- end
+ if @show_offsets
+ self.style.paint_shadow(
+ self.window,
+ Gtk::STATE_NORMAL, Gtk::SHADOW_IN,
+ nil, self, nil,
+ bw, bw,
+ 8*@char_width + 2*xt, self.allocation.height - 2*bw
+ )
- def redraw_widget
- return unless self.realized?
+ x += 8*@char_width + 2*xt
+ end
- self.window.invalidate(nil, false)
- end
+ self.style.paint_shadow(
+ self.window,
+ Gtk::STATE_NORMAL, Gtk::SHADOW_IN,
+ nil, self, nil,
+ x, bw,
+ @xdisp_width + 2*xt, self.allocation.height - 2*bw
+ )
- def widget_get_xt
- self.style.xthickness
- end
+ self.style.paint_shadow(
+ self.window,
+ Gtk::STATE_NORMAL, Gtk::SHADOW_IN,
+ nil, self, nil,
+ self.allocation.width - bw - @adisp_width - @scrollbar.requisition[0] - 2*xt, bw,
+ @adisp_width + 2*xt, self.allocation.height - 2*bw
+ )
+ end
- def widget_get_yt
- self.style.ythickness
- end
+ def redraw_widget
+ return unless self.realized?
- def recalc_displays(width, height)
- old_cpl = @cpl
+ self.window.invalidate(nil, false)
+ end
- w, h = @scrollbar.size_request
- @xdisp_width = 1
- @adisp_width = 1
+ def widget_get_xt
+ self.style.xthickness
+ end
- total_width = width - 2 * self.border_width - 4 * widget_get_xt - w
- total_width -= 2 * widget_get_xt + 8 * @char_width if @show_offsets
-
- total_cpl = total_width / @char_width
- if total_cpl == 0 or total_width < 0
- @cpl = @lines = @vis_lines = 0
- return
- end
+ def widget_get_yt
+ self.style.ythickness
+ end
- @cpl = 0
- begin
- break if @cpl % @group_type == 0 and total_cpl < @group_type * 3
+ def recalc_displays(width, height)
+ old_cpl = @cpl
- @cpl += 1
- total_cpl -= 3
+ w, _h = @scrollbar.size_request
+ @xdisp_width = 1
+ @adisp_width = 1
- total_cpl -= 1 if @cpl % @group_type == 0
- end while total_cpl > 0
+ total_width = width - 2 * self.border_width - 4 * widget_get_xt - w
+ total_width -= 2 * widget_get_xt + 8 * @char_width if @show_offsets
- return if @cpl == 0
+ total_cpl = total_width / @char_width
+ if total_cpl == 0 or total_width < 0
+ @cpl = @lines = @vis_lines = 0
+ return
+ end
- if @data.empty?
- @lines = 1
- else
- @lines = @data.size / @cpl
- @lines += 1 if @data.size % @cpl != 0
- end
+ @cpl = 0
+ begin
+ break if @cpl % @group_type == 0 and total_cpl < @group_type * 3
- @vis_lines = (height - 2*self.border_width - 2*widget_get_yt).to_i / @char_height.to_i
- @adisp_width = @cpl * @char_width + 1
- xcpl = @cpl * 2 + (@cpl - 1) / @group_type
- @xdisp_width = xcpl * @char_width + 1
+ @cpl += 1
+ total_cpl -= 3
- @disp_buffer = ''
+ total_cpl -= 1 if @cpl % @group_type == 0
+ end while total_cpl > 0
- @adj.value = [@top_line * old_cpl / @cpl, @lines - @vis_lines].min
- @adj.value = [ 0, @adj.value ].max
- if @cursor_pos / @cpl < @adj.value or @cursor_pos / @cpl > @adj.value + @vis_lines - 1
- @adj.value = [ @cursor_pos / @cpl, @lines - @vis_lines ].min
- @adj.value = [ 0, @adj.value ].max
- end
+ return if @cpl == 0
- @adj.lower = 0
- @adj.upper = @lines
- @adj.step_increment = 1
- @adj.page_increment = @vis_lines - 1
- @adj.page_size = @vis_lines
+ if @data.empty?
+ @lines = 1
+ else
+ @lines = @data.size / @cpl
+ @lines += 1 if @data.size % @cpl != 0
+ end
- @adj.signal_emit 'changed'
- @adj.signal_emit 'value_changed'
- end
+ @vis_lines = (height - 2*self.border_width - 2*widget_get_yt).to_i / @char_height.to_i
+ @adisp_width = @cpl * @char_width + 1
+ xcpl = @cpl * 2 + (@cpl - 1) / @group_type
+ @xdisp_width = xcpl * @char_width + 1
- def get_max_char_width(metrics)
+ @disp_buffer = ''
- layout = self.create_pango_layout('')
- layout.set_font_description(@font_desc)
- char_widths = [ 0 ]
+ @adj.value = [@top_line * old_cpl / @cpl, @lines - @vis_lines].min
+ @adj.value = [ 0, @adj.value ].max
+ if @cursor_pos / @cpl < @adj.value or @cursor_pos / @cpl > @adj.value + @vis_lines - 1
+ @adj.value = [ @cursor_pos / @cpl, @lines - @vis_lines ].min
+ @adj.value = [ 0, @adj.value ].max
+ end
- (1..100).each do |i|
- logical_rect = Pango::Rectangle.new(0, 0, 0, 0)
- if is_displayable(i.chr)
- layout.set_text(i.chr)
- logical_rect = layout.pixel_extents[1]
+ @adj.lower = 0
+ @adj.upper = @lines
+ @adj.step_increment = 1
+ @adj.page_increment = @vis_lines - 1
+ @adj.page_size = @vis_lines
+
+ @adj.signal_emit 'changed'
+ @adj.signal_emit 'value_changed'
end
- char_widths << logical_rect.width
- end
- char_widths[48..122].max
- end
+ def get_max_char_width(metrics)
+ layout = self.create_pango_layout('')
+ layout.set_font_description(@font_desc)
+ char_widths = [ 0 ]
- def show_cursor
- unless @cursor_shown
- if @xdisp_gc and @adisp_gc and @xdisp.realized? and @adisp.realized?
- render_xc
- render_ac
+ (1..100).each do |i|
+ logical_rect = Pango::Rectangle.new(0, 0, 0, 0)
+ if is_displayable(i.chr)
+ layout.set_text(i.chr)
+ logical_rect = layout.pixel_extents[1]
+ end
+ char_widths << logical_rect.width
+ end
+
+ char_widths[48..122].max
end
- @cursor_shown = true
- end
- end
+ def show_cursor
+ unless @cursor_shown
+ if @xdisp_gc and @adisp_gc and @xdisp.realized? and @adisp.realized?
+ render_xc
+ render_ac
+ end
- def hide_cursor
- if @cursor_shown
- if @xdisp_gc and @adisp_gc and @xdisp.realized? and @adisp.realized?
- render_byte(@cursor_pos)
+ @cursor_shown = true
+ end
end
- @cursor_shown = false
- end
- end
+ def hide_cursor
+ if @cursor_shown
+ if @xdisp_gc and @adisp_gc and @xdisp.realized? and @adisp.realized?
+ render_byte(@cursor_pos)
+ end
- def show_offsets_widget
- @offsets = DrawingArea.new
- @offsets.modify_font @font_desc
- @olayout = @offsets.create_pango_layout('')
+ @cursor_shown = false
+ end
+ end
- @offsets.events = Gdk::Event::EXPOSURE_MASK
- @offsets.signal_connect 'expose_event' do |offsets, event|
- imin = (event.area.y / @char_height).to_i
- imax = ((event.area.y + event.area.height) / @char_height).to_i
- imax += 1 if (event.area.y + event.area.height).to_i % @char_height != 0
+ def show_offsets_widget
+ @offsets = DrawingArea.new
+ @offsets.modify_font @font_desc
+ @olayout = @offsets.create_pango_layout('')
- imax = [ imax, @vis_lines ].min
+ @offsets.events = Gdk::Event::EXPOSURE_MASK
+ @offsets.signal_connect 'expose_event' do |offsets, event|
+ imin = (event.area.y / @char_height).to_i
+ imax = ((event.area.y + event.area.height) / @char_height).to_i
+ imax += 1 if (event.area.y + event.area.height).to_i % @char_height != 0
- render_offsets(imin, imax)
- end
+ imax = [ imax, @vis_lines ].min
- put @offsets, 0, 0
- @offsets.show
- end
+ render_offsets(imin, imax)
+ end
- def hide_offsets_widget
- if @offsets
- self.remove(@offsets)
- @offsets = @offsets_gc = nil
- end
- end
+ put @offsets, 0, 0
+ @offsets.show
+ end
- def is_displayable(c)
- if RUBY_VERSION < '1.9'
- c = c[0]
- else
- c = c.ord
- end
+ def hide_offsets_widget
+ if @offsets
+ self.remove(@offsets)
+ @offsets = @offsets_gc = nil
+ end
+ end
- c >= 0x20 and c < 0x7f
- end
+ def is_displayable(c)
+ c = c.ord
+ c >= 0x20 and c < 0x7f
+ end
- def bytes_changed(s, e)
- start_line = s / @cpl - @top_line
- end_line = e / @cpl - @top_line
+ def bytes_changed(s, e)
+ start_line = s / @cpl - @top_line
+ end_line = e / @cpl - @top_line
- return if end_line < 0 or start_line > @vis_lines
+ return if end_line < 0 or start_line > @vis_lines
- start_line = [ 0, start_line ].max
+ start_line = [ 0, start_line ].max
- render_hex_lines(start_line, end_line)
- render_ascii_lines(start_line, end_line)
- render_offsets(start_line, end_line) if @show_offsets
- end
+ render_hex_lines(start_line, end_line)
+ render_ascii_lines(start_line, end_line)
+ render_offsets(start_line, end_line) if @show_offsets
+ end
- def render_hex_highlights(cursor_line)
- xcpl = @cpl * 2 + @cpl / @group_type
+ def render_hex_highlights(cursor_line)
+ xcpl = @cpl * 2 + @cpl / @group_type
- @highlights.each do |hl|
- next if (hl.start - hl.end).abs < hl.min_select
+ @highlights.each do |hl|
+ next if (hl.start - hl.end).abs < hl.min_select
- validate_highlight(hl)
+ validate_highlight(hl)
- s, e = [ hl.start, hl.end ].sort
- sl, el = hl.start_line, hl.end_line
+ s, e = [ hl.start, hl.end ].sort
+ sl, el = hl.start_line, hl.end_line
- hl.style.attach(@xdisp.window) if hl.style
- state = (@active_view == View::HEX) ? Gtk::STATE_SELECTED : Gtk::STATE_INSENSITIVE
+ hl.style.attach(@xdisp.window) if hl.style
+ state = (@active_view == View::HEX) ? Gtk::STATE_SELECTED : Gtk::STATE_INSENSITIVE
- if cursor_line == sl
- cursor_off = 2 * (s % @cpl) + (s % @cpl) / @group_type
- if cursor_line == el
- len = 2 * (e % @cpl + 1) + (e % @cpl) / @group_type
- else
- len = xcpl
- end
+ if cursor_line == sl
+ cursor_off = 2 * (s % @cpl) + (s % @cpl) / @group_type
+ if cursor_line == el
+ len = 2 * (e % @cpl + 1) + (e % @cpl) / @group_type
+ else
+ len = xcpl
+ end
- len -= cursor_off
- (hl.style || self.style).paint_flat_box(
- @xdisp.window,
- state, Gtk::SHADOW_NONE,
- nil, @xdisp, '',
- cursor_off * @char_width, cursor_line * @char_height,
- len * @char_width, @char_height
- ) if len > 0
+ len -= cursor_off
+ (hl.style || self.style).paint_flat_box(
+ @xdisp.window,
+ state, Gtk::SHADOW_NONE,
+ nil, @xdisp, '',
+ cursor_off * @char_width, cursor_line * @char_height,
+ len * @char_width, @char_height
+ ) if len > 0
- elsif cursor_line == el
- cursor_off = 2 * (e % @cpl + 1) + (e % @cpl) / @group_type
- (hl.style || self.style).paint_flat_box(
- @xdisp.window,
- state, Gtk::SHADOW_NONE,
- nil, @xdisp, '',
- 0, cursor_line * @char_height,
- cursor_off * @char_width, @char_height
- ) if cursor_off > 0
+ elsif cursor_line == el
+ cursor_off = 2 * (e % @cpl + 1) + (e % @cpl) / @group_type
+ (hl.style || self.style).paint_flat_box(
+ @xdisp.window,
+ state, Gtk::SHADOW_NONE,
+ nil, @xdisp, '',
+ 0, cursor_line * @char_height,
+ cursor_off * @char_width, @char_height
+ ) if cursor_off > 0
- elsif cursor_line > sl and cursor_line < el
- (hl.style || self.style).paint_flat_box(
- @xdisp.window,
- state, Gtk::SHADOW_NONE,
- nil, @xdisp, '',
- 0, cursor_line * @char_height,
- xcpl * @char_width, @char_height
- )
+ elsif cursor_line > sl and cursor_line < el
+ (hl.style || self.style).paint_flat_box(
+ @xdisp.window,
+ state, Gtk::SHADOW_NONE,
+ nil, @xdisp, '',
+ 0, cursor_line * @char_height,
+ xcpl * @char_width, @char_height
+ )
+ end
+
+ hl.style.attach(@adisp.window) if hl.style
+ end
end
-
- hl.style.attach(@adisp.window) if hl.style
- end
- end
- def render_hex_lines(imin, imax)
- return unless self.realized? and @cpl != 0
+ def render_hex_lines(imin, imax)
+ return unless self.realized? and @cpl != 0
- cursor_line = @cursor_pos / @cpl - @top_line
+ cursor_line = @cursor_pos / @cpl - @top_line
- @xdisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
- @xdisp.window.draw_rectangle(
- @xdisp_gc,
- true,
- 0,
- imin * @char_height,
- @xdisp.allocation.width,
- (imax - imin + 1) * @char_height
- )
+ @xdisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
+ @xdisp.window.draw_rectangle(
+ @xdisp_gc,
+ true,
+ 0,
+ imin * @char_height,
+ @xdisp.allocation.width,
+ (imax - imin + 1) * @char_height
+ )
- imax = [ imax, @vis_lines, @lines ].min
+ imax = [ imax, @vis_lines, @lines ].min
- @xdisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
+ @xdisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
- frm_len = format_xblock((@top_line+imin) * @cpl, [(@top_line+imax+1) * @cpl, @data.size].min)
+ frm_len = format_xblock((@top_line+imin) * @cpl, [(@top_line+imax+1) * @cpl, @data.size].min)
- tmp = nil
- xcpl = @cpl*2 + @cpl/@group_type
- (imin..imax).each do |i|
- return unless (tmp = frm_len - ((i - imin) * xcpl)) > 0
-
- render_hex_highlights(i)
- text = @disp_buffer[(i-imin) * xcpl, [xcpl, tmp].min]
- @xlayout.set_text(text)
- @xdisp.window.draw_layout(@xdisp_gc, 0, i * @char_height, @xlayout)
- end
+ tmp = nil
+ xcpl = @cpl*2 + @cpl/@group_type
+ (imin..imax).each do |i|
+ return unless (tmp = frm_len - ((i - imin) * xcpl)) > 0
- render_xc if cursor_line >= imin and cursor_line <= imax and @cursor_shown
- end
+ render_hex_highlights(i)
+ text = @disp_buffer[(i-imin) * xcpl, [xcpl, tmp].min]
+ @xlayout.set_text(text)
+ @xdisp.window.draw_layout(@xdisp_gc, 0, i * @char_height, @xlayout)
+ end
- def render_ascii_highlights(cursor_line)
- @highlights.each do |hl|
- next if (hl.start - hl.end).abs < hl.min_select
+ render_xc if cursor_line >= imin and cursor_line <= imax and @cursor_shown
+ end
- validate_highlight(hl)
+ def render_ascii_highlights(cursor_line)
+ @highlights.each do |hl|
+ next if (hl.start - hl.end).abs < hl.min_select
- s, e = [ hl.start, hl.end ].sort
- sl, el = hl.start_line, hl.end_line
+ validate_highlight(hl)
- hl.style.attach(@adisp.window) if hl.style
- state = (@active_view == View::ASCII) ? Gtk::STATE_SELECTED : Gtk::STATE_INSENSITIVE
+ s, e = [ hl.start, hl.end ].sort
+ sl, el = hl.start_line, hl.end_line
- if cursor_line == sl
- cursor_off = s % @cpl
- len =
- if cursor_line == el
- e - s + 1
- else
- @cpl - cursor_off
- end
+ hl.style.attach(@adisp.window) if hl.style
+ state = (@active_view == View::ASCII) ? Gtk::STATE_SELECTED : Gtk::STATE_INSENSITIVE
- (hl.style || self.style).paint_flat_box(
- @adisp.window,
- state, Gtk::SHADOW_NONE,
- nil, @adisp, '',
- cursor_off * @char_width, cursor_line * @char_height,
- len * @char_width, @char_height
- ) if len > 0
+ if cursor_line == sl
+ cursor_off = s % @cpl
+ len =
+ if cursor_line == el
+ e - s + 1
+ else
+ @cpl - cursor_off
+ end
- elsif cursor_line == el
- cursor_off = e % @cpl + 1
- (hl.style || self.style).paint_flat_box(
- @adisp.window,
- state, Gtk::SHADOW_NONE,
- nil, @adisp, '',
- 0, cursor_line * @char_height,
- cursor_off * @char_width, @char_height
- ) if cursor_off > 0
+ (hl.style || self.style).paint_flat_box(
+ @adisp.window,
+ state, Gtk::SHADOW_NONE,
+ nil, @adisp, '',
+ cursor_off * @char_width, cursor_line * @char_height,
+ len * @char_width, @char_height
+ ) if len > 0
- elsif cursor_line > sl and cursor_line < el
- (hl.style || self.style).paint_flat_box(
- @adisp.window,
- state, Gtk::SHADOW_NONE,
- nil, @adisp, '',
- 0, cursor_line * @char_height,
- @cpl * @char_width, @char_height
- )
+ elsif cursor_line == el
+ cursor_off = e % @cpl + 1
+ (hl.style || self.style).paint_flat_box(
+ @adisp.window,
+ state, Gtk::SHADOW_NONE,
+ nil, @adisp, '',
+ 0, cursor_line * @char_height,
+ cursor_off * @char_width, @char_height
+ ) if cursor_off > 0
+
+ elsif cursor_line > sl and cursor_line < el
+ (hl.style || self.style).paint_flat_box(
+ @adisp.window,
+ state, Gtk::SHADOW_NONE,
+ nil, @adisp, '',
+ 0, cursor_line * @char_height,
+ @cpl * @char_width, @char_height
+ )
+ end
+
+ hl.style.attach(@adisp.window) if hl.style
+ end
end
- hl.style.attach(@adisp.window) if hl.style
- end
- end
+ def render_ascii_lines(imin, imax)
+ return unless self.realized? and @cpl != 0
- def render_ascii_lines(imin, imax)
- return unless self.realized? and @cpl != 0
+ cursor_line = @cursor_pos / @cpl - @top_line
- cursor_line = @cursor_pos / @cpl - @top_line
+ @adisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
+ @adisp.window.draw_rectangle(
+ @adisp_gc,
+ true,
+ 0,
+ imin * @char_height,
+ @adisp.allocation.width,
+ (imax - imin + 1) * @char_height
+ )
- @adisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
- @adisp.window.draw_rectangle(
- @adisp_gc,
- true,
- 0,
- imin * @char_height,
- @adisp.allocation.width,
- (imax - imin + 1) * @char_height
- )
-
- imax = [ imax, @vis_lines, @lines ].min
+ imax = [ imax, @vis_lines, @lines ].min
- @adisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
-
- frm_len = format_ablock((@top_line+imin) * @cpl, [(@top_line+imax+1) * @cpl, @data.size].min)
+ @adisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
- tmp = nil
- (imin..imax).each do |i|
- return unless (tmp = frm_len - ((i - imin) * @cpl)) > 0
-
- render_ascii_highlights(i)
- text = @disp_buffer[(i-imin) * @cpl, [@cpl, tmp].min]
- @alayout.set_text(text)
- @adisp.window.draw_layout(@adisp_gc, 0, i * @char_height, @alayout)
- end
+ frm_len = format_ablock((@top_line+imin) * @cpl, [(@top_line+imax+1) * @cpl, @data.size].min)
- render_ac if cursor_line >= imin and cursor_line <= imax and @cursor_shown
- end
+ tmp = nil
+ (imin..imax).each do |i|
+ return unless (tmp = frm_len - ((i - imin) * @cpl)) > 0
- def render_offsets(imin, imax)
- return unless self.realized?
+ render_ascii_highlights(i)
+ text = @disp_buffer[(i-imin) * @cpl, [@cpl, tmp].min]
+ @alayout.set_text(text)
+ @adisp.window.draw_layout(@adisp_gc, 0, i * @char_height, @alayout)
+ end
- unless @offsets_gc
- @offsets_gc = Gdk::GC.new(@offsets.window)
- @offsets_gc.set_exposures(true)
- end
+ render_ac if cursor_line >= imin and cursor_line <= imax and @cursor_shown
+ end
- @offsets_gc.set_foreground(self.style.base(Gtk::STATE_INSENSITIVE))
- @offsets.window.draw_rectangle(
- @offsets_gc,
- true,
- 0, imin * @char_height,
- @offsets.allocation.width, (imax - imin + 1) * @char_height
- )
+ def render_offsets(imin, imax)
+ return unless self.realized?
- imax = [ imax, @vis_lines, @lines - @top_line - 1 ].min
- @offsets_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
+ unless @offsets_gc
+ @offsets_gc = Gdk::GC.new(@offsets.window)
+ @offsets_gc.set_exposures(true)
+ end
- (imin..imax).each do |i|
- text = "%08x" % ((@top_line + i) * @cpl + @starting_offset)
- @olayout.set_text(text)
- @offsets.window.draw_layout(@offsets_gc, 0, i * @char_height, @olayout)
- end
- end
+ @offsets_gc.set_foreground(self.style.base(Gtk::STATE_INSENSITIVE))
+ @offsets.window.draw_rectangle(
+ @offsets_gc,
+ true,
+ 0, imin * @char_height,
+ @offsets.allocation.width, (imax - imin + 1) * @char_height
+ )
- def render_byte(pos)
- return unless @xdisp_gc and @adisp_gc and @xdisp.realized? and @adisp.realized?
-
- return unless (coords = get_xcoords(pos))
- cx, cy = coords
- c = format_xbyte(pos)
-
- @xdisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
- @xdisp.window.draw_rectangle(
- @xdisp_gc,
- true,
- cx, cy,
- 2 * @char_width, @char_height
- )
+ imax = [ imax, @vis_lines, @lines - @top_line - 1 ].min
+ @offsets_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
- if pos < @data.size
- @xdisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
- @xlayout.set_text(c)
- @xdisp.window.draw_layout(@xdisp_gc, cx, cy, @xlayout)
- end
+ (imin..imax).each do |i|
+ text = "%08x" % ((@top_line + i) * @cpl + @starting_offset)
+ @olayout.set_text(text)
+ @offsets.window.draw_layout(@offsets_gc, 0, i * @char_height, @olayout)
+ end
+ end
- return unless (coords = get_acoords(pos))
- cx, cy = coords
+ def render_byte(pos)
+ return unless @xdisp_gc and @adisp_gc and @xdisp.realized? and @adisp.realized?
- @adisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
- @adisp.window.draw_rectangle(
- @adisp_gc,
- true,
- cx, cy,
- @char_width, @char_height
- )
+ return unless (coords = get_xcoords(pos))
+ cx, cy = coords
+ c = format_xbyte(pos)
- if pos < @data.size
- @adisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
- c = get_byte(pos)
- c = '.' unless is_displayable(c)
+ @xdisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
+ @xdisp.window.draw_rectangle(
+ @xdisp_gc,
+ true,
+ cx, cy,
+ 2 * @char_width, @char_height
+ )
- @alayout.set_text(c)
- @adisp.window.draw_layout(@adisp_gc, cx, cy, @alayout)
- end
- end
+ if pos < @data.size
+ @xdisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
+ @xlayout.set_text(c)
+ @xdisp.window.draw_layout(@xdisp_gc, cx, cy, @xlayout)
+ end
- def render_xc
- return unless @xdisp.realized?
+ return unless (coords = get_acoords(pos))
+ cx, cy = coords
- if coords = get_xcoords(@cursor_pos)
- cx, cy = coords
+ @adisp_gc.set_foreground(self.style.base(Gtk::STATE_NORMAL))
+ @adisp.window.draw_rectangle(
+ @adisp_gc,
+ true,
+ cx, cy,
+ @char_width, @char_height
+ )
- c = format_xbyte(@cursor_pos)
- if @lower_nibble
- cx += @char_width
- c = c[1,1]
- else
- c = c[0,1]
+ if pos < @data.size
+ @adisp_gc.set_foreground(self.style.text(Gtk::STATE_NORMAL))
+ c = get_byte(pos)
+ c = '.' unless is_displayable(c)
+
+ @alayout.set_text(c)
+ @adisp.window.draw_layout(@adisp_gc, cx, cy, @alayout)
+ end
end
- @xdisp_gc.set_foreground(self.style.base(Gtk::STATE_ACTIVE))
- @xdisp.window.draw_rectangle(
- @xdisp_gc,
- (@active_view == View::HEX),
- cx, cy,
- @char_width,
- @char_height - 1
- )
- @xdisp_gc.set_foreground(self.style.text(Gtk::STATE_ACTIVE))
- @xlayout.set_text(c)
- @xdisp.window.draw_layout(@xdisp_gc, cx, cy, @xlayout)
- end
- end
+ def render_xc
+ return unless @xdisp.realized?
- def render_ac
- return unless @adisp.realized?
+ if coords = get_xcoords(@cursor_pos)
+ cx, cy = coords
- if coords = get_acoords(@cursor_pos)
- cx, cy = coords
+ c = format_xbyte(@cursor_pos)
+ if @lower_nibble
+ cx += @char_width
+ c = c[1,1]
+ else
+ c = c[0,1]
+ end
- c = get_byte(@cursor_pos)
- c = '.' unless is_displayable(c)
-
- @adisp_gc.set_foreground(self.style.base(Gtk::STATE_ACTIVE))
- @adisp.window.draw_rectangle(
- @adisp_gc,
- (@active_view == View::ASCII),
- cx, cy,
- @char_width,
- @char_height - 1
- )
- @adisp_gc.set_foreground(self.style.text(Gtk::STATE_ACTIVE))
- @alayout.set_text(c)
- @adisp.window.draw_layout(@adisp_gc, cx, cy, @alayout)
- end
- end
+ @xdisp_gc.set_foreground(self.style.base(Gtk::STATE_ACTIVE))
+ @xdisp.window.draw_rectangle(
+ @xdisp_gc,
+ (@active_view == View::HEX),
+ cx, cy,
+ @char_width,
+ @char_height - 1
+ )
+ @xdisp_gc.set_foreground(self.style.text(Gtk::STATE_ACTIVE))
+ @xlayout.set_text(c)
+ @xdisp.window.draw_layout(@xdisp_gc, cx, cy, @xlayout)
+ end
+ end
- def get_xcoords(pos)
- return nil if @cpl == 0
+ def render_ac
+ return unless @adisp.realized?
- cy = pos / @cpl - @top_line
- return nil if cy < 0
+ if coords = get_acoords(@cursor_pos)
+ cx, cy = coords
- cx = 2 * (pos % @cpl)
- spaces = (pos % @cpl) / @group_type
+ c = get_byte(@cursor_pos)
+ c = '.' unless is_displayable(c)
- cx *= @char_width
- cy *= @char_height
- spaces *= @char_width
+ @adisp_gc.set_foreground(self.style.base(Gtk::STATE_ACTIVE))
+ @adisp.window.draw_rectangle(
+ @adisp_gc,
+ (@active_view == View::ASCII),
+ cx, cy,
+ @char_width,
+ @char_height - 1
+ )
+ @adisp_gc.set_foreground(self.style.text(Gtk::STATE_ACTIVE))
+ @alayout.set_text(c)
+ @adisp.window.draw_layout(@adisp_gc, cx, cy, @alayout)
+ end
+ end
- [cx + spaces, cy]
- end
+ def get_xcoords(pos)
+ return nil if @cpl == 0
- def get_acoords(pos)
- return nil if @cpl == 0
+ cy = pos / @cpl - @top_line
+ return nil if cy < 0
- cy = pos / @cpl - @top_line
- return nil if cy < 0
+ cx = 2 * (pos % @cpl)
+ spaces = (pos % @cpl) / @group_type
- cy *= @char_height
- cx = @char_width * (pos % @cpl)
+ cx *= @char_width
+ cy *= @char_height
+ spaces *= @char_width
- [cx, cy]
- end
+ [cx + spaces, cy]
+ end
- def format_xblock(s, e)
- @disp_buffer = ''
+ def get_acoords(pos)
+ return nil if @cpl == 0
- (s+1..e).each do |i|
- @disp_buffer << get_byte(i - 1).unpack('H2')[0]
- @disp_buffer << ' ' if i % @group_type == 0
- end
+ cy = pos / @cpl - @top_line
+ return nil if cy < 0
- @disp_buffer.size
- end
+ cy *= @char_height
+ cx = @char_width * (pos % @cpl)
- def format_ablock(s, e)
- @disp_buffer = ''
+ [cx, cy]
+ end
- (s..e-1).each do |i|
- c = get_byte(i)
- c = '.' unless is_displayable(c)
- @disp_buffer << c
- end
+ def format_xblock(s, e)
+ @disp_buffer = ''
- @disp_buffer.size
- end
+ (s+1..e).each do |i|
+ @disp_buffer << get_byte(i - 1).unpack('H2')[0]
+ @disp_buffer << ' ' if i % @group_type == 0
+ end
- def get_byte(offset)
- if offset >= 0 and offset < @data.size
- @data[offset, 1]
- else
- 0.chr
- end
- end
+ @disp_buffer.size
+ end
- def format_xbyte(pos)
- get_byte(pos).unpack('H2')[0]
- end
- end
+ def format_ablock(s, e)
+ @disp_buffer = ''
+ (s..e-1).each do |i|
+ c = get_byte(i)
+ c = '.' unless is_displayable(c)
+ @disp_buffer << c
+ end
+
+ @disp_buffer.size
+ end
+
+ def get_byte(offset)
+ if offset >= 0 and offset < @data.size
+ @data[offset, 1]
+ else
+ 0.chr
+ end
+ end
+
+ def format_xbyte(pos)
+ get_byte(pos).unpack('H2')[0]
+ end
+ end
end
__END__
hexedit = Gtk::HexEditor.new(File.read '/bin/cat')
hexedit.show_offsets(true)