class Metasm::Gui::ListWindow::LBoxWidget

Public Instance Methods

click(x, y) click to toggle source
# File metasm/gui/win32.rb, line 2989
def click(x, y)
        if y >= @btny and y < @btny+@btnheight
                # TODO column resize
                @btndown[xtobtn(x)] = true
                redraw
        elsif y >= @btny+@btnheight
                y += @sbv % @font_height
                cy = @linehead + (y - @btny - @btnheight)/@font_height
                if cy < @list.length
                        @linesel = cy
                        redraw
                        Gui.main_iter
                        protect { @action.call(@list[@linesel]) }
                end
        end
end
destroy() click to toggle source
# File metasm/gui/win32.rb, line 3048
def destroy
        @parent.destroy
end
doubleclick(x, y) click to toggle source
# File metasm/gui/win32.rb, line 3006
def doubleclick(x, y)
        if y >= @btny+@btnheight
                return click(x, y) if @noclose_dblclick
                y += @sbv % @font_height
                cy = @linehead + (y - @btny - @btnheight)/@font_height
                if cy < @list.length
                        destroy
                        Gui.main_iter
                        protect { @action.call(@list[@linesel]) }
                end
        end
end
hscroll(val) click to toggle source
# File metasm/gui/win32.rb, line 2964
def hscroll(val)
        Win32Gui.setscrollpos(@hwnd, Win32Gui::SB_HORZ, val, Win32Gui::TRUE)
        @sbh = Win32Gui.getscrollpos(@hwnd, Win32Gui::SB_HORZ)        # clipping, etc
        redraw
end
initial_size() click to toggle source
# File metasm/gui/win32.rb, line 2798
def initial_size
        @colw = @colwmax.map { |w| (w+1) * @font_width }
        allw = @colw.inject(0) { |a, i| a+i }
        [[allw+@font_width, 80*@font_width].min, [@list.length+2, 30].min * @font_height+2]
end
initialize_widget(list, opts={}, &b) click to toggle source
# File metasm/gui/win32.rb, line 2768
def initialize_widget(list, opts={}, &b)
        ccnt = list.first.length
        # store a true/false per column saying if the original data was integers (for col sorting)
        @list_ints = list[1..-1].transpose.map { |col| col.all? { |e| e.kind_of? Integer } } rescue []
        @list = list.map { |l|
                l += ['']*(ccnt - l.length) if l.length < ccnt
                l = l[0, ccnt] if l.length > ccnt
                l.map { |w| w.to_s }
        }
        # length of the longest element of the column
        @colwmax = @list.transpose.map { |l| l.map { |w| w.length }.max }
        @titles = @list.shift

        @action = b
        @linehead = 0
        @color_callback = opts[:color_callback]       # lambda { |ary_entries_text| [color_font, color_bg] }
        @noclose_dblclick = opts[:noclose_dblclick]
        # index of the currently selected row
        @linesel = nil
        # ary indicating whether a title label is being clicked
        @btndown = []
        @btnheight = @font_height * 4/3
        @sbh = 0      # position of the hz scrollbar
        @sbv = 0

        @default_color_association = { :background => :winbg, :label => :black,
                :text => :black, :textbg => :white, :btnc1 => :white, :btnc2 => :grey,
                :textsel => :white, :textselbg => :darkblue }
end
keypress(key) click to toggle source
# File metasm/gui/win32.rb, line 2886
def keypress(key)
        case key
        when :up
                if not @linesel
                        @linesel = @linehead
                elsif @linesel > 0
                        @linesel -= 1
                        vscroll(@linesel*@font_height) if @linesel < @linehead
                end
                redraw
        when :down
                if not @linesel
                        @linesel = @linehead
                elsif @linesel < @list.length-1
                        @linesel += 1
                        vscroll((@linesel-(@lineshown-1))*@font_height) if @linehead < @linesel-(@lineshown-1)
                end
                redraw
        when :pgup
                off = [@lineshown, [@lineshown/2, 5].max].min
                if not @linesel
                        @linesel = @linehead
                elsif @linesel != @linehead
                        @linesel = [@linehead, @linesel-off].max
                else
                        @linesel = [0, @linehead-off].max
                        vscroll(@linesel*@font_height)
                end
                redraw
        when :pgdown
                n = @lineshown-1
                off = [@lineshown, [@lineshown/2, 5].max].min
                if not @linesel
                        @linesel = @linehead+n
                elsif @linesel != @linehead+n
                        @linesel = [@linehead+n, @linesel+off].min
                else
                        vscroll((@linehead+off)*@font_height)
                        @linesel = [@linehead+n, @list.length-1].min
                end
                redraw
        when :home
                @linesel = 0
                vscroll(0)
                redraw
        when :end
                @linesel = @list.length-1
                vscroll(@list.length*@font_height)
                redraw
        when :enter
                if @linesel and @list[@linesel]
                        protect { @action.call(@list[@linesel]) }
                end
        when :esc
                if not @btndown.compact.empty?
                        @btndown = []
                        redraw
                else
                        destroy
                end
        else return false
        end
        true
end
mouse_wheel(dir, x, y) click to toggle source
# File metasm/gui/win32.rb, line 2951
def mouse_wheel(dir, x, y)
        case dir
        when :up
                off = [@lineshown, [@lineshown/2, 5].max].min
                vscroll((@linehead-off)*@font_height)
                redraw
        when :down
                off = [@lineshown, [@lineshown/2, 5].max].min
                vscroll((@linehead+off)*@font_height)
                redraw
        end
