rbcurse-extras 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.md +75 -0
  2. data/VERSION +1 -0
  3. data/examples/data/list.txt +300 -0
  4. data/examples/data/lotr.txt +12 -0
  5. data/examples/data/table.txt +36 -0
  6. data/examples/data/tasks.txt +27 -0
  7. data/examples/data/unix1.txt +21 -0
  8. data/examples/inc/qdfilechooser.rb +70 -0
  9. data/examples/inc/rfe_renderer.rb +121 -0
  10. data/examples/newtabbedwindow.rb +100 -0
  11. data/examples/rfe.rb +1236 -0
  12. data/examples/test2.rb +670 -0
  13. data/examples/testeditlist.rb +78 -0
  14. data/examples/testtable.rb +270 -0
  15. data/examples/testvimsplit.rb +141 -0
  16. data/lib/rbcurse/extras/include/celleditor.rb +112 -0
  17. data/lib/rbcurse/extras/include/checkboxcellrenderer.rb +57 -0
  18. data/lib/rbcurse/extras/include/comboboxcellrenderer.rb +30 -0
  19. data/lib/rbcurse/extras/include/defaultlistselectionmodel.rb +79 -0
  20. data/lib/rbcurse/extras/include/listkeys.rb +37 -0
  21. data/lib/rbcurse/extras/include/listselectable.rb +144 -0
  22. data/lib/rbcurse/extras/include/tableextended.rb +40 -0
  23. data/lib/rbcurse/extras/widgets/horizlist.rb +203 -0
  24. data/lib/rbcurse/extras/widgets/menutree.rb +63 -0
  25. data/lib/rbcurse/extras/widgets/multilinelabel.rb +142 -0
  26. data/lib/rbcurse/extras/widgets/rcomboedit.rb +256 -0
  27. data/lib/rbcurse/extras/widgets/rlink.rb.moved +27 -0
  28. data/lib/rbcurse/extras/widgets/rlistbox.rb +1247 -0
  29. data/lib/rbcurse/extras/widgets/rmenulink.rb.moved +21 -0
  30. data/lib/rbcurse/extras/widgets/rmulticontainer.rb +304 -0
  31. data/lib/rbcurse/extras/widgets/rmultisplit.rb +722 -0
  32. data/lib/rbcurse/extras/widgets/rmultitextview.rb +306 -0
  33. data/lib/rbcurse/extras/widgets/rpopupmenu.rb +755 -0
  34. data/lib/rbcurse/extras/widgets/rtable.rb +1758 -0
  35. data/lib/rbcurse/extras/widgets/rvimsplit.rb +800 -0
  36. data/lib/rbcurse/extras/widgets/table/tablecellrenderer.rb +86 -0
  37. data/lib/rbcurse/extras/widgets/table/tabledatecellrenderer.rb +98 -0
  38. metadata +94 -0
