rbcurse 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1570 -0
- data/History.txt +6 -0
- data/Manifest.txt +54 -0
- data/README.txt +304 -0
- data/Rakefile +28 -0
- data/examples/qdfilechooser.rb +68 -0
- data/examples/rfe.rb +853 -0
- data/examples/rfe_renderer.rb +69 -0
- data/examples/test1.rb +242 -0
- data/examples/test2.rb +498 -0
- data/examples/testcombo.rb +95 -0
- data/examples/testkeypress.rb +61 -0
- data/examples/testmenu.rb +105 -0
- data/examples/testtable.rb +266 -0
- data/examples/testtabp.rb +106 -0
- data/examples/testtodo.rb +532 -0
- data/examples/viewtodo.rb +512 -0
- data/lib/rbcurse/action.rb +31 -0
- data/lib/rbcurse/applicationheader.rb +57 -0
- data/lib/rbcurse/celleditor.rb +120 -0
- data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
- data/lib/rbcurse/colormap.rb +133 -0
- data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
- data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
- data/lib/rbcurse/keylabelprinter.rb +143 -0
- data/lib/rbcurse/listcellrenderer.rb +99 -0
- data/lib/rbcurse/listkeys.rb +33 -0
- data/lib/rbcurse/listscrollable.rb +216 -0
- data/lib/rbcurse/listselectable.rb +67 -0
- data/lib/rbcurse/mapper.rb +108 -0
- data/lib/rbcurse/orderedhash.rb +77 -0
- data/lib/rbcurse/rcombo.rb +243 -0
- data/lib/rbcurse/rdialogs.rb +183 -0
- data/lib/rbcurse/rform.rb +845 -0
- data/lib/rbcurse/rinputdataevent.rb +36 -0
- data/lib/rbcurse/rlistbox.rb +804 -0
- data/lib/rbcurse/rmenu.rb +666 -0
- data/lib/rbcurse/rmessagebox.rb +325 -0
- data/lib/rbcurse/rpopupmenu.rb +754 -0
- data/lib/rbcurse/rtabbedpane.rb +259 -0
- data/lib/rbcurse/rtable.rb +1296 -0
- data/lib/rbcurse/rtextarea.rb +673 -0
- data/lib/rbcurse/rtextview.rb +335 -0
- data/lib/rbcurse/rwidget.rb +1731 -0
- data/lib/rbcurse/scrollable.rb +301 -0
- data/lib/rbcurse/selectable.rb +94 -0
- data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
- data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
- data/lib/rbcurse.rb +7 -0
- data/lib/ver/keyboard.rb +150 -0
- data/lib/ver/keyboard2.rb +170 -0
- data/lib/ver/ncurses.rb +102 -0
- data/lib/ver/window.rb +369 -0
- data/test/test_rbcurse.rb +0 -0
- metadata +118 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ncurses'
|
3
|
+
require 'logger'
|
4
|
+
#require 'lib/rbcurse/rwidget'
|
5
|
+
|
6
|
+
|
7
|
+
##
|
8
|
+
# This file gives us a mean of using a component as an editor in a list or later table.
|
9
|
+
# The component is created once and used with each row.
|
10
|
+
# It does not really have a form associated with it, although we do set a form
|
11
|
+
# so it can display itself. Otherwise it is not added to the forms widget list, so the
|
12
|
+
# form has no idea tha this widget exists.
|
13
|
+
#
|
14
|
+
# Tested with Field, combo and checkbox
|
15
|
+
# TODO test and integrate with tables.
|
16
|
+
#
|
17
|
+
module RubyCurses
|
18
|
+
class CellEditor
|
19
|
+
include ConfigSetup
|
20
|
+
include RubyCurses::Utils
|
21
|
+
|
22
|
+
def initialize component, config={}, &block
|
23
|
+
@component = component
|
24
|
+
s = @component.class.to_s.downcase()
|
25
|
+
s.slice!("rubycurses::")
|
26
|
+
@_class = s.to_sym
|
27
|
+
#$log.debug " CELL EIDOTR got #{@_class}"
|
28
|
+
config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
|
29
|
+
instance_eval &block if block_given?
|
30
|
+
end
|
31
|
+
def getvalue
|
32
|
+
case @_class
|
33
|
+
when :field
|
34
|
+
return field_getvalue
|
35
|
+
when :checkbox
|
36
|
+
return checkbox_getvalue
|
37
|
+
when :combobox
|
38
|
+
return combobox_getvalue
|
39
|
+
else
|
40
|
+
raise "Unknown class #{@_class} in CellEditor getv"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# maybe this should check valid (on_leave) and throw exception
|
44
|
+
def field_getvalue
|
45
|
+
#@component.on_leave # throws exception! Added 2009-01-17 00:47
|
46
|
+
@component.init_vars # 2009-01-18 01:13 should not carry over to next row curpos and pcol
|
47
|
+
return @component.getvalue
|
48
|
+
end
|
49
|
+
def checkbox_getvalue
|
50
|
+
@component.getvalue
|
51
|
+
end
|
52
|
+
def combobox_getvalue
|
53
|
+
#@component.on_leave # added 2009-01-19 12:12
|
54
|
+
@component.getvalue
|
55
|
+
#@component.selected_item
|
56
|
+
end
|
57
|
+
def setvalue value
|
58
|
+
case @_class
|
59
|
+
when :field
|
60
|
+
@component.set_buffer value
|
61
|
+
when :checkbox
|
62
|
+
@component.checked value
|
63
|
+
when :combobox
|
64
|
+
@component.set_buffer value
|
65
|
+
#index = @component.list.index value
|
66
|
+
#@component.current_index = index
|
67
|
+
else
|
68
|
+
raise "Unknown class #{@_class} in CellEditor setv"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
def component
|
72
|
+
@component
|
73
|
+
end
|
74
|
+
# should be called from on_leave_cell of table, but is beng called from editing_stopped FIXME
|
75
|
+
def on_leave row, col
|
76
|
+
f = @component
|
77
|
+
f.on_leave
|
78
|
+
if f.respond_to? :editable and f.modified?
|
79
|
+
$log.debug " Table about to fire CHANGED for #{f} "
|
80
|
+
f.fire_handler(:CHANGED, f)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
def prepare_editor parent, row, col, value
|
84
|
+
#value = value.dup if value.respond_to? :dup
|
85
|
+
value = value.dup rescue value
|
86
|
+
setvalue value #.dup
|
87
|
+
widget = component()
|
88
|
+
widget.row = row
|
89
|
+
widget.col = col
|
90
|
+
# unfortunately 2009-01-11 19:47 combo boxes editable allows changing value
|
91
|
+
# FIXME so combo's can be editable, but no new value added
|
92
|
+
if @_class == :combobox
|
93
|
+
widget.editable = false if widget.respond_to? :editable # chb's don't ???
|
94
|
+
else
|
95
|
+
widget.editable = true if widget.respond_to? :editable # chb's don't ???
|
96
|
+
end
|
97
|
+
widget.focusable = true
|
98
|
+
widget.visible = true
|
99
|
+
widget.form = parent.form
|
100
|
+
#$log.debug " prepare editor value #{widget.display_length} displlen #{widget.maxlen}"
|
101
|
+
#widget.display_length = widget.display_length -1
|
102
|
+
widget.bgcolor = 'yellow'
|
103
|
+
widget.color = 'black'
|
104
|
+
widget.on_enter
|
105
|
+
#widget.attr = Ncurses::A_REVERSE | Ncurses::A_BOLD
|
106
|
+
#$log.debug " prepare editor value #{value} : fr:#{row}, fc:#{col}"
|
107
|
+
end
|
108
|
+
#This may not really be necessary since we paint the cell editor only if editing is on
|
109
|
+
def cancel_editor
|
110
|
+
widget = component()
|
111
|
+
# NOOO THIS IS CALLED BY CANCEL AND STOP
|
112
|
+
# somehow we need to ensure that if on_leave fails you can't get out. Here its a bit late
|
113
|
+
# i think FIXME TODO
|
114
|
+
#widget.on_leave # call so any triggers or validations can fire
|
115
|
+
widget.focusable = false
|
116
|
+
widget.visible = false
|
117
|
+
widget.attr = Ncurses::A_REVERSE
|
118
|
+
end
|
119
|
+
end # class
|
120
|
+
end # module
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ncurses'
|
3
|
+
require 'logger'
|
4
|
+
require 'rbcurse/listcellrenderer'
|
5
|
+
module RubyCurses
|
6
|
+
|
7
|
+
##
|
8
|
+
# This is a basic list cell renderer that will render the to_s value of anything.
|
9
|
+
# Using alignment one can use for numbers too.
|
10
|
+
# However, for booleans it will print true and false. If editing, you may want checkboxes
|
11
|
+
class CheckBoxCellRenderer < ListCellRenderer
|
12
|
+
include ConfigSetup
|
13
|
+
include RubyCurses::Utils
|
14
|
+
dsl_accessor :justify # :right, :left, :center # added 2008-12-22 19:02
|
15
|
+
dsl_accessor :display_length # please give this to ensure the we only print this much
|
16
|
+
dsl_accessor :height # if you want a multiline label.
|
17
|
+
dsl_accessor :text # text of label
|
18
|
+
dsl_accessor :value # text of label
|
19
|
+
dsl_accessor :color, :bgcolor
|
20
|
+
dsl_accessor :row, :col
|
21
|
+
dsl_accessor :parent #usuall the table to get colors and other default info
|
22
|
+
dsl_accessor :surround_chars
|
23
|
+
|
24
|
+
def initialize boolean=nil, config={}, &block
|
25
|
+
@value = boolean
|
26
|
+
@text = "" # what if someone wants to show a label later. ??? XXX
|
27
|
+
@editable = false
|
28
|
+
@focusable = false
|
29
|
+
config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
|
30
|
+
instance_eval &block if block_given?
|
31
|
+
init_vars
|
32
|
+
end
|
33
|
+
def init_vars
|
34
|
+
@justify ||= :left
|
35
|
+
@display_length ||= 5
|
36
|
+
@surround_chars = ['[',']']
|
37
|
+
end
|
38
|
+
def getvalue
|
39
|
+
@value
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
#
|
44
|
+
def repaint graphic, r=@row,c=@col, row_index=-1,value=@value, focussed=false, selected=false
|
45
|
+
#$log.debug "label :#{@text}, #{value}, #{r}, #{c} col= #{@color}, #{@bgcolor} acolor= #{acolor} j:#{@justify} dlL: #{@display_length} "
|
46
|
+
|
47
|
+
prepare_default_colors focussed, selected
|
48
|
+
|
49
|
+
buttontext = value ? "X" : " "
|
50
|
+
# HOW TO DO THE TEXT ??? XXX
|
51
|
+
# the space in dtext next line is a cheat, to clear off the space that the
|
52
|
+
# editor is leaving.
|
53
|
+
dtext = " " #@display_length.nil? ? @text : "%-*s" % [@display_length, @text]
|
54
|
+
if @align_right
|
55
|
+
#@text_offset = 0
|
56
|
+
#@col_offset = dtext.length + @surround_chars[0].length + 1
|
57
|
+
str = "#{dtext} " + @surround_chars[0] + buttontext + @surround_chars[1]
|
58
|
+
else
|
59
|
+
pretext = @surround_chars[0] + buttontext + @surround_chars[1]
|
60
|
+
#@text_offset = pretext.length + 1
|
61
|
+
#@col_offset = @surround_chars[0].length
|
62
|
+
#@surround_chars[0] + buttontext + @surround_chars[1] + " #{@text}"
|
63
|
+
str = pretext + " #{dtext}"
|
64
|
+
end
|
65
|
+
graphic.printstring r, c, str, @color_pair,@attr
|
66
|
+
end
|
67
|
+
# ADD HERE
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ver/ncurses'
|
3
|
+
module ColorMap
|
4
|
+
## private
|
5
|
+
# returns a color constant for a human color string
|
6
|
+
def ColorMap.get_color_const colorstring
|
7
|
+
Ncurses.const_get "COLOR_#{colorstring.upcase}"
|
8
|
+
end
|
9
|
+
## private
|
10
|
+
# creates a new color pair, puts in color map and returns color_pair
|
11
|
+
# number
|
12
|
+
def ColorMap.install_color fgc, bgc
|
13
|
+
# $log.debug " install_color found #{fgc} #{@bgc} "
|
14
|
+
@color_id += 1
|
15
|
+
fg = ColorMap.get_color_const fgc
|
16
|
+
bg = ColorMap.get_color_const bgc
|
17
|
+
Ncurses.init_pair(@color_id, fg, bg);
|
18
|
+
$color_map[[fgc, bgc]] = @color_id
|
19
|
+
return @color_id
|
20
|
+
end
|
21
|
+
## public
|
22
|
+
# returns a color_pair for a given foreground and background color
|
23
|
+
def ColorMap.get_color fgc, bgc=$def_bg_color
|
24
|
+
if $color_map.include? [fgc, bgc]
|
25
|
+
# $log.debug " get_color found #{fgc} #{@bgc} "
|
26
|
+
return $color_map[[fgc, bgc]]
|
27
|
+
else
|
28
|
+
# $log.debug " get_color NOT found #{fgc} #{@bgc} "
|
29
|
+
return ColorMap.install_color fgc, bgc
|
30
|
+
end
|
31
|
+
end
|
32
|
+
def ColorMap.colors
|
33
|
+
@@colors
|
34
|
+
end
|
35
|
+
|
36
|
+
## public
|
37
|
+
# setup color map at start of application
|
38
|
+
def ColorMap.setup
|
39
|
+
@color_id = 0
|
40
|
+
$color_map = {}
|
41
|
+
Ncurses.start_color();
|
42
|
+
# Initialize few color pairs
|
43
|
+
$def_fg_color = "white" # pls set these 2 for your application
|
44
|
+
$def_bg_color = "black"
|
45
|
+
#COLORS = [COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
|
46
|
+
# COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE]
|
47
|
+
@@colors = %w[black red green yellow blue magenta cyan white]
|
48
|
+
|
49
|
+
# make foreground colors
|
50
|
+
bg = ColorMap.get_color_const $def_bg_color
|
51
|
+
@@colors[0...@@colors.size].each_with_index do |color, i|
|
52
|
+
next if color == $def_bg_color
|
53
|
+
ColorMap.install_color color, $def_bg_color
|
54
|
+
end
|
55
|
+
$reversecolor = ColorMap.get_color $def_bg_color, $def_fg_color
|
56
|
+
$popupcolor = ColorMap.get_color 'cyan', $def_fg_color
|
57
|
+
|
58
|
+
$errorcolor = ColorMap.get_color 'white', 'red'
|
59
|
+
$promptcolor = $selectedcolor = ColorMap.get_color('yellow', 'red')
|
60
|
+
$normalcolor = $datacolor = ColorMap.get_color('white', 'black')
|
61
|
+
$bottomcolor = $topcolor = ColorMap.get_color('white', 'blue')
|
62
|
+
|
63
|
+
# $log.debug " colormap SETUP: #{$datacolor} #{$reversecolor} "
|
64
|
+
end
|
65
|
+
|
66
|
+
end # modul
|
67
|
+
if $0 == __FILE__
|
68
|
+
require 'logger'
|
69
|
+
require 'lib/ver/window'
|
70
|
+
include Ncurses
|
71
|
+
include ColorMap
|
72
|
+
# Initialize curses
|
73
|
+
begin
|
74
|
+
VER::start_ncurses
|
75
|
+
@window = VER::Window.root_window
|
76
|
+
$log = Logger.new("view.log")
|
77
|
+
$log.level = Logger::DEBUG
|
78
|
+
ColorMap.setup
|
79
|
+
|
80
|
+
# Create the window to be associated with the form
|
81
|
+
# Un post form and free the memory
|
82
|
+
|
83
|
+
catch(:close) do
|
84
|
+
# $log.debug "START ---------"
|
85
|
+
# need to pass a form, not window.
|
86
|
+
r = 1; c = 2; i=0
|
87
|
+
attr = Ncurses::A_NORMAL
|
88
|
+
@window.printstring 20, c, "press 0-9 to change BG color, F1/q to quit. r-everse, n-ormal,b-old ", ColorMap.get_color('white')
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
while((ch = @window.getchar()) != KEY_F1 )
|
93
|
+
next if ch == -1
|
94
|
+
break if ch == ?q
|
95
|
+
case ch
|
96
|
+
when ?r
|
97
|
+
attr |= Ncurses::A_REVERSE
|
98
|
+
when ?b
|
99
|
+
attr |= Ncurses::A_BOLD
|
100
|
+
when ?n
|
101
|
+
attr = Ncurses::A_NORMAL
|
102
|
+
when ?u
|
103
|
+
attr |= Ncurses::A_UNDERLINE
|
104
|
+
else
|
105
|
+
i = ch.chr.to_i
|
106
|
+
i = 1 if i > ColorMap::colors.length-1
|
107
|
+
end
|
108
|
+
bg = ColorMap::colors[i]
|
109
|
+
@@colors = %w[black red green yellow blue magenta cyan white]
|
110
|
+
@window.printstring r, c, "%-40s" % "red #{bg} ", ColorMap.get_color('red',bg) , attr
|
111
|
+
@window.printstring 2, c, "%-40s" % "blue #{bg} ", ColorMap.get_color('blue',bg) , attr
|
112
|
+
@window.printstring 3, c, "%-40s" % "white #{bg} ", ColorMap.get_color('white',bg) , attr
|
113
|
+
@window.printstring 4, c, "%-40s" % "green #{bg} ", ColorMap.get_color('green',bg) , attr
|
114
|
+
@window.printstring 5, c, "%-40s" % "cyan #{bg} ", ColorMap.get_color('cyan',bg) , attr
|
115
|
+
@window.printstring 6, c, "%-40s" % "magenta #{bg} ", ColorMap.get_color('magenta',bg) , attr
|
116
|
+
@window.printstring 7, c, "black #{bg} ", ColorMap.get_color('black',bg) , attr
|
117
|
+
@window.wrefresh
|
118
|
+
end
|
119
|
+
# VER::Keyboard.focus = tp
|
120
|
+
end
|
121
|
+
rescue => ex
|
122
|
+
ensure
|
123
|
+
# @panel = @window.panel if @window
|
124
|
+
# Ncurses::Panel.del_panel(@panel) if !@panel.nil?
|
125
|
+
# @window.delwin if !@window.nil?
|
126
|
+
@window.destroy unless @window.nil?
|
127
|
+
VER::stop_ncurses
|
128
|
+
p ex if ex
|
129
|
+
p(ex.backtrace.join("\n")) if ex
|
130
|
+
# $log.debug( ex) if ex
|
131
|
+
# $log.debug(ex.backtrace.join("\n")) if ex
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ncurses'
|
3
|
+
require 'logger'
|
4
|
+
#require 'lib/rbcurse/rwidget'
|
5
|
+
module RubyCurses
|
6
|
+
|
7
|
+
##
|
8
|
+
# This is a list cell renderer that will render combo boxes.
|
9
|
+
# Since a combo box extends a field therefore the repaint of field is used.
|
10
|
+
# In other words there is nothing much to do here.
|
11
|
+
#
|
12
|
+
class ComboBoxCellRenderer < ListCellRenderer
|
13
|
+
include ConfigSetup
|
14
|
+
include RubyCurses::Utils
|
15
|
+
dsl_accessor :justify # :right, :left, :center # added 2008-12-22 19:02
|
16
|
+
dsl_accessor :display_length # please give this to ensure the we only print this much
|
17
|
+
dsl_accessor :height # if you want a multiline label.
|
18
|
+
dsl_accessor :text # text of label
|
19
|
+
dsl_accessor :color, :bgcolor
|
20
|
+
dsl_accessor :row, :col
|
21
|
+
dsl_accessor :parent #usuall the table to get colors and other default info
|
22
|
+
|
23
|
+
def initialize text="", config={}, &block
|
24
|
+
@text = text
|
25
|
+
@editable = false
|
26
|
+
@focusable = false
|
27
|
+
config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
|
28
|
+
instance_eval &block if block_given?
|
29
|
+
init_vars
|
30
|
+
end
|
31
|
+
def init_vars
|
32
|
+
@justify ||= :left
|
33
|
+
@display_length ||= 10
|
34
|
+
end
|
35
|
+
## me thinks this is unused
|
36
|
+
def getvalue
|
37
|
+
raise "I think this is unused. comboboxcellrenderer line 36"
|
38
|
+
@text
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
#
|
43
|
+
# ADD HERE
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RubyCurses
|
2
|
+
class DefaultListSelectionModel
|
3
|
+
include EventHandler
|
4
|
+
attr_accessor :selection_mode
|
5
|
+
attr_reader :anchor_selection_index
|
6
|
+
attr_reader :lead_selection_index
|
7
|
+
def initialize
|
8
|
+
@selected_indices=[]
|
9
|
+
@anchor_selection_index = -1
|
10
|
+
@lead_selection_index = -1
|
11
|
+
@selection_mode = :MULTIPLE
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear_selection
|
15
|
+
@selected_indices=[]
|
16
|
+
end
|
17
|
+
def is_selected_index ix
|
18
|
+
@selected_indices.include? ix
|
19
|
+
end
|
20
|
+
def get_max_selection_index
|
21
|
+
@selected_indices[-1]
|
22
|
+
end
|
23
|
+
def get_min_selection_index
|
24
|
+
@selected_indices[0]
|
25
|
+
end
|
26
|
+
def get_selected_rows
|
27
|
+
@selected_indices
|
28
|
+
end
|
29
|
+
## TODO should go in sorted, and no dupes
|
30
|
+
def add_selection_interval ix0, ix1
|
31
|
+
if @selection_mode != :MULTIPLE
|
32
|
+
clear_selection
|
33
|
+
end
|
34
|
+
@anchor_selection_index = ix0
|
35
|
+
@lead_selection_index = ix1
|
36
|
+
ix0.upto(ix1) {|i| @selected_indices << i unless @selected_indices.include? i }
|
37
|
+
end
|
38
|
+
def remove_selection_interval ix0, ix1
|
39
|
+
@anchor_selection_index = ix0
|
40
|
+
@lead_selection_index = ix1
|
41
|
+
@selected_indices.delete_if {|x| x >= ix0 and x <= ix1}
|
42
|
+
end
|
43
|
+
def insert_index_interval ix0, len
|
44
|
+
@anchor_selection_index = ix0
|
45
|
+
@lead_selection_index = ix0+len
|
46
|
+
add_selection_interval @anchor_selection_index, @lead_selection_index
|
47
|
+
end
|
48
|
+
end # class DefaultListSelectionModel
|
49
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'rbcurse/rwidget'
|
2
|
+
include Ncurses
|
3
|
+
include RubyCurses
|
4
|
+
module RubyCurses
|
5
|
+
class KeyLabelPrinter < Widget
|
6
|
+
attr_reader :key_labels
|
7
|
+
dsl_property :mode
|
8
|
+
|
9
|
+
def initialize form, key_labels, config={}, &block
|
10
|
+
|
11
|
+
super form, config, &block
|
12
|
+
@mode ||= :normal
|
13
|
+
#@key_labels = key_labels
|
14
|
+
@key_hash = {}
|
15
|
+
@key_hash[@mode] = key_labels
|
16
|
+
@editable = false
|
17
|
+
@focusable = false
|
18
|
+
@cols ||= Ncurses.COLS-1
|
19
|
+
@row ||= Ncurses.LINES-3
|
20
|
+
@col ||= 0
|
21
|
+
@repaint_required = true
|
22
|
+
@footer_color_pair ||= $bottomcolor
|
23
|
+
@footer_mnemonic_color_pair ||= $reversecolor #2
|
24
|
+
end
|
25
|
+
def key_labels mode=@mode
|
26
|
+
@key_hash[mode]
|
27
|
+
end
|
28
|
+
# returns the keys as printed. these may or may not help
|
29
|
+
# in validation depedign on what you passed as zeroth index
|
30
|
+
def get_current_keys
|
31
|
+
a = []
|
32
|
+
@key_hash[@mode].each do |arr|
|
33
|
+
a << arr[0] unless arr.nil?
|
34
|
+
end
|
35
|
+
return a
|
36
|
+
end
|
37
|
+
def getvalue
|
38
|
+
@key_hash
|
39
|
+
end
|
40
|
+
def set_key_labels _key_labels, mode=:normal
|
41
|
+
@key_hash[mode] = _key_labels
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# XXX need to move wrapping etc up and done once.
|
46
|
+
def repaint
|
47
|
+
return unless @repaint_required
|
48
|
+
r,c = rowcol
|
49
|
+
print_key_labels(arr = key_labels(), mode=@mode)
|
50
|
+
@repaint_required = false
|
51
|
+
end
|
52
|
+
def append_key_label key, label, mode=@mode
|
53
|
+
@key_labels << [key, label] if !@key_labels.include? [key, label]
|
54
|
+
@repaint_required = true
|
55
|
+
end
|
56
|
+
def print_key_labels(arr = key_labels(), mode=@mode)
|
57
|
+
#return if !@show_key_labels # XXX
|
58
|
+
@win ||= @form.window
|
59
|
+
@padding = @cols / (arr.length/2)
|
60
|
+
posx = 0
|
61
|
+
even = []
|
62
|
+
odd = []
|
63
|
+
arr.each_index { |i|
|
64
|
+
if i % 2 == 0
|
65
|
+
#arr[i+1] = ['',''] if arr[i+1].nil?
|
66
|
+
nextarr = arr[i+1] || ['', '']
|
67
|
+
keyw = [arr[i][0].length, nextarr[0].length].max
|
68
|
+
labelw = [arr[i][1].length, nextarr[1].length].max
|
69
|
+
|
70
|
+
even << [ sprintf("%*s", keyw, arr[i][0]), sprintf("%-*s", labelw, arr[i][1]) ]
|
71
|
+
odd << [ sprintf("%*s", keyw, nextarr[0]), sprintf("%-*s", labelw, nextarr[1]) ]
|
72
|
+
#$log.debug("loop even: #{even.inspect}")
|
73
|
+
else
|
74
|
+
end
|
75
|
+
}
|
76
|
+
#$log.debug("even: #{even.inspect}")
|
77
|
+
#$log.debug("odd : #{odd.inspect}")
|
78
|
+
#posy = @barrow-1
|
79
|
+
posy = @row
|
80
|
+
print_key_labels_row(posy, posx, even)
|
81
|
+
posy = @row+1
|
82
|
+
print_key_labels_row(posy, posx, odd)
|
83
|
+
#@win.wrefresh # needed else secod row not shown after askchoice XXX
|
84
|
+
end
|
85
|
+
def print_key_labels_row(posy, posx, arr)
|
86
|
+
# FIXME: this logic of padding needs to take into account
|
87
|
+
# width of window
|
88
|
+
padding = 8
|
89
|
+
padding = 4 if arr.length > 5
|
90
|
+
padding = 2 if arr.length > 7
|
91
|
+
padding = 0 if arr.length > 9
|
92
|
+
#padding = @padding # XXX 2008-11-13 23:01
|
93
|
+
my_form_win = @win
|
94
|
+
@win.printstring(posy,0, "%-*s" % [@cols," "], @footer_color_pair, @attr)
|
95
|
+
arr.each do |kl|
|
96
|
+
key = kl[0]
|
97
|
+
lab = kl[1]
|
98
|
+
if key !="" # don't print that white blank space for fillers
|
99
|
+
color_pair= @footer_mnemonic_color_pair # $reversecolor #2
|
100
|
+
x = posx + (key.length - key.strip.length)
|
101
|
+
my_form_win.attron(Ncurses.COLOR_PAIR(color_pair))
|
102
|
+
my_form_win.mvprintw(posy, x, "%s" % kl[0].strip );
|
103
|
+
my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair))
|
104
|
+
end
|
105
|
+
color_pair=@footer_color_pair
|
106
|
+
posx = posx + kl[0].length
|
107
|
+
my_form_win.attron(Ncurses.COLOR_PAIR(color_pair))
|
108
|
+
|
109
|
+
#lab = sprintf(" %s %*s" , kl[1], padding, " ");
|
110
|
+
lab = sprintf(" %s %s" , kl[1], " "*padding);
|
111
|
+
my_form_win.mvprintw(posy, posx, lab)
|
112
|
+
my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair))
|
113
|
+
posx = posx + lab.length
|
114
|
+
end
|
115
|
+
end
|
116
|
+
##
|
117
|
+
# updates existing label with a new one.
|
118
|
+
# @return true if updated, else false
|
119
|
+
def update_application_key_label(display_code, new_display_code, text)
|
120
|
+
@repaint_required = true
|
121
|
+
labels = key_labels()
|
122
|
+
labels.each_index do |ix|
|
123
|
+
lab = labels[ix]
|
124
|
+
if lab[0] == display_code
|
125
|
+
labels[ix] = [new_display_code , text]
|
126
|
+
$log.debug("updated #{labels[ix]}")
|
127
|
+
return true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
return false
|
131
|
+
end
|
132
|
+
##
|
133
|
+
# inserts an application label at given index
|
134
|
+
# to add the key, use create_datakeys to add bindings
|
135
|
+
# remember to call restore_application_key_labels after updating/inserting
|
136
|
+
def insert_application_key_label(index, display_code, text)
|
137
|
+
@repaint_required = true
|
138
|
+
labels = key_labels()
|
139
|
+
labels.insert(index, [display_code , text] )
|
140
|
+
end
|
141
|
+
# ADD HERE KEYLABEL
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ncurses'
|
3
|
+
require 'logger'
|
4
|
+
require 'rbcurse/rwidget'
|
5
|
+
module RubyCurses
|
6
|
+
|
7
|
+
##
|
8
|
+
# This is a basic list cell renderer that will render the to_s value of anything.
|
9
|
+
# Using alignment one can use for numbers too.
|
10
|
+
# However, for booleans it will print true and false. If editing, you may want checkboxes
|
11
|
+
class ListCellRenderer
|
12
|
+
#include DSL
|
13
|
+
#include EventHandler
|
14
|
+
include RubyCurses::ConfigSetup
|
15
|
+
include RubyCurses::Utils
|
16
|
+
dsl_accessor :justify # :right, :left, :center # added 2008-12-22 19:02
|
17
|
+
dsl_accessor :display_length # please give this to ensure the we only print this much
|
18
|
+
dsl_accessor :height # if you want a multiline label.
|
19
|
+
dsl_accessor :text # text of label
|
20
|
+
dsl_accessor :color, :bgcolor
|
21
|
+
dsl_accessor :row, :col
|
22
|
+
dsl_accessor :parent #usuall the table to get colors and other default info
|
23
|
+
|
24
|
+
def initialize text="", config={}, &block
|
25
|
+
@text = text
|
26
|
+
@editable = false
|
27
|
+
@focusable = false
|
28
|
+
config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
|
29
|
+
instance_eval &block if block_given?
|
30
|
+
init_vars
|
31
|
+
end
|
32
|
+
def init_vars
|
33
|
+
@justify ||= :left
|
34
|
+
@display_length ||= 10
|
35
|
+
end
|
36
|
+
def getvalue
|
37
|
+
@text
|
38
|
+
end
|
39
|
+
##
|
40
|
+
# sets @color_pair and @attr
|
41
|
+
def prepare_default_colors focussed, selected
|
42
|
+
@color_pair = get_color $datacolor
|
43
|
+
#acolor =get_color $datacolor, @color || @parent.color, @bgcolor || @parent.bgcolor #unless @parent.nil?
|
44
|
+
@attr = @row_attr || Ncurses::A_NORMAL
|
45
|
+
##@row_attr = Ncurses::A_NORMAL # added 2009-02-04 18:35 since overriding in rfe
|
46
|
+
|
47
|
+
|
48
|
+
## determine bg and fg and attr
|
49
|
+
if selected
|
50
|
+
@attr = Ncurses::A_BOLD if selected
|
51
|
+
@color_pair =get_color $selectedcolor, @parent.selected_color, @parent.selected_bgcolor unless @parent.nil?
|
52
|
+
end
|
53
|
+
if focussed
|
54
|
+
@attr |= Ncurses::A_REVERSE
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
#
|
60
|
+
def repaint graphic, r=@row,c=@col, row_index=-1,value=@text, focussed=false, selected=false
|
61
|
+
#$log.debug "label :#{@text}, #{value}, #{r}, #{c} col= #{@color}, #{@bgcolor} acolor= #{acolor} j:#{@justify} dlL: #{@display_length} "
|
62
|
+
|
63
|
+
prepare_default_colors focussed, selected
|
64
|
+
|
65
|
+
lablist = []
|
66
|
+
value=value.to_s # ??
|
67
|
+
if @height && @height > 1
|
68
|
+
lablist = wrap_text(value, @display_length).split("\n")
|
69
|
+
else
|
70
|
+
# ensure we do not exceed
|
71
|
+
if !@display_length.nil?
|
72
|
+
if value.length > @display_length
|
73
|
+
value = value[0..@display_length-1]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
lablist << value
|
77
|
+
end
|
78
|
+
len = @display_length || value.length
|
79
|
+
_height = @height || 1
|
80
|
+
str = @justify.to_sym == :right ? "%*s" : "%-*s" # added 2008-12-22 19:05
|
81
|
+
# loop added for labels that are wrapped.
|
82
|
+
# clear separately since value can change in status like labels
|
83
|
+
#len -= @left_margin
|
84
|
+
0.upto(_height-1) { |i|
|
85
|
+
graphic.printstring r+i, c, ( " " * len) , @color_pair,@attr
|
86
|
+
}
|
87
|
+
lablist.each_with_index do |_value, ix|
|
88
|
+
break if ix >= _height
|
89
|
+
if @justify.to_sym == :center
|
90
|
+
padding = (@display_length - _value.length)/2
|
91
|
+
_value = " "*padding + _value + " "*padding # so its cleared if we change it midway
|
92
|
+
end
|
93
|
+
graphic.printstring r, c, str % [len, _value], @color_pair,@attr
|
94
|
+
r += 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
# ADD HERE
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RubyCurses
|
2
|
+
module ListKeys
|
3
|
+
## Note: keeping variables gives the false feeling that one can change the var anytime.
|
4
|
+
# That was possible earlier, but now that i am binding the key at construction time
|
5
|
+
# any changes to the vars after construction won't have an effect.
|
6
|
+
def install_list_keys
|
7
|
+
@KEY_ROW_SELECTOR ||= ?\C-x
|
8
|
+
@KEY_GOTO_TOP ||= ?\M-0
|
9
|
+
@KEY_GOTO_BOTTOM ||= ?\M-9
|
10
|
+
@KEY_ASK_FIND_FORWARD ||= ?\M-f
|
11
|
+
@KEY_ASK_FIND_BACKWARD ||= ?\M-F
|
12
|
+
@KEY_FIND_NEXT ||= ?\M-g
|
13
|
+
@KEY_FIND_PREV ||= ?\M-G
|
14
|
+
@KEY_SCROLL_FORWARD ||= ?\C-n
|
15
|
+
@KEY_SCROLL_BACKWARD ||= ?\C-p
|
16
|
+
|
17
|
+
@KEY_CLEAR_SELECTION ||= ?\M-e
|
18
|
+
@KEY_PREV_SELECTION ||= ?\M-"
|
19
|
+
@KEY_NEXT_SELECTION ||= ?\M-'
|
20
|
+
|
21
|
+
=begin
|
22
|
+
bind_key(@KEY_ROW_SELECTOR) { toggle_row_selection }
|
23
|
+
bind_key(@KEY_GOTO_TOP) { goto_top }
|
24
|
+
bind_key(@KEY_GOTO_BOTTOM) { goto_bottom }
|
25
|
+
bind_key(@KEY_CLEAR_SELECTION) { clear_selection }
|
26
|
+
bind_key(@KEY_ASK_FIND_FORWARD) { ask_search_forward }
|
27
|
+
bind_key(@KEY_ASK_FIND_BACKWARD) { ask_search_backward }
|
28
|
+
bind_key(@KEY_FIND_NEXT) { find_next }
|
29
|
+
bind_key(@KEY_FIND_PREV) { find_prev }
|
30
|
+
=end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|