end
mousemove(x, y) click to toggle source
# File metasm/gui/win32.rb, line 3019
def mousemove(x, y)
        if @btndown.compact.first
                @btndown = []
                @btndown[xtobtn(x)] = true
                redraw
        end
end
mouserelease(x, y) click to toggle source
# File metasm/gui/win32.rb, line 3027
def mouserelease(x, y)
        if @btndown.compact.first
                @btndown = []
                col = xtobtn(x)
                cursel = @list[@linesel] if @linesel
                if @list_ints[col]
                        nlist = @list.sort_by { |a| [a[col].to_i, a] }
                else
                        nlist = @list.sort_by { |a| [a[col], a] }
                end
                nlist.reverse! if nlist == @list
                @list = nlist
                @linehead = 0
                if cursel
                        @linesel = @list.index(cursel)
                        @linehead = @linesel - (@lineshown-1) if @linehead < @linesel-(@lineshown-1)
                end
                redraw
        end
end
paint() click to toggle source
# File metasm/gui/win32.rb, line 2833
def paint
        @btnx = []
        @btny = 0
        if @btnheight != @font_height * 4/3
                # fix vscrollbar height on w7
                @btnheight = @font_height * 4/3
                resized(width, height)
        end
        x = 0
        @colw.each { |w|
                @btnx << x
                x += w
        }

        x -= @sbh
        y = @btnheight
        @linehead = @sbv / @font_height
        y -= @sbv % @font_height
        tl = (@linesel || -1) - @linehead
        @lineshown = @list[@linehead, (height-y)/@font_height+1].to_a.length
        @list[@linehead, @lineshown].to_a.each { |l|
                x = @btnx.first - @sbh
                ct, cb = @color_callback[l] if @color_callback
                ct ||= :text
                cb ||= :textbg
                ct, cb = :textsel, :textselbg if tl == 0
                tl -= 1
                draw_rectangle_color(cb, x, y, width-2*x, @font_height)
                l.zip(@colw).each { |t, w|
                        draw_string_color(ct, x+@font_width/2, y, t[0, w/@font_width-1])
                        x += w
                }
                y += @font_height
        }

        @titles.zip(@colw, @btnx, @btndown).each { |t, w, bx, d|
                x = bx - @sbh
                y = @btny
                h = @btnheight-1
                c1 = d ? :btnc2 : :btnc1
                c2 = d ? :btnc1 : :btnc2
                draw_rectangle_color(:background, x, y, w-1, h)
                draw_line_color(c1, x, y, x, y+h)
                draw_line_color(c1, x, y, x+w-1, y)
                draw_line_color(c2, x+w-1, y+h, x, y+h)
                draw_line_color(c2, x+w-1, y+h, x+w-1, y)

                cw = w/@font_width-1
                xo = [(cw-t.length) * @font_width/2, 0].max  # center titles
                draw_string_color(:label, x+@font_width/2+xo, y+@font_height/6, t[0, cw])
        }
end
resized(w, h) click to toggle source
# File metasm/gui/win32.rb, line 2804
def resized(w, h)
        # scrollbar stuff
        fullw = @colwmax.inject(0) { |a, i| a+i+1 } * @font_width
        @sbh = fullw-w if @sbh > fullw-w
        @sbh = 0 if @sbh < 0
        sif = Win32Gui.alloc_c_struct('SCROLLINFO',
                :cbsize => :size, :fmask => Win32Gui::SIF_ALL,
                :nmin => 0, :nmax => fullw-1, :npage => w, :npos => @sbh)
        Win32Gui.setscrollinfo(@hwnd, Win32Gui::SB_HORZ, sif, Win32Gui::TRUE)

        fullh = @list.length * @font_height + @btnheight
        @sbv = fullh-h if @sbv > fullh-h
        @sbv = 0 if @sbv < 0
        sif = Win32Gui.alloc_c_struct('SCROLLINFO',
                :cbsize => :size, :fmask => Win32Gui::SIF_ALL,
                :nmin => 0, :nmax => fullh-1, :npage => h, :npos => @sbv)
        Win32Gui.setscrollinfo(@hwnd, Win32Gui::SB_VERT, sif, Win32Gui::TRUE)

        # resize columns to fill available hz space
        if w > fullw
                mi = (w-fullw) / @colw.length
                mm = (w-fullw) % @colw.length
                @colw.length.times { |i|
                        @colw[i] = (@colwmax[i]+1)*@font_width + mi + (i < mm ? 1 : 0)
                }
                redraw
        end
end
vscroll(val) click to toggle source
# File metasm/gui/win32.rb, line 2970
def vscroll(val)
        Win32Gui.setscrollpos(@hwnd, Win32Gui::SB_VERT, val, Win32Gui::TRUE)
        @sbv = Win32Gui.getscrollpos(@hwnd, Win32Gui::SB_VERT)
        redraw
end
xtobtn(x) click to toggle source
# File metasm/gui/win32.rb, line 2976
def xtobtn(x)
        x += @sbh
        if x < @btnx.first
                return 0
        elsif x >= @btnx.last + @colw.last
                return @btnx.length-1
        else
                @btnx.zip(@colw).each_with_index { |(bx, bw), i|
                        return i if x >= bx and x < bx+bw
                }
        end
end