@@ -0,0 +1,40 @@
1
+ # Provides extended abilities to a table
2
+ # so user does not need to code it into his app.
3
+ # At the same time, i don't want to weigh down Table with too much functionality/
4
+ # I am putting in some stuff, so that table columns can be resized, using multipliers.
5
+ # That allows us to redistribute the space taken or released across rows.
6
+ # Other options: dd, C, . (repeat) and how about range operations
7
+ #
8
+ module TableExtended
9
+
10
+ ##
11
+ # increase the focused column
12
+ # If no size passed, then use numeric multiplier, else 1
13
+ # Typically, one would bind a key such as + to this method
14
+ # e.g. atable.bind_key(?+) { atable.increase_column ; }
15
+ # See examples/viewtodo.rb for usage
16
+ def increase_column num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
17
+
18
+ acolumn = column focussed_col()
19
+ #num = $multiplier || 1
20
+ $multiplier = 0
21
+ w = acolumn.width + num
22
+ acolumn.width w
23
+ #atable.table_structure_changed
24
+ end
25
+ # decrease the focused column
26
+ # If no size passed, then use numeric multiplier, else 1
27
+ # Typically, one would bind a key such as - to this method
28
+ def decrease_column num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
29
+ acolumn = column focussed_col()
30
+ w = acolumn.width - num
31
+ $multiplier = 0
32
+ if w > 3
33
+ acolumn.width w
34
+ #atable.table_structure_changed
35
+ end
36
+ end
37
+
38
+
39
+
40
+ end
@@ -0,0 +1,203 @@
1
+ require 'rbcurse'
2
+
3
+ # This is a horizontal scroller, to scroll a list of options much like
4
+ # vim often does on the statusline. I'd like to use it for scrolling
5
+ # menus or buttons like on TabbedPanes to avoid another Form.
6
+
7
+ # You may bind to the ENTER_ROW event to chagne some data elsewhere,
8
+ # or the PRESS event. In this case, PRESS will refer to pressing the
9
+ # space bar or ENTER. There is <em>no</em> LIST_SELECTION event for that.
10
+
11
+
12
+
13
+ module RubyCurses
14
+
15
+ # Horizontal list scrolling and selection.
16
+ #
17
+ # == Example
18
+ # require 'rbcurse/extras/widgets/horizlist'
19
+ # require 'fileutils'
20
+ # l = HorizList.new @form, :row => 5, :col => 5, :width => 80
21
+ # list = Dir.glob("*")
22
+ # l.list(list)
23
+
24
+ class HorizList < Widget
25
+
26
+ def initialize form, config={}, &block
27
+ super
28
+ @_events.push(*[:ENTER_ROW, :LEAVE_ROW, :PRESS])
29
+ @focusable = true
30
+ init_vars
31
+ @list = []
32
+ @toprow = 0
33
+
34
+ # last printed index
35
+ @last_index = 0
36
+
37
+ # item on which cursor is
38
+ @current_index = 0
39
+ end
40
+ def init_vars
41
+ end
42
+ # alias :text :getvalue # NEXT VERSION
43
+
44
+ def map_keys
45
+ @keys_mapped = true
46
+ bind_keys([KEY_RIGHT, ?l, ?.], :next_item)
47
+ bind_keys([KEY_LEFT, ?h,?,], :previous_item)
48
+ bind_keys([10,13,32]){ fire_action_event }
49
+ bind_keys([?\M-l,?>, KEY_DOWN], :scroll_right)
50
+ bind_keys([?\M-h,?<, KEY_UP], :scroll_left)
51
+ end
52
+ def list(strings)
53
+ @list = strings
54
+ end
55
+ def add item
56
+ @list << item
57
+ end
58
+ def repaint
59
+ return unless @repaint_required
60
+ @window ||= @form.window
61
+ $log.debug "XXX:HORIZ REPAINT Ci #{@current_index}, TR #{@toprow} "
62
+ $status_message.value = " #{@current_index}, TR #{@toprow} "
63
+ @window.printstring @row, @col, " "* @width, @color_pair || $reversecolor
64
+ c = @col + 1
65
+ t = @toprow
66
+ @list.each_with_index { |e, i|
67
+ next if i < t # sucks for large lists
68
+ break if c + e.length >= @width + @col
69
+ att = @attrib || FFI::NCurses::A_NORMAL
70
+ if i == @current_index
71
+ att = FFI::NCurses::A_REVERSE if i == @current_index
72
+ acolor = @focussed_color_pair || get_color($datacolor,'green', 'white')
73
+ else
74
+ acolor = @color_pair
75
+ end
76
+ @window.printstring @row, c, e, acolor || $reversecolor, att
77
+ c += e.length + 2
78
+ @last_index = i
79
+ break if c >= @width + @col
80
+ }
81
+ @repaint_required = false
82
+ end
83
+ def handle_key ch
84
+ map_keys unless @keys_mapped
85
+ ret = process_key ch, self
86
+ @multiplier = 0
87
+ return :UNHANDLED if ret == :UNHANDLED
88
+ end
89
+ def previous_item num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
90
+
91
+ return :NO_PREVIOUS_ROW if @current_index == 0
92
+ @old_toprow = @toprow
93
+ @oldrow = @current_index
94
+ @current_index -= num
95
+ @current_index = 0 if @current_index < 0
96
+ bounds_check
97
+ $multiplier = 0
98
+ if @current_index < @toprow
99
+ @toprow = @current_index
100
+ end
101
+ @toprow = 0 if @toprow < 0
102
+ @repaint_required = true
103
+ end
104
+ def next_item num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
105
+ rc = row_count
106
+ return :NO_NEXT_ROW if @current_index == rc-1 # changed 2011-10-5 so process can do something
107
+ @old_toprow = @toprow
108
+ @oldrow = @current_index
109
+ @current_index += num
110
+ @current_index = rc - 1 if @current_index >= rc
111
+ @toprow = @current_index if @current_index > @last_index
112
+ bounds_check
113
+ $multiplier = 0
114
+ @repaint_required = true
115
+ end
116
+ def scroll_right
117
+ rc = row_count
118
+ return :NO_NEXT_ROW if @current_index == rc-1 # changed 2011-10-5 so process can do something
119
+ @old_toprow = @toprow
120
+ @oldrow = @current_index
121
+
122
+ @current_index = @last_index + 1
123
+
124
+ @current_index = rc - 1 if @current_index >= rc
125
+ @toprow = @current_index if @current_index > @last_index
126
+ bounds_check
127
+ $multiplier = 0
128
+ @repaint_required = true
129
+ end
130
+ def scroll_left
131
+ return :NO_PREVIOUS_ROW if @current_index == 0
132
+ @old_toprow = @toprow
133
+ @oldrow = @current_index
134
+ @current_index = @toprow - 4
135
+ @current_index = 0 if @current_index < 0
136
+ bounds_check
137
+ $multiplier = 0
138
+ if @current_index < @toprow
139
+ @toprow = @current_index
140
+ end
141
+ @toprow = 0 if @toprow < 0
142
+ @repaint_required = true
143
+ end
144
+ def row_count; @list.size; end
145
+ def bounds_check
146
+ @row_changed = false
147
+ if @oldrow != @current_index
148
+ on_leave_row @oldrow if respond_to? :on_leave_row # to be defined by widget that has included this
149
+ on_enter_row @current_index if respond_to? :on_enter_row # to be defined by widget that has included this
150
+ set_form_row
151
+ @row_changed = true
152
+ end
153
+ if @old_toprow != @toprow # only if scrolling has happened should we repaint
154
+ @repaint_required = true
155
+ @widget_scrolled = true
156
+ end
157
+ end
158
+ def on_enter
159
+ if @list.nil? || @list.size == 0
160
+ Ncurses.beep
161
+ return :UNHANDLED
162
+ end
163
+ super
164
+ on_enter_row @current_index
165
+ set_form_row
166
+ true
167
+ end
168
+ def on_enter_row arow
169
+ fire_handler :ENTER_ROW, self
170
+ @repaint_required = true
171
+ end
172
+ def on_leave_row arow
173
+ fire_handler :LEAVE_ROW, self
174
+ end
175
+ def fire_action_event
176
+ require 'rbcurse/core/include/ractionevent'
177
+ fire_handler :PRESS, ActionEvent.new(self, :PRESS, text)
178
+ end
179
+ def current_value
180
+ @list[@current_index]
181
+ end
182
+ alias :text :current_value
183
+ ##
184
+ end # class
185
+ end # module
186
+ if __FILE__ == $PROGRAM_NAME
187
+ require 'rbcurse/core/util/app'
188
+
189
+ App.new do
190
+ require 'rbcurse/extras/widgets/horizlist'
191
+ require 'fileutils'
192
+ l = HorizList.new @form, :row => 5, :col => 5, :width => 80
193
+ list = Dir.glob("*")
194
+ l.list(list)
195
+ l.bind(:PRESS){ |eve| alert "You pressed #{eve.text} " }
196
+ sl = status_line
197
+ sl.command do
198
+ " Status: #{$status_message} "
199
+ end
200
+ end
201
+
202
+
203
+ end
@@ -0,0 +1,63 @@
1
+ module RubyCurses
2
+ # Create a simple tree-ish structure.
3
+ # Each node is not a tree, only submenus are trees
4
+ # Others contain a hash with menu character and code
5
+ # Typically the code is not a method symbol, it is to be
6
+ # used to decode a description or method symbol from anoterh hash
7
+ # @usage
8
+ # menu = MenuTree.new "Main", { c: :goprev, d: :gonext, e: :gonext, s: :submenu }
9
+ # menu.submenu :s, "submenu", {a: :next1, b: :next2, f: :next3 }
10
+ # puts menu.hash
11
+ # puts "each ..."
12
+ # menu.each { |e| puts e }
13
+ # menu.each_pair { |e, v| puts "#{e} #{v}" }
14
+ # puts " -- :c -- "
15
+ # puts menu[:c]
16
+ # puts " -- :s -- "
17
+ # puts menu[:s].children
18
+ class MenuTree
19
+ attr_reader :value
20
+ def initialize value, hash = {}
21
+ @value = [value, hash]
22
+ end
23
+ def << kv
24
+ @value[1][kv[0]] = kv[1]
25
+ end
26
+ def hash
27
+ @value[1]
28
+ end
29
+ alias :children :hash
30
+ def push hsh
31
+ hash().merge hsh
32
+ end
33
+ def [](x)
34
+ hash()[x]
35
+ end
36
+ def []=(x,y)
37
+ hash()[x] = y
38
+ end
39
+ def submenu key, value, hash = {}
40
+ m = MenuTree.new value, hash
41
+ #hash()[key] = [value, hash]
42
+ hash()[key] = m
43
+ end
44
+ def each
45
+ hash().keys.each { |e| yield e }
46
+ end
47
+ def each_pair
48
+ hash().each_pair { |name, val| yield name, val }
49
+ end
50
+ end
51
+ end
52
+ if __FILE__ == $PROGRAM_NAME
53
+ menu = RubyCurses::MenuTree.new "Main", { c: :goprev, d: :gonext, e: :gonext, s: :submenu }
54
+ menu.submenu :s, "submenu", {a: :next1, b: :next2, f: :next3 }
55
+ puts menu.hash
56
+ puts "each ..."
57
+ menu.each { |e| puts e }
58
+ menu.each_pair { |e, v| puts "#{e} #{v}" }
59
+ puts " -- :c -- "
60
+ puts menu[:c]
61
+ puts " -- :s -- "
62
+ puts menu[:s].children
63
+ end
@@ -0,0 +1,142 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: multilinelabel.rb
3
+ # Description: Prints a label on the screen.
4
+ # This is the original label that was present in rwidgets.rb
5
+ # It allowed for multiple lines. I am simplifying that to a simple
6
+ # single line label.
7
+ # I am basically moving multiline labels out of hte core package
8
+ # Author: rkumar http://github.com/rkumar/rbcurse/
9
+ # Date: 2011-11-12 - 12:04
10
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
11
+ # Last update: 2011-11-12 - 12:05
12
+ # ----------------------------------------------------------------------------- #
13
+ #
14
+ module RubyCurses
15
+
16
+ # print static text on a form, allowing for text to be wrapped.
17
+ #
18
+ class MultiLineLabel < Widget
19
+ dsl_accessor :mnemonic # keyboard focus is passed to buddy based on this key (ALT mask)
20
+
21
+ # justify required a display length, esp if center.
22
+ dsl_property :justify #:right, :left, :center
23
+ dsl_property :display_length #please give this to ensure the we only print this much
24
+ #dsl_property :height #if you want a multiline label. already added to widget
25
+ # for consistency with others 2011-11-5
26
+ alias :width :display_length
27
+ alias :width= :display_length=
28
+
29
+ def initialize form, config={}, &block
30
+
31
+ # this crap was used in position_label, find another way. where is it used ?
32
+ #@row = config.fetch("row",-1) # why on earth this monstrosity ? 2011-11-5
33
+ #@col = config.fetch("col",-1)
34
+ #@bgcolor = config.fetch("bgcolor", $def_bg_color)
35
+ #@color = config.fetch("color", $def_fg_color)
36
+ @text = config.fetch("text", "NOTFOUND")
37
+ @editable = false
38
+ @focusable = false
39
+ super
40
+ @justify ||= :left
41
+ @name ||= @text
42
+ @repaint_required = true
43
+ end
44
+ #
45
+ # get the value for the label
46
+ def getvalue
47
+ @text_variable && @text_variable.value || @text
48
+ end
49
+ def label_for field
50
+ @label_for = field
51
+ #$log.debug " label for: #{@label_for}"
52
+ if @form
53
+ bind_hotkey
54
+ else
55
+ @when_form ||= []
56
+ @when_form << lambda { bind_hotkey }
57
+ end
58
+ end
59
+
60
+ ##
61
+ # for a button, fire it when label invoked without changing focus
62
+ # for other widgets, attempt to change focus to that field
63
+ def bind_hotkey
64
+ if !@mnemonic.nil?
65
+ ch = @mnemonic.downcase()[0].ord ## 1.9 DONE
66
+ # meta key
67
+ mch = ?\M-a.getbyte(0) + (ch - ?a.getbyte(0)) ## 1.9
68
+ if @label_for.is_a? RubyCurses::Button and @label_for.respond_to? :fire
69
+ @form.bind_key(mch, @label_for) { |_form, _butt| _butt.fire }
70
+ else
71
+ $log.debug " bind_hotkey label for: #{@label_for}"
72
+ @form.bind_key(mch, @label_for) { |_form, _field| _field.focus }
73
+ end
74
+ end
75
+ end
76
+
77
+ ##
78
+ # XXX need to move wrapping etc up and done once.
79
+ def repaint
80
+ return unless @repaint_required
81
+ raise "Label row or col nil #{@row} , #{@col}, #{@text} " if @row.nil? || @col.nil?
82
+ r,c = rowcol
83
+
84
+ @bgcolor ||= $def_bg_color
85
+ @color ||= $def_fg_color
86
+ # value often nil so putting blank, but usually some application error
87
+ value = getvalue_for_paint || ""
88
+ lablist = []
89
+ # trying out array values 2011-10-16 more for messageboxes.
90
+ if value.is_a? Array
91
+ lablist = text
92
+ @height = text.size
93
+ elsif @height && @height > 1
94
+ lablist = wrap_text(value, @display_length).split("\n")
95
+ else
96
+ # ensure we do not exceed
97
+ if !@display_length.nil?
98
+ if value.length > @display_length
99
+ value = value[0..@display_length-1]
100
+ end
101
+ end
102
+ lablist << value
103
+ end
104
+ len = @display_length || value.length
105
+ acolor = get_color $datacolor
106
+ $log.debug "label :#{@text}, #{value}, r #{r}, c #{c} col= #{@color}, #{@bgcolor} acolor #{acolor} j:#{@justify} dlL: #{@display_length} "
107
+ firstrow = r
108
+ _height = @height || 1
109
+ str = @justify.to_sym == :right ? "%*s" : "%-*s" # added 2008-12-22 19:05
110
+ # loop added for labels that are wrapped.
111
+ # TODO clear separately since value can change in status like labels
112
+
113
+ @graphic = @form.window if @graphic.nil? ## HACK messagebox givig this in repaint, 423 not working ??
114
+ 0.upto(_height-1) { |i|
115
+ @graphic.printstring r+i, c, " " * len , acolor,@attr
116
+ }
117
+ lablist.each_with_index do |_value, ix|
118
+ break if ix >= _height
119
+ if @justify.to_sym == :center
120
+ padding = (@display_length - _value.length)/2
121
+ _value = " "*padding + _value + " "*padding # so its cleared if we change it midway
122
+ end
123
+ @graphic.printstring r, c, str % [len, _value], acolor,@attr
124
+ r += 1
125
+ end
126
+ if !@mnemonic.nil?
127
+ ulindex = value.index(@mnemonic) || value.index(@mnemonic.swapcase)
128
+ @graphic.mvchgat(y=firstrow, x=c+ulindex, max=1, Ncurses::A_BOLD|Ncurses::A_UNDERLINE, acolor, nil)
129
+ end
130
+ #@form.window.mvchgat(y=r, x=c, max=len, Ncurses::A_NORMAL, color, nil)
131
+ @repaint_required = false
132
+ end
133
+ # Added 2011-10-22 to prevent some naive components from putting focus here.
134
+ def on_enter
135
+ raise "Cannot enter Label"
136
+ end
137
+ def on_leave
138
+ raise "Cannot leave Label"
139
+ end
140
+ # ADD HERE LABEL
141
+ end # class
142
+ end # module