rbcurse-core 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +69 -0
- data/VERSION +1 -0
- data/examples/abasiclist.rb +151 -0
- data/examples/alpmenu.rb +46 -0
- data/examples/app.sample +17 -0
- data/examples/atree.rb +100 -0
- data/examples/common/file.rb +45 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +60 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/table.txt +37 -0
- data/examples/data/tasks.csv +88 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todo.txt +10 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +487 -0
- data/examples/dirtree.rb +90 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +132 -0
- data/examples/tasks.rb +167 -0
- data/examples/term2.rb +83 -0
- data/examples/testkeypress.rb +72 -0
- data/examples/testlistbox.rb +158 -0
- data/examples/testmessagebox.rb +140 -0
- data/examples/testree.rb +106 -0
- data/examples/testwsshortcuts.rb +66 -0
- data/examples/testwsshortcuts2.rb +127 -0
- data/lib/rbcurse.rb +8 -0
- data/lib/rbcurse/core/docs/index.txt +73 -0
- data/lib/rbcurse/core/include/action.rb +40 -0
- data/lib/rbcurse/core/include/appmethods.rb +112 -0
- data/lib/rbcurse/core/include/bordertitle.rb +41 -0
- data/lib/rbcurse/core/include/chunk.rb +182 -0
- data/lib/rbcurse/core/include/io.rb +953 -0
- data/lib/rbcurse/core/include/listcellrenderer.rb +140 -0
- data/lib/rbcurse/core/include/listeditable.rb +317 -0
- data/lib/rbcurse/core/include/listscrollable.rb +590 -0
- data/lib/rbcurse/core/include/listselectable.rb +264 -0
- data/lib/rbcurse/core/include/multibuffer.rb +83 -0
- data/lib/rbcurse/core/include/orderedhash.rb +77 -0
- data/lib/rbcurse/core/include/ractionevent.rb +67 -0
- data/lib/rbcurse/core/include/rchangeevent.rb +27 -0
- data/lib/rbcurse/core/include/rhistory.rb +62 -0
- data/lib/rbcurse/core/include/rinputdataevent.rb +47 -0
- data/lib/rbcurse/core/include/vieditable.rb +170 -0
- data/lib/rbcurse/core/system/colormap.rb +163 -0
- data/lib/rbcurse/core/system/keyboard.rb +150 -0
- data/lib/rbcurse/core/system/keydefs.rb +30 -0
- data/lib/rbcurse/core/system/ncurses.rb +218 -0
- data/lib/rbcurse/core/system/panel.rb +162 -0
- data/lib/rbcurse/core/system/window.rb +901 -0
- data/lib/rbcurse/core/util/ansiparser.rb +117 -0
- data/lib/rbcurse/core/util/app.rb +1235 -0
- data/lib/rbcurse/core/util/basestack.rb +407 -0
- data/lib/rbcurse/core/util/bottomline.rb +1850 -0
- data/lib/rbcurse/core/util/colorparser.rb +71 -0
- data/lib/rbcurse/core/util/focusmanager.rb +31 -0
- data/lib/rbcurse/core/util/padreader.rb +189 -0
- data/lib/rbcurse/core/util/rcommandwindow.rb +587 -0
- data/lib/rbcurse/core/util/rdialogs.rb +619 -0
- data/lib/rbcurse/core/util/viewer.rb +149 -0
- data/lib/rbcurse/core/util/widgetshortcuts.rb +505 -0
- data/lib/rbcurse/core/widgets/applicationheader.rb +102 -0
- data/lib/rbcurse/core/widgets/box.rb +58 -0
- data/lib/rbcurse/core/widgets/divider.rb +310 -0
- data/lib/rbcurse/core/widgets/keylabelprinter.rb +178 -0
- data/lib/rbcurse/core/widgets/rcombo.rb +238 -0
- data/lib/rbcurse/core/widgets/rcontainer.rb +415 -0
- data/lib/rbcurse/core/widgets/rlink.rb +30 -0
- data/lib/rbcurse/core/widgets/rlist.rb +723 -0
- data/lib/rbcurse/core/widgets/rmenu.rb +939 -0
- data/lib/rbcurse/core/widgets/rmenulink.rb +22 -0
- data/lib/rbcurse/core/widgets/rmessagebox.rb +373 -0
- data/lib/rbcurse/core/widgets/rprogress.rb +118 -0
- data/lib/rbcurse/core/widgets/rtabbedpane.rb +615 -0
- data/lib/rbcurse/core/widgets/rtabbedwindow.rb +68 -0
- data/lib/rbcurse/core/widgets/rtextarea.rb +920 -0
- data/lib/rbcurse/core/widgets/rtextview.rb +780 -0
- data/lib/rbcurse/core/widgets/rtree.rb +787 -0
- data/lib/rbcurse/core/widgets/rwidget.rb +3040 -0
- data/lib/rbcurse/core/widgets/scrollbar.rb +143 -0
- data/lib/rbcurse/core/widgets/statusline.rb +94 -0
- data/lib/rbcurse/core/widgets/tabular.rb +264 -0
- data/lib/rbcurse/core/widgets/tabularwidget.rb +1211 -0
- data/lib/rbcurse/core/widgets/textpad.rb +516 -0
- data/lib/rbcurse/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/rbcurse/core/widgets/tree/treemodel.rb +428 -0
- metadata +156 -0
@@ -0,0 +1,615 @@
|
|
1
|
+
=begin
|
2
|
+
* Name: newtabbedpane.rb
|
3
|
+
* Description : This is radically simplified tabbedpane. The earlier version
|
4
|
+
was too complex with multiple forms and pads, and a scrollform. This uses
|
5
|
+
the external form and has some very simple programming to handle the whole thing.
|
6
|
+
* Author: rkumar (http://github.com/rkumar/rbcurse/)
|
7
|
+
* Date: 2011-10-20
|
8
|
+
* License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
9
|
+
* Last update: Sat Oct 22 18:40:49 IST 2011
|
10
|
+
|
11
|
+
== CHANGES
|
12
|
+
As of 1.5.0, this replaces the earlier TabbedPane which
|
13
|
+
now lies in lib/rbcurse/deprecated/widgets
|
14
|
+
in the rbcurse repo.
|
15
|
+
== TODO
|
16
|
+
on start first buttons bottom should not be lined.
|
17
|
+
Alt-1-9 to goto tabs
|
18
|
+
add remove tabs at any time - started, untested
|
19
|
+
events for tab add/remove/etc
|
20
|
+
=end
|
21
|
+
require 'rbcurse'
|
22
|
+
##
|
23
|
+
module RubyCurses
|
24
|
+
class TabbedPane < Widget
|
25
|
+
dsl_property :title, :title_attrib
|
26
|
+
# what kind of buttons, if this is a window, :ok :ok_camcel :ok_apply_cancel
|
27
|
+
dsl_accessor :button_type
|
28
|
+
attr_reader :button_row
|
29
|
+
# index of tab that is currently open
|
30
|
+
attr_reader :current_tab
|
31
|
+
|
32
|
+
|
33
|
+
def initialize form=nil, config={}, &block
|
34
|
+
@_events ||= []
|
35
|
+
@_events.push(:PRESS)
|
36
|
+
@button_gap = 2
|
37
|
+
init_vars
|
38
|
+
super
|
39
|
+
@focusable = true
|
40
|
+
@editable = true
|
41
|
+
@col_offset = 2
|
42
|
+
raise ArgumentError, "NewTabbedPane : row or col not set: r: #{@row} c: #{@col} " unless @row && @col
|
43
|
+
end
|
44
|
+
|
45
|
+
# Add a tab
|
46
|
+
def tab title, config={}, &block
|
47
|
+
#@tab_components[title]=[]
|
48
|
+
#@tabs << Tab.new(title, self, config, &block)
|
49
|
+
insert_tab @tabs.count, title, config, &block
|
50
|
+
self
|
51
|
+
end
|
52
|
+
alias :add_tab :tab
|
53
|
+
|
54
|
+
# a shortcut for binding a command to a press of an action button
|
55
|
+
# The block will be passed
|
56
|
+
# This is only relevant if you have asked for buttons to be created, which is
|
57
|
+
# only relevant in a TabbedWindow
|
58
|
+
# ActionEvent has source event and action_command
|
59
|
+
def command *args, &block
|
60
|
+
bind :PRESS, *args, &block
|
61
|
+
end
|
62
|
+
|
63
|
+
# -------------- tab maintenance commands ------------------ #
|
64
|
+
|
65
|
+
def insert_tab index, title, config={}, &block
|
66
|
+
@tabs.insert(index, Tab.new(title, self, config, &block) )
|
67
|
+
end
|
68
|
+
def remove_tab tab
|
69
|
+
@tabs.delete tab
|
70
|
+
self
|
71
|
+
end
|
72
|
+
def remove_all
|
73
|
+
@tabs = []
|
74
|
+
self
|
75
|
+
end
|
76
|
+
def remove_tab_at index = @current_tab
|
77
|
+
@tabs.delete_at index
|
78
|
+
end
|
79
|
+
|
80
|
+
def repaint
|
81
|
+
@current_tab ||= 0
|
82
|
+
@button_row ||= @row + 2
|
83
|
+
@separator_row = @button_row + 1 # hope we have it by now, where to print separator
|
84
|
+
@separator_row0 = @button_row - 1 unless @button_row == @row + 1
|
85
|
+
@separator_row2 = @row + @height - 3 # hope we have it by now, where to print separator
|
86
|
+
#return unless @repaint_required
|
87
|
+
if @buttons.empty?
|
88
|
+
_create_buttons
|
89
|
+
@components = @buttons.dup
|
90
|
+
@components.push(*@tabs[@current_tab].items)
|
91
|
+
create_action_buttons
|
92
|
+
@components.push(*@action_buttons)
|
93
|
+
elsif @tab_changed
|
94
|
+
@components = @buttons.dup
|
95
|
+
@components.push(*@tabs[@current_tab].items)
|
96
|
+
@components.push(*@action_buttons)
|
97
|
+
@tab_changed = false
|
98
|
+
end
|
99
|
+
# if some major change has happened then repaint everything
|
100
|
+
if @repaint_required
|
101
|
+
$log.debug " NEWTAB repaint graphic #{@graphic} "
|
102
|
+
print_borders unless @suppress_borders # do this once only, unless everything changes
|
103
|
+
print_separator1
|
104
|
+
@components.each { |e| e.repaint_all(true); e.repaint }
|
105
|
+
else
|
106
|
+
@components.each { |e| e.repaint }
|
107
|
+
end # if repaint_required
|
108
|
+
print_border if (@suppress_borders == false && @repaint_all) # do this once only, unless everything changes
|
109
|
+
@repaint_required = false
|
110
|
+
end
|
111
|
+
def handle_key ch
|
112
|
+
$log.debug " NEWTABBED handle_key #{ch} "
|
113
|
+
return if @components.empty?
|
114
|
+
_multiplier = ($multiplier == 0 ? 1 : $multiplier )
|
115
|
+
|
116
|
+
# should this go here 2011-10-19
|
117
|
+
unless @_entered
|
118
|
+
$log.warn "WARN: calling ON_ENTER since in this situation it was not called"
|
119
|
+
on_enter
|
120
|
+
end
|
121
|
+
#if ch == KEY_TAB
|
122
|
+
#$log.debug "NEWTABBED GOTO NEXT"
|
123
|
+
#return goto_next_component
|
124
|
+
#elsif ch == KEY_BTAB
|
125
|
+
#return goto_prev_component
|
126
|
+
#end
|
127
|
+
comp = @current_component
|
128
|
+
$log.debug " NEWTABBED handle_key #{ch}: #{comp}"
|
129
|
+
if comp
|
130
|
+
ret = comp.handle_key(ch)
|
131
|
+
$log.debug " NEWTABBED handle_key#{ch}: #{comp} returned #{ret} "
|
132
|
+
if ret != :UNHANDLED
|
133
|
+
comp.repaint # NOTE: if we don;t do this, then it won't get repainted. I will have to repaint ALL
|
134
|
+
# in repaint of this.
|
135
|
+
return ret
|
136
|
+
end
|
137
|
+
$log.debug "XXX NEWTABBED key unhandled by comp #{comp.name} "
|
138
|
+
else
|
139
|
+
Ncurses.beep
|
140
|
+
$log.warn "XXX NEWTABBED key unhandled NULL comp"
|
141
|
+
end
|
142
|
+
case ch
|
143
|
+
when ?\C-c.getbyte(0)
|
144
|
+
$multiplier = 0
|
145
|
+
return 0
|
146
|
+
when ?0.getbyte(0)..?9.getbyte(0)
|
147
|
+
$log.debug " VIM coming here to set multiplier #{$multiplier} "
|
148
|
+
$multiplier *= 10 ; $multiplier += (ch-48)
|
149
|
+
return 0
|
150
|
+
end
|
151
|
+
ret = process_key ch, self
|
152
|
+
# allow user to map left and right if he wants
|
153
|
+
if ret == :UNHANDLED
|
154
|
+
case ch
|
155
|
+
when KEY_UP, KEY_BTAB
|
156
|
+
# form will pick this up and do needful
|
157
|
+
return goto_prev_component #unless on_first_component?
|
158
|
+
when KEY_LEFT
|
159
|
+
# if i don't check for first component, key will go back to form,
|
160
|
+
# but not be processes. so focussed remain here, but be false.
|
161
|
+
# In case of returnign an unhandled TAB, on_leave will happen and cursor will move to
|
162
|
+
# previous component outside of this.
|
163
|
+
return goto_prev_component unless on_first_component?
|
164
|
+
when KEY_RIGHT, KEY_TAB
|
165
|
+
return goto_next_component #unless on_last_component?
|
166
|
+
when KEY_DOWN
|
167
|
+
if on_a_button?
|
168
|
+
return goto_first_item
|
169
|
+
else
|
170
|
+
return goto_next_component #unless on_last_component?
|
171
|
+
end
|
172
|
+
else
|
173
|
+
#@_entered = false
|
174
|
+
return :UNHANDLED
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
$multiplier = 0
|
179
|
+
return 0
|
180
|
+
end
|
181
|
+
# on enter processing
|
182
|
+
# Very often the first may be a label !
|
183
|
+
def on_enter
|
184
|
+
# if BTAB, the last comp
|
185
|
+
if $current_key == KEY_BTAB
|
186
|
+
@current_component = @components.last
|
187
|
+
else
|
188
|
+
@current_component = @components.first
|
189
|
+
end
|
190
|
+
return unless @current_component
|
191
|
+
$log.debug " NEWTABBED came to ON_ENTER #{@current_component} "
|
192
|
+
set_form_row
|
193
|
+
@_entered = true
|
194
|
+
end
|
195
|
+
def on_leave
|
196
|
+
@_entered = false
|
197
|
+
super
|
198
|
+
end
|
199
|
+
# takes focus to first item (after buttons)
|
200
|
+
def goto_first_item
|
201
|
+
bc = @buttons.count
|
202
|
+
@components[bc..-1].each { |c|
|
203
|
+
if c.focusable
|
204
|
+
leave_current_component
|
205
|
+
@current_component = c
|
206
|
+
set_form_row
|
207
|
+
break
|
208
|
+
end
|
209
|
+
}
|
210
|
+
end
|
211
|
+
def goto_last_item
|
212
|
+
bc = @buttons.count
|
213
|
+
f = nil
|
214
|
+
@components[bc..-1].each { |c|
|
215
|
+
if c.focusable
|
216
|
+
f = c
|
217
|
+
end
|
218
|
+
}
|
219
|
+
if f
|
220
|
+
leave_current_component
|
221
|
+
@current_component = f
|
222
|
+
set_form_row
|
223
|
+
end
|
224
|
+
end
|
225
|
+
def goto_next_component
|
226
|
+
if @current_component != nil
|
227
|
+
leave_current_component
|
228
|
+
if on_last_component?
|
229
|
+
@_entered = false
|
230
|
+
return :UNHANDLED
|
231
|
+
end
|
232
|
+
@current_index = @components.index(@current_component)
|
233
|
+
index = @current_index + 1
|
234
|
+
index.upto(@components.length-1) do |i|
|
235
|
+
f = @components[i]
|
236
|
+
if f.focusable
|
237
|
+
@current_index = i
|
238
|
+
@current_component = f
|
239
|
+
return set_form_row
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
@_entered = false
|
244
|
+
return :UNHANDLED
|
245
|
+
end
|
246
|
+
def goto_prev_component
|
247
|
+
if @current_component != nil
|
248
|
+
leave_current_component
|
249
|
+
if on_first_component?
|
250
|
+
@_entered = false
|
251
|
+
return :UNHANDLED
|
252
|
+
end
|
253
|
+
@current_index = @components.index(@current_component)
|
254
|
+
index = @current_index -= 1
|
255
|
+
index.downto(0) do |i|
|
256
|
+
f = @components[i]
|
257
|
+
if f.focusable
|
258
|
+
@current_index = i
|
259
|
+
@current_component = f
|
260
|
+
return set_form_row
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
return :UNHANDLED
|
265
|
+
end
|
266
|
+
# private
|
267
|
+
def set_form_row
|
268
|
+
return :UNHANDLED if @current_component.nil?
|
269
|
+
$log.debug " NEWTABBED on enter sfr #{@current_component} "
|
270
|
+
@current_component.on_enter
|
271
|
+
@current_component.set_form_row # why was this missing in vimsplit. is it
|
272
|
+
# that on_enter does a set_form_row
|
273
|
+
@current_component.set_form_col # XXX
|
274
|
+
@current_component.repaint
|
275
|
+
# XXX compo should do set_form_row and col if it has that
|
276
|
+
end
|
277
|
+
# private
|
278
|
+
def set_form_col
|
279
|
+
return if @current_component.nil?
|
280
|
+
$log.debug " #{@name} NEWTABBED set_form_col calling sfc for #{@current_component.name} "
|
281
|
+
@current_component.set_form_col
|
282
|
+
end
|
283
|
+
# leave the component we are on.
|
284
|
+
# This should be followed by all containers, so that the on_leave action
|
285
|
+
# of earlier comp can be displayed, such as dimming components selections
|
286
|
+
def leave_current_component
|
287
|
+
@current_component.on_leave
|
288
|
+
# NOTE this is required, since repaint will just not happen otherwise
|
289
|
+
# Some components are erroneously repainting all, after setting this to true so it is
|
290
|
+
# working there.
|
291
|
+
@current_component.repaint_required true
|
292
|
+
$log.debug " after on_leave VIMS XXX #{@current_component.focussed} #{@current_component.name}"
|
293
|
+
@current_component.repaint
|
294
|
+
end
|
295
|
+
|
296
|
+
# is focus on first component
|
297
|
+
def on_first_component?
|
298
|
+
@current_component == @components.first
|
299
|
+
end
|
300
|
+
# is focus on last component
|
301
|
+
def on_last_component?
|
302
|
+
@current_component == @components.last
|
303
|
+
end
|
304
|
+
def on_a_button?
|
305
|
+
@components.index(@current_component) < @buttons.count
|
306
|
+
end
|
307
|
+
# set focus on given component
|
308
|
+
# Sometimes you have the handle to component, and you want to move focus to it
|
309
|
+
def goto_component comp
|
310
|
+
return if comp == @current_component
|
311
|
+
leave_current_component
|
312
|
+
@current_component = comp
|
313
|
+
set_form_row
|
314
|
+
end
|
315
|
+
def set_current_tab t
|
316
|
+
return if @current_tab == t
|
317
|
+
@current_tab = t
|
318
|
+
goto_component @components[t]
|
319
|
+
@tab_changed = true
|
320
|
+
@repaint_required = true
|
321
|
+
self
|
322
|
+
end
|
323
|
+
|
324
|
+
def DEPRECATED_handle_key ch # :nodoc
|
325
|
+
map_keys unless @keys_mapped
|
326
|
+
ret = process_key ch, self
|
327
|
+
@multiplier = 0
|
328
|
+
return :UNHANDLED if ret == :UNHANDLED
|
329
|
+
return 0
|
330
|
+
end
|
331
|
+
|
332
|
+
# Put all the housekeeping stuff at the end
|
333
|
+
private
|
334
|
+
def init_vars
|
335
|
+
@buttons = []
|
336
|
+
@tabs = []
|
337
|
+
#@tab_components = {}
|
338
|
+
@bottombuttons = []
|
339
|
+
#
|
340
|
+
# I'll keep current tabs comps in this to simplify
|
341
|
+
@components = []
|
342
|
+
@_entered = false
|
343
|
+
end
|
344
|
+
|
345
|
+
def map_keys
|
346
|
+
@keys_mapped = true
|
347
|
+
#bind_key(?q, :myproc)
|
348
|
+
#bind_key(32, :myproc)
|
349
|
+
end
|
350
|
+
|
351
|
+
def _create_buttons
|
352
|
+
$log.debug "XXX: INSIDE create_buttons col_offset #{@col_offset} "
|
353
|
+
v = Variable.new
|
354
|
+
r = @button_row # @row + 1
|
355
|
+
col = @col + @col_offset
|
356
|
+
@tabs.each_with_index { |t, i|
|
357
|
+
txt = t.text
|
358
|
+
@buttons << TabButton.new(nil) do
|
359
|
+
variable v
|
360
|
+
text txt
|
361
|
+
name txt
|
362
|
+
#value txt
|
363
|
+
row r
|
364
|
+
col col
|
365
|
+
surround_chars ['','']
|
366
|
+
selected_background 'green'
|
367
|
+
selected_foreground 'white'
|
368
|
+
|
369
|
+
end
|
370
|
+
b = @buttons.last
|
371
|
+
b.command do
|
372
|
+
set_current_tab i
|
373
|
+
end
|
374
|
+
b.form = @form
|
375
|
+
b.override_graphic @graphic
|
376
|
+
col += txt.length + @button_gap
|
377
|
+
}
|
378
|
+
end # _create_buttons
|
379
|
+
private
|
380
|
+
def print_borders
|
381
|
+
width = @width
|
382
|
+
height = @height-1
|
383
|
+
window = @graphic
|
384
|
+
startcol = @col
|
385
|
+
startrow = @row
|
386
|
+
@color_pair = get_color($datacolor)
|
387
|
+
$log.debug "NTP #{name}: window.print_border #{startrow}, #{startcol} , h:#{height}, w:#{width} , @color_pair, @attr "
|
388
|
+
window.print_border startrow, startcol, height, width, @color_pair, @attr
|
389
|
+
print_title
|
390
|
+
end
|
391
|
+
def print_separator1
|
392
|
+
|
393
|
+
width = @width
|
394
|
+
height = @height-1
|
395
|
+
window = @graphic
|
396
|
+
startcol = @col
|
397
|
+
startrow = @row
|
398
|
+
@color_pair = get_color($datacolor)
|
399
|
+
r = @separator_row
|
400
|
+
c = @col + @col_offset
|
401
|
+
|
402
|
+
urcorner = []
|
403
|
+
#window.printstring r, c, '-' * (@width-2), @color_pair, @attr
|
404
|
+
window.mvwhline( r, @col+1, Ncurses::ACS_HLINE, @width-2)
|
405
|
+
@buttons.each_with_index do |b, i|
|
406
|
+
l = b.text.length
|
407
|
+
if b.selected?
|
408
|
+
if false #c == @col + @col_offset
|
409
|
+
cc = c
|
410
|
+
ll = l+1
|
411
|
+
else
|
412
|
+
cc = c-1
|
413
|
+
ll = l+2
|
414
|
+
end
|
415
|
+
#rr = r -1 #unless rr == @col
|
416
|
+
window.printstring r, cc, " "*ll, @color_pair, @attr
|
417
|
+
#window.printstring r, cc-1, FFI::NCurses::ACS_HLINE.chr*ll, @color_pair, @attr
|
418
|
+
#window.printstring r-2, cc, FFI::NCurses::ACS_HLINE.chr*ll, @color_pair, @attr
|
419
|
+
window.mvwaddch r, cc-1, FFI::NCurses::ACS_LRCORNER unless cc-1 <= @col
|
420
|
+
window.mvwaddch r, c+l+1, FFI::NCurses::ACS_LLCORNER
|
421
|
+
else
|
422
|
+
window.mvwaddch r, c+l+1, FFI::NCurses::ACS_BTEE
|
423
|
+
end
|
424
|
+
|
425
|
+
#window.printstring r-2, c, FFI::NCurses::ACS_HLINE*l, @color_pair, @attr
|
426
|
+
#tt = b.text
|
427
|
+
#window.printstring r, c, tt, @color_pair, @attr
|
428
|
+
c += l + 1
|
429
|
+
#window.mvwaddch r, c, '+'.ord
|
430
|
+
window.mvwaddch r-1, c, FFI::NCurses::ACS_VLINE
|
431
|
+
window.mvwaddch r-2, c, FFI::NCurses::ACS_URCORNER #ACS_TTEE
|
432
|
+
#window.mvwaddch r-2, c+1, '/'.ord
|
433
|
+
urcorner << c
|
434
|
+
c+=@button_gap
|
435
|
+
end
|
436
|
+
window.mvwhline( @separator_row0, @col + 1, Ncurses::ACS_HLINE, c-@col-1-@button_gap)
|
437
|
+
window.mvwhline( @separator_row2, @col + 1, Ncurses::ACS_HLINE, @width-2)
|
438
|
+
urcorner.each do |c|
|
439
|
+
window.mvwaddch r-2, c, FFI::NCurses::ACS_URCORNER #ACS_TTEE
|
440
|
+
end
|
441
|
+
end
|
442
|
+
def print_title
|
443
|
+
return unless @title
|
444
|
+
_title = @title
|
445
|
+
if @title.length > @width - 2
|
446
|
+
_title = @title[0..@width-2]
|
447
|
+
end
|
448
|
+
@graphic.printstring( @row, @col+(@width-_title.length)/2, _title,
|
449
|
+
@color_pair, @title_attrib) unless @title.nil?
|
450
|
+
end
|
451
|
+
|
452
|
+
#
|
453
|
+
# create the buttons at the bottom OK/ APPLY/ CANCEL
|
454
|
+
|
455
|
+
def create_action_buttons
|
456
|
+
return unless @button_type
|
457
|
+
case @button_type.to_s.downcase
|
458
|
+
when "ok"
|
459
|
+
make_buttons ["&OK"]
|
460
|
+
when "ok_cancel" #, "input", "list", "field_list"
|
461
|
+
make_buttons %w[&OK &Cancel]
|
462
|
+
when "ok_apply_cancel" #, "input", "list", "field_list"
|
463
|
+
make_buttons %w[&OK &Apply &Cancel]
|
464
|
+
when "yes_no"
|
465
|
+
make_buttons %w[&Yes &No]
|
466
|
+
when "yes_no_cancel"
|
467
|
+
make_buttons ["&Yes", "&No", "&Cancel"]
|
468
|
+
when "custom"
|
469
|
+
raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
|
470
|
+
make_buttons @buttons
|
471
|
+
else
|
472
|
+
$log.warn "No buttontype passed for creating tabbedpane. Not creating any"
|
473
|
+
#make_buttons ["&OK"]
|
474
|
+
end
|
475
|
+
end
|
476
|
+
def make_buttons names
|
477
|
+
@action_buttons = []
|
478
|
+
$log.debug "XXX: came to NTP make buttons FORM= #{@form.name} names #{names} "
|
479
|
+
total = names.inject(0) {|total, item| total + item.length + 4}
|
480
|
+
bcol = center_column total
|
481
|
+
|
482
|
+
# this craps out when height is zero
|
483
|
+
brow = @row + @height-2
|
484
|
+
brow = FFI::NCurses.LINES-2 if brow < 0
|
485
|
+
$log.debug "XXX: putting buttons :on #{brow} : #{@row} , #{@height} "
|
486
|
+
button_ct=0
|
487
|
+
tpp = self
|
488
|
+
names.each_with_index do |bname, ix|
|
489
|
+
text = bname
|
490
|
+
#underline = @underlines[ix] if !@underlines.nil?
|
491
|
+
|
492
|
+
button = Button.new nil do
|
493
|
+
text text
|
494
|
+
name bname
|
495
|
+
row brow
|
496
|
+
col bcol
|
497
|
+
#underline underline
|
498
|
+
highlight_background $reversecolor
|
499
|
+
color $datacolor
|
500
|
+
bgcolor $datacolor
|
501
|
+
end
|
502
|
+
@action_buttons << button
|
503
|
+
button.form = @form
|
504
|
+
button.override_graphic @graphic
|
505
|
+
index = button_ct
|
506
|
+
tpp = self
|
507
|
+
button.command { |form| @selected_index = index; @stop = true;
|
508
|
+
# ActionEvent has source event and action_command
|
509
|
+
fire_handler :PRESS, ActionEvent.new(tpp, index, button.text)
|
510
|
+
#throw(:close, @selected_index)
|
511
|
+
}
|
512
|
+
button_ct += 1
|
513
|
+
bcol += text.length+6
|
514
|
+
end
|
515
|
+
end
|
516
|
+
def center_column textlen
|
517
|
+
width = @col + @width
|
518
|
+
return (width-textlen)/2
|
519
|
+
end
|
520
|
+
|
521
|
+
## ADD ABOVE
|
522
|
+
end # class
|
523
|
+
|
524
|
+
class Tab
|
525
|
+
attr_accessor :text
|
526
|
+
attr_reader :config
|
527
|
+
attr_reader :items
|
528
|
+
attr_accessor :parent_component
|
529
|
+
attr_accessor :index
|
530
|
+
attr_accessor :button # so you can set an event on it 2011-10-4
|
531
|
+
attr_accessor :row_offset
|
532
|
+
attr_accessor :col_offset
|
533
|
+
def initialize text, parent_component, aconfig={}, &block
|
534
|
+
@text = text
|
535
|
+
@items = []
|
536
|
+
@config = aconfig
|
537
|
+
@parent_component = parent_component
|
538
|
+
@row_offset ||= 2
|
539
|
+
@col_offset ||= 2
|
540
|
+
@config.each_pair { |k,v| variable_set(k,v) }
|
541
|
+
instance_eval &block if block_given?
|
542
|
+
end
|
543
|
+
def item widget
|
544
|
+
widget.form = @parent_component.form
|
545
|
+
widget.override_graphic @parent_component.form.window
|
546
|
+
# these will fail if TP put inside some other container. NOTE
|
547
|
+
widget.row ||= 0
|
548
|
+
widget.col ||= 0
|
549
|
+
# If we knew it was only widget we could expand it
|
550
|
+
if widget.kind_of?(RubyCurses::Container) #|| widget.respond_to?(:width)
|
551
|
+
widget.width ||= @parent_component.width-3
|
552
|
+
end
|
553
|
+
# Darn ! this was setting Label to fully height
|
554
|
+
if widget.kind_of?(RubyCurses::Container) #|| widget.respond_to?(:height)
|
555
|
+
widget.height ||= @parent_component.height-3
|
556
|
+
end
|
557
|
+
# i don't know button_offset as yet
|
558
|
+
widget.row += @row_offset + @parent_component.row + 1
|
559
|
+
widget.col += @col_offset + @parent_component.col
|
560
|
+
@items << widget
|
561
|
+
end
|
562
|
+
end # class tab
|
563
|
+
class TabButton < RadioButton
|
564
|
+
attr_accessor :display_tab_on_traversal
|
565
|
+
def getvalue_for_paint
|
566
|
+
@text
|
567
|
+
end
|
568
|
+
def selected?
|
569
|
+
@variable.value == @value
|
570
|
+
end
|
571
|
+
|
572
|
+
end
|
573
|
+
|
574
|
+
end # module
|
575
|
+
if __FILE__ == $PROGRAM_NAME
|
576
|
+
require 'rbcurse/core/util/app'
|
577
|
+
require 'rbcurse/core/widgets/rcontainer'
|
578
|
+
App.new do
|
579
|
+
#r = Container.new nil, :row => 1, :col => 2, :width => 40, :height => 10, :title => "A container"
|
580
|
+
r = Container.new nil, :suppress_borders => true
|
581
|
+
f1 = field "name", :maxlen => 20, :display_length => 20, :bgcolor => :white,
|
582
|
+
:color => :black, :text => "abc", :label => ' Name: '
|
583
|
+
f2 = field "email", :display_length => 20, :bgcolor => :white,
|
584
|
+
:color => :blue, :text => "me@google.com", :label => 'Email: '
|
585
|
+
f3 = radio :group => :grp, :text => "red", :value => "RED", :color => :red
|
586
|
+
f4 = radio :group => :grp, :text => "blue", :value => "BLUE", :color => :blue
|
587
|
+
f5 = radio :group => :grp, :text => "green", :value => "GREEN", :color => :green
|
588
|
+
r.add(f1)
|
589
|
+
r.add(f2)
|
590
|
+
r.add(f3,f4,f5)
|
591
|
+
TabbedPane.new @form, :row => 3, :col => 5, :width => 60, :height => 20 do
|
592
|
+
title "User Setup"
|
593
|
+
button_type :ok_apply_cancel
|
594
|
+
tab "&Profile" do
|
595
|
+
item Field.new nil, :row => 2, :col => 2, :text => "enter your name", :label => ' Name: '
|
596
|
+
item Field.new nil, :row => 3, :col => 2, :text => "enter your email", :label => 'Email: '
|
597
|
+
end
|
598
|
+
tab "&Settings" do
|
599
|
+
item CheckBox.new nil, :row => 2, :col => 2, :text => "Use HTTPS", :mnemonic => 'u'
|
600
|
+
item CheckBox.new nil, :row => 3, :col => 2, :text => "Quit with confirm", :mnemonic => 'q'
|
601
|
+
end
|
602
|
+
tab "&Term" do
|
603
|
+
radio = Variable.new
|
604
|
+
item RadioButton.new nil, :row => 2, :col => 2, :text => "&xterm", :value => "xterm", :variable => radio
|
605
|
+
item RadioButton.new nil, :row => 3, :col => 2, :text => "sc&reen", :value => "screen", :variable => radio
|
606
|
+
radio.update_command() {|rb| ENV['TERM']=rb.value }
|
607
|
+
end
|
608
|
+
tab "Conta&iner" do
|
609
|
+
item r
|
610
|
+
end
|
611
|
+
|
612
|
+
end
|
613
|
+
end # app
|
614
|
+
|
615
|
+
end
|