rbcurse 1.4.1 → 1.5.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +31 -0
- data/README.markdown +69 -11
- data/VERSION +1 -1
- data/lib/rbcurse.rb +5 -5
- metadata +10 -198
- data/Makefile +0 -21
- data/Manifest.txt +0 -91
- data/TODO +0 -372
- data/TODO2.txt +0 -118
- data/examples/README.txt +0 -67
- data/examples/abasiclist.rb +0 -33
- data/examples/alpmenu.rb +0 -42
- data/examples/app.rb +0 -859
- data/examples/app.sample +0 -10
- data/examples/appdirtree.rb +0 -75
- data/examples/appemail.rb +0 -191
- data/examples/appemaillb.rb +0 -308
- data/examples/appgcompose.rb +0 -315
- data/examples/atree.rb +0 -64
- data/examples/common/file.rb +0 -40
- data/examples/common/rmail.rb +0 -257
- data/examples/data.txt +0 -683
- data/examples/data/README.markdown +0 -9
- data/examples/data/brew.txt +0 -38
- data/examples/data/color.2 +0 -37
- data/examples/data/gemlist.txt +0 -60
- data/examples/data/lotr.txt +0 -12
- data/examples/data/ports.txt +0 -136
- data/examples/data/tasks.txt +0 -27
- data/examples/data/todocsv.csv +0 -28
- data/examples/data/unix1.txt +0 -21
- data/examples/data/unix2.txt +0 -11
- data/examples/dbdemo.rb +0 -495
- data/examples/deprecated/appgmail.rb +0 -952
- data/examples/deprecated/splitp.rb +0 -56
- data/examples/deprecated/testscrolllb.rb +0 -86
- data/examples/deprecated/testscrollp.rb +0 -88
- data/examples/deprecated/testscrollta.rb +0 -80
- data/examples/deprecated/testscrolltable.rb +0 -165
- data/examples/deprecated/testsplit.rb +0 -87
- data/examples/deprecated/testsplit2.rb +0 -123
- data/examples/deprecated/testsplit3.rb +0 -215
- data/examples/deprecated/testsplit3_1.rb +0 -244
- data/examples/deprecated/testsplit3a.rb +0 -215
- data/examples/deprecated/testsplit3b.rb +0 -237
- data/examples/deprecated/testsplitta.rb +0 -148
- data/examples/deprecated/testsplittv.rb +0 -142
- data/examples/deprecated/testsplittvv.rb +0 -144
- data/examples/deprecated/testtpane.rb +0 -215
- data/examples/deprecated/testtpane2.rb +0 -145
- data/examples/deprecated/testtpanetable.rb +0 -203
- data/examples/dirtree.rb +0 -88
- data/examples/experimental/resultsetdemo.rb +0 -280
- data/examples/experimental/testmform.rb +0 -35
- data/examples/experimental/testscroller.rb +0 -117
- data/examples/experimental/teststackflow.rb +0 -111
- data/examples/menu1.rb +0 -112
- data/examples/multispl.rb +0 -86
- data/examples/newmessagebox.rb +0 -130
- data/examples/newtabbedwindow.rb +0 -100
- data/examples/newtesttabp.rb +0 -121
- data/examples/qdfilechooser.rb +0 -68
- data/examples/rfe.rb +0 -1195
- data/examples/rfe_renderer.rb +0 -121
- data/examples/sqlc.rb +0 -454
- data/examples/sqlm.rb +0 -437
- data/examples/sqlt.rb +0 -408
- data/examples/status.txt +0 -68
- data/examples/table1.rb +0 -24
- data/examples/term2.rb +0 -84
- data/examples/test1.rb +0 -239
- data/examples/test2.rb +0 -674
- data/examples/testapp.rb +0 -44
- data/examples/testapp2.rb +0 -58
- data/examples/testchars.rb +0 -137
- data/examples/testcombo.rb +0 -91
- data/examples/testkeypress.rb +0 -66
- data/examples/testlistbox.rb +0 -113
- data/examples/testmenu.rb +0 -101
- data/examples/testmulticomp.rb +0 -70
- data/examples/testmulticontainer.rb +0 -94
- data/examples/testmultispl.rb +0 -199
- data/examples/testree.rb +0 -106
- data/examples/testtable.rb +0 -263
- data/examples/testtabp.rb +0 -107
- data/examples/testtodo.rb +0 -584
- data/examples/testvimsplit.rb +0 -112
- data/examples/testwsshortcuts.rb +0 -64
- data/examples/testwsshortcuts2.rb +0 -126
- data/examples/todo.db +0 -0
- data/examples/todo.yml +0 -191
- data/examples/viewtodo.rb +0 -574
- data/lib/rbcurse/action.rb +0 -40
- data/lib/rbcurse/app.rb +0 -1374
- data/lib/rbcurse/applicationheader.rb +0 -102
- data/lib/rbcurse/celleditor.rb +0 -112
- data/lib/rbcurse/checkboxcellrenderer.rb +0 -57
- data/lib/rbcurse/colormap.rb +0 -159
- data/lib/rbcurse/comboboxcellrenderer.rb +0 -30
- data/lib/rbcurse/common/ansiparser.rb +0 -117
- data/lib/rbcurse/common/appmethods.rb +0 -112
- data/lib/rbcurse/common/basestack.rb +0 -407
- data/lib/rbcurse/common/bordertitle.rb +0 -41
- data/lib/rbcurse/common/chunk.rb +0 -177
- data/lib/rbcurse/common/colorparser.rb +0 -71
- data/lib/rbcurse/common/keydefs.rb +0 -30
- data/lib/rbcurse/common/widgetshortcuts.rb +0 -302
- data/lib/rbcurse/defaultlistselectionmodel.rb +0 -79
- data/lib/rbcurse/deprecated/README.markdown +0 -12
- data/lib/rbcurse/deprecated/rscrollpane.rb +0 -512
- data/lib/rbcurse/deprecated/rsplitpane.rb +0 -894
- data/lib/rbcurse/deprecated/rsplitpane2.rb +0 -1009
- data/lib/rbcurse/deprecated/rviewport.rb +0 -204
- data/lib/rbcurse/experimental/README.markdown +0 -14
- data/lib/rbcurse/experimental/resultsettextview.rb +0 -585
- data/lib/rbcurse/experimental/stackflow.rb +0 -478
- data/lib/rbcurse/extras/bottomline.rb +0 -1850
- data/lib/rbcurse/extras/box.rb +0 -58
- data/lib/rbcurse/extras/directorylist.rb +0 -467
- data/lib/rbcurse/extras/directorytree.rb +0 -69
- data/lib/rbcurse/extras/divider.rb +0 -310
- data/lib/rbcurse/extras/focusmanager.rb +0 -31
- data/lib/rbcurse/extras/horizlist.rb +0 -203
- data/lib/rbcurse/extras/listselectable.rb +0 -264
- data/lib/rbcurse/extras/masterdetail.rb +0 -166
- data/lib/rbcurse/extras/menutree.rb +0 -63
- data/lib/rbcurse/extras/multiform.rb +0 -330
- data/lib/rbcurse/extras/multilinelabel.rb +0 -142
- data/lib/rbcurse/extras/newmessagebox.rb +0 -328
- data/lib/rbcurse/extras/newtabbedpane.rb +0 -612
- data/lib/rbcurse/extras/newtabbedwindow.rb +0 -68
- data/lib/rbcurse/extras/padreader.rb +0 -189
- data/lib/rbcurse/extras/rcomboedit.rb +0 -256
- data/lib/rbcurse/extras/resultsetbrowser.rb +0 -281
- data/lib/rbcurse/extras/rlink.rb +0 -27
- data/lib/rbcurse/extras/rmenulink.rb +0 -21
- data/lib/rbcurse/extras/scrollbar.rb +0 -143
- data/lib/rbcurse/extras/statusline.rb +0 -94
- data/lib/rbcurse/extras/stdscrwindow.rb +0 -309
- data/lib/rbcurse/extras/tableextended.rb +0 -40
- data/lib/rbcurse/extras/tabular.rb +0 -264
- data/lib/rbcurse/extras/tabularwidget.rb +0 -1150
- data/lib/rbcurse/extras/textpad.rb +0 -516
- data/lib/rbcurse/extras/viewer.rb +0 -136
- data/lib/rbcurse/io.rb +0 -850
- data/lib/rbcurse/keylabelprinter.rb +0 -178
- data/lib/rbcurse/listcellrenderer.rb +0 -140
- data/lib/rbcurse/listeditable.rb +0 -310
- data/lib/rbcurse/listkeys.rb +0 -37
- data/lib/rbcurse/listscrollable.rb +0 -564
- data/lib/rbcurse/listselectable.rb +0 -142
- data/lib/rbcurse/mapper.rb +0 -130
- data/lib/rbcurse/orderedhash.rb +0 -77
- data/lib/rbcurse/ractionevent.rb +0 -67
- data/lib/rbcurse/rbasiclistbox.rb +0 -768
- data/lib/rbcurse/rchangeevent.rb +0 -27
- data/lib/rbcurse/rcombo.rb +0 -238
- data/lib/rbcurse/rcommandwindow.rb +0 -587
- data/lib/rbcurse/rcontainer.rb +0 -415
- data/lib/rbcurse/rdialogs.rb +0 -451
- data/lib/rbcurse/rinputdataevent.rb +0 -47
- data/lib/rbcurse/rlistbox.rb +0 -1196
- data/lib/rbcurse/rmenu.rb +0 -939
- data/lib/rbcurse/rmessagebox.rb +0 -348
- data/lib/rbcurse/rmulticontainer.rb +0 -304
- data/lib/rbcurse/rmultisplit.rb +0 -722
- data/lib/rbcurse/rmultitextview.rb +0 -306
- data/lib/rbcurse/rpopupmenu.rb +0 -755
- data/lib/rbcurse/rprogress.rb +0 -118
- data/lib/rbcurse/rscrollform.rb +0 -418
- data/lib/rbcurse/rtabbedpane.rb +0 -1158
- data/lib/rbcurse/rtabbedwindow.rb +0 -167
- data/lib/rbcurse/rtable.rb +0 -1718
- data/lib/rbcurse/rtextarea.rb +0 -920
- data/lib/rbcurse/rtextview.rb +0 -761
- data/lib/rbcurse/rtree.rb +0 -780
- data/lib/rbcurse/rvimsplit.rb +0 -763
- data/lib/rbcurse/rwidget.rb +0 -2915
- data/lib/rbcurse/scrollable.rb +0 -301
- data/lib/rbcurse/table/tablecellrenderer.rb +0 -86
- data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -98
- data/lib/rbcurse/tree/treecellrenderer.rb +0 -150
- data/lib/rbcurse/tree/treemodel.rb +0 -428
- data/lib/rbcurse/undomanager.rb +0 -188
- data/lib/rbcurse/vieditable.rb +0 -144
- data/lib/ver/keyboard.rb +0 -150
- data/lib/ver/keyboard2.rb +0 -170
- data/lib/ver/ncurses.rb +0 -218
- data/lib/ver/panel.rb +0 -162
- data/lib/ver/rpad.rb +0 -375
- data/lib/ver/window.rb +0 -882
- data/test/test_rbcurse.rb +0 -0
data/lib/rbcurse/rcontainer.rb
DELETED
@@ -1,415 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
* Name: A container that manages components placed in it but
|
3
|
-
is not a form. Thus it can be safely placed as a widget
|
4
|
-
without all the complicatinos of a form embedded inside another.
|
5
|
-
NOTE: Still experimental
|
6
|
-
* Description
|
7
|
-
* Author: rkumar (http://github.com/rkumar/rbcurse/)
|
8
|
-
* Date: 21.10.11 - 00:29
|
9
|
-
* License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
10
|
-
|
11
|
-
* Last update: 23.10.11 - 00:29
|
12
|
-
== CHANGES
|
13
|
-
Focusables so we don't focus on label
|
14
|
-
== TODO
|
15
|
-
How to put blank lines in stack - use a blank label
|
16
|
-
|
17
|
-
- The contaomers and multis need to do their own on_enter and on_leave
|
18
|
-
management, they cannot rely on some other container doing it.
|
19
|
-
We can only rely on handle_key being called. HK should determine
|
20
|
-
whether any set_form row etc needs to be done.
|
21
|
-
- Should have its own stack and flow
|
22
|
-
=end
|
23
|
-
|
24
|
-
require 'rbcurse'
|
25
|
-
|
26
|
-
include RubyCurses
|
27
|
-
module RubyCurses
|
28
|
-
extend self
|
29
|
-
|
30
|
-
# This is an attempt at having a container which can contain multiple
|
31
|
-
# widgets without being a form itself. Having forms within forms
|
32
|
-
# complicates code too much, esp cursor positioning. e.g. tabbedpane
|
33
|
-
|
34
|
-
class Container < Widget
|
35
|
-
|
36
|
-
dsl_accessor :suppress_borders #to_print_borders
|
37
|
-
dsl_accessor :border_attrib, :border_color
|
38
|
-
dsl_accessor :title #set this on top
|
39
|
-
dsl_accessor :title_attrib #bold, reverse, normal
|
40
|
-
# should container stack objects ignoring users row col
|
41
|
-
# this is esp needed since App sets row and col which is too early
|
42
|
-
# This is now the default value, till i can redo things
|
43
|
-
#dsl_accessor :stack
|
44
|
-
dsl_accessor :positioning # absolute, relative, stack
|
45
|
-
attr_reader :current_component
|
46
|
-
|
47
|
-
def initialize form=nil, config={}, &block
|
48
|
-
@suppress_borders = false
|
49
|
-
@row_offset = @col_offset = 1
|
50
|
-
@_events ||= []
|
51
|
-
@stack = true
|
52
|
-
@positioning = :stack
|
53
|
-
super
|
54
|
-
@focusable = true
|
55
|
-
@editable = false
|
56
|
-
@components = [] # all components
|
57
|
-
@focusables = [] # focusable components, makes checks easier
|
58
|
-
|
59
|
-
init_vars
|
60
|
-
end
|
61
|
-
def init_vars
|
62
|
-
@repaint_required = true
|
63
|
-
@row_offset = @col_offset = 0 if @suppress_borders # FIXME supposed to use this !!
|
64
|
-
|
65
|
-
@internal_width = 2
|
66
|
-
@internal_width = 1 if @suppress_borders
|
67
|
-
@name ||= "AContainer"
|
68
|
-
@first_time = true
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
# NOTE: since we are handling the traversal, we delink the object from any
|
73
|
-
# form's widgets array that might have been added. Whenever a form is available,
|
74
|
-
# we set it (without adding widget to it) so it can print using the form's window.
|
75
|
-
#
|
76
|
-
# @param [Widget] to add
|
77
|
-
def add *items
|
78
|
-
items.each do |c|
|
79
|
-
raise ArgumentError, "Nil component passed to add" unless c
|
80
|
-
if c.is_a? Widget
|
81
|
-
if c.form && c.form != @form
|
82
|
-
$log.debug " removing widget VIMSPLIT #{c.class} wr: #{c.row} row:#{@row} ht:#{@height} "
|
83
|
-
c.form.remove_widget c
|
84
|
-
c.form = nil
|
85
|
-
# or should i just stack them myself and screw what you've asked for
|
86
|
-
end
|
87
|
-
# take it out of form's control. We will control it.
|
88
|
-
if c.form
|
89
|
-
c.form.remove_widget c
|
90
|
-
end
|
91
|
-
# shoot, what if at this point the container does not have a form
|
92
|
-
attach_form c if @form
|
93
|
-
end
|
94
|
-
# most likely if you have created both container and widgets
|
95
|
-
# inside app, it would have given row after container
|
96
|
-
|
97
|
-
@components << c
|
98
|
-
if c.focusable
|
99
|
-
@focusables << c
|
100
|
-
@current_component ||= c # only the first else cursor falls on last on enter
|
101
|
-
end
|
102
|
-
|
103
|
-
end # items each
|
104
|
-
self
|
105
|
-
end
|
106
|
-
|
107
|
-
# When we get a form, we silently attach it to this object, without the form
|
108
|
-
# knowing. We don't want form managing this object.
|
109
|
-
def attach_form c
|
110
|
-
c.form = @form
|
111
|
-
c.override_graphic @graphic
|
112
|
-
c.parent_component = self
|
113
|
-
end
|
114
|
-
alias :add_widget :add
|
115
|
-
def widgets; @components; end
|
116
|
-
# what of by_name
|
117
|
-
|
118
|
-
|
119
|
-
# correct coordinates of comp esp if App has stacked them after this
|
120
|
-
# container
|
121
|
-
# It is best to use the simple stack feature. The rest could change at any time
|
122
|
-
# and is quite arbitrary. Some folks may set absolute locations if container
|
123
|
-
# is directly on a form, others may set relative locations if it is inside a
|
124
|
-
# tabbed pane or other container. Thus, stacks are best
|
125
|
-
def correct_component c
|
126
|
-
raise "Form is still not set in Container" unless @form
|
127
|
-
attach_form(c) unless c.form
|
128
|
-
@last_row ||= @row + 1
|
129
|
-
inset = 2
|
130
|
-
# 2011-10-20 current default behaviour is to stack
|
131
|
-
if @positioning == :stack
|
132
|
-
c.row = @last_row
|
133
|
-
c.col = @col + inset
|
134
|
-
|
135
|
-
# do not advance row, save col for next row
|
136
|
-
@last_row += 1
|
137
|
-
elsif @positioning == :relative # UNTESTED NOTE
|
138
|
-
if (c.row || 0) <= 0
|
139
|
-
$log.warn "c.row in CONTAINER is #{c.row} "
|
140
|
-
c.row = @last_row
|
141
|
-
@last_row += 1
|
142
|
-
elsif c.row > @row + @height -1
|
143
|
-
$log.warn "c.row in CONTAINER exceeds container. #{c.row} "
|
144
|
-
c.row -= @height - @row_offset
|
145
|
-
else
|
146
|
-
# this is where it should come
|
147
|
-
c.row += @row + @row_offset
|
148
|
-
@last_row = c.row + 1
|
149
|
-
end
|
150
|
-
if (c.col || 0) <= 0
|
151
|
-
c.col = @col + inset + @col_offset
|
152
|
-
elsif c.col > @col + @width -1
|
153
|
-
c.col -= @width
|
154
|
-
elsif c.col == @col
|
155
|
-
c.col += @col_offset + inset
|
156
|
-
else #f c.col < @col
|
157
|
-
c.col += @col+@col_offset
|
158
|
-
end
|
159
|
-
$log.debug "XXX: CORRECT #{c.name} r:#{c.row} c:#{c.col} "
|
160
|
-
end
|
161
|
-
@first_time = false
|
162
|
-
end
|
163
|
-
def check_component c
|
164
|
-
raise "row is less than container #{c.row} #{@row} " if c.row <= @row
|
165
|
-
raise "col is less than container #{c.col} #{@col} " if c.col <= @col
|
166
|
-
end
|
167
|
-
|
168
|
-
public
|
169
|
-
# repaint object
|
170
|
-
# called by Form, and sometimes parent component (if not form).
|
171
|
-
def repaint
|
172
|
-
my_win = @form ? @form.window : @target_window
|
173
|
-
@graphic = my_win unless @graphic
|
174
|
-
raise " #{@name} NO GRAPHIC set as yet CONTAINER paint " unless @graphic
|
175
|
-
@components.each { |e| correct_component e } if @first_time
|
176
|
-
#@components.each { |e| check_component e } # seeme one if printing out
|
177
|
-
|
178
|
-
#return unless @repaint_required
|
179
|
-
|
180
|
-
# if some major change has happened then repaint everything
|
181
|
-
if @repaint_required
|
182
|
-
$log.debug " VIM repaint graphic #{@graphic} "
|
183
|
-
print_borders unless @suppress_borders # do this once only, unless everything changes
|
184
|
-
@components.each { |e| e.repaint_all(true); e.repaint }
|
185
|
-
else
|
186
|
-
@components.each { |e| e.repaint }
|
187
|
-
end # if repaint_required
|
188
|
-
|
189
|
-
@repaint_required = false
|
190
|
-
end
|
191
|
-
|
192
|
-
private
|
193
|
-
def print_borders
|
194
|
-
width = @width
|
195
|
-
height = @height-1 # 2010-01-04 15:30 BUFFERED HEIGHT
|
196
|
-
window = @graphic # 2010-01-04 12:37 BUFFERED
|
197
|
-
startcol = @col
|
198
|
-
startrow = @row
|
199
|
-
@color_pair = get_color($datacolor)
|
200
|
-
#$log.debug "rlistb #{name}: window.print_border #{startrow}, #{startcol} , h:#{height}, w:#{width} , @color_pair, @attr "
|
201
|
-
window.print_border startrow, startcol, height, width, @color_pair, @attr
|
202
|
-
print_title
|
203
|
-
end
|
204
|
-
def print_title
|
205
|
-
$log.debug "CONTAINER PRINTING TITLE at #{row} #{col} "
|
206
|
-
@graphic.printstring( @row, @col+(@width-@title.length)/2, @title, @color_pair, @title_attrib) unless @title.nil?
|
207
|
-
end
|
208
|
-
|
209
|
-
public
|
210
|
-
# called by parent or form, otherwise its private
|
211
|
-
def handle_key ch
|
212
|
-
$log.debug " CONTAINER handle_key #{ch} "
|
213
|
-
return if @components.empty?
|
214
|
-
_multiplier = ($multiplier == 0 ? 1 : $multiplier )
|
215
|
-
|
216
|
-
# should this go here 2011-10-19
|
217
|
-
unless @_entered
|
218
|
-
$log.warn "XXX WARN: calling ON_ENTER since in this situation it was not called"
|
219
|
-
on_enter
|
220
|
-
end
|
221
|
-
if ch == KEY_TAB
|
222
|
-
$log.debug "CONTAINER GOTO NEXT TAB"
|
223
|
-
return goto_next_component
|
224
|
-
elsif ch == KEY_BTAB
|
225
|
-
return goto_prev_component
|
226
|
-
end
|
227
|
-
comp = @current_component
|
228
|
-
$log.debug " CONTAINER handle_key #{ch}: #{comp}"
|
229
|
-
if comp
|
230
|
-
ret = comp.handle_key(ch)
|
231
|
-
$log.debug " CONTAINER handle_key#{ch}: #{comp} returned #{ret} "
|
232
|
-
if ret != :UNHANDLED
|
233
|
-
comp.repaint # NOTE: if we don;t do this, then it won't get repainted. I will have to repaint ALL
|
234
|
-
# in repaint of this.
|
235
|
-
return ret
|
236
|
-
end
|
237
|
-
$log.debug "XXX CONTAINER key unhandled by comp #{comp.name} "
|
238
|
-
else
|
239
|
-
$log.warn "XXX CONTAINER key unhandled NULL comp"
|
240
|
-
end
|
241
|
-
case ch
|
242
|
-
when ?\C-c.getbyte(0)
|
243
|
-
$multiplier = 0
|
244
|
-
return 0
|
245
|
-
when ?0.getbyte(0)..?9.getbyte(0)
|
246
|
-
$log.debug " VIM coming here to set multiplier #{$multiplier} "
|
247
|
-
$multiplier *= 10 ; $multiplier += (ch-48)
|
248
|
-
return 0
|
249
|
-
end
|
250
|
-
ret = process_key ch, self
|
251
|
-
# allow user to map left and right if he wants
|
252
|
-
if ret == :UNHANDLED
|
253
|
-
case ch
|
254
|
-
when KEY_UP
|
255
|
-
# form will pick this up and do needful
|
256
|
-
return goto_prev_component #unless on_first_component?
|
257
|
-
when KEY_LEFT
|
258
|
-
# if i don't check for first component, key will go back to form,
|
259
|
-
# but not be processes. so focussed remain here, but be false.
|
260
|
-
# In case of returnign an unhandled TAB, on_leave will happen and cursor will move to
|
261
|
-
# previous component outside of this.
|
262
|
-
return goto_prev_component unless on_first_component?
|
263
|
-
when KEY_RIGHT
|
264
|
-
return goto_next_component #unless on_last_component?
|
265
|
-
when KEY_DOWN
|
266
|
-
return goto_next_component #unless on_last_component?
|
267
|
-
else
|
268
|
-
@_entered = false
|
269
|
-
return :UNHANDLED
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
$multiplier = 0
|
274
|
-
return 0
|
275
|
-
end
|
276
|
-
# Actually we should only go to current component if it accepted
|
277
|
-
# a key stroke. if user tabbed thru it, then no point going back to
|
278
|
-
# it. Go to first or last depending on TAB or BACKTAB otherwise.
|
279
|
-
# NOTE: if user comes in using DOWN or UP, last traversed component will get the focus
|
280
|
-
#
|
281
|
-
def on_enter
|
282
|
-
# if BTAB, the last comp XXX they must be focusable FIXME
|
283
|
-
if $current_key == KEY_BTAB || $current_key == KEY_UP
|
284
|
-
@current_component = @focusables.last
|
285
|
-
else
|
286
|
-
@current_component = @focusables.first
|
287
|
-
end
|
288
|
-
return unless @current_component
|
289
|
-
$log.debug " CONTAINER came to ON_ENTER #{@current_component} "
|
290
|
-
set_form_row
|
291
|
-
@_entered = true
|
292
|
-
end
|
293
|
-
# we cannot be sure that this will be called especially if this is embedded
|
294
|
-
# inside some other component
|
295
|
-
def on_leave
|
296
|
-
@_entered = false
|
297
|
-
super
|
298
|
-
end
|
299
|
-
def goto_next_component
|
300
|
-
if @current_component != nil
|
301
|
-
leave_current_component
|
302
|
-
if on_last_component?
|
303
|
-
#@_entered = false
|
304
|
-
return :UNHANDLED
|
305
|
-
end
|
306
|
-
@current_index = @focusables.index(@current_component)
|
307
|
-
index = @current_index + 1
|
308
|
-
f = @focusables[index]
|
309
|
-
if f
|
310
|
-
@current_index = index
|
311
|
-
@current_component = f
|
312
|
-
return set_form_row
|
313
|
-
end
|
314
|
-
end
|
315
|
-
@_entered = false
|
316
|
-
return :UNHANDLED
|
317
|
-
end
|
318
|
-
def goto_prev_component
|
319
|
-
if @current_component != nil
|
320
|
-
leave_current_component
|
321
|
-
if on_first_component?
|
322
|
-
@_entered = false
|
323
|
-
return :UNHANDLED
|
324
|
-
end
|
325
|
-
@current_index = @focusables.index(@current_component)
|
326
|
-
index = @current_index -= 1
|
327
|
-
f = @focusables[i]
|
328
|
-
if f
|
329
|
-
@current_index = index
|
330
|
-
@current_component = f
|
331
|
-
return set_form_row
|
332
|
-
end
|
333
|
-
end
|
334
|
-
return :UNHANDLED
|
335
|
-
end
|
336
|
-
# private
|
337
|
-
# XXX why are we calling 3 methods in a row, why not OE manages these 3
|
338
|
-
# There's double calling going on.
|
339
|
-
def set_form_row
|
340
|
-
return :UNHANDLED if @current_component.nil?
|
341
|
-
cc = @current_component
|
342
|
-
$log.debug "CONT #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} "
|
343
|
-
$log.debug " CONTAINER on enter sfr #{@current_component.name} #{@current_component} "
|
344
|
-
|
345
|
-
# bug caught here. we were printing a field before it had been set, so it printed out
|
346
|
-
@components.each { |e| correct_component e } if @first_time
|
347
|
-
@current_component.on_enter
|
348
|
-
@current_component.set_form_row # why was this missing in vimsplit. is it
|
349
|
-
$log.debug "CONT2 #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} "
|
350
|
-
# that on_enter does a set_form_row
|
351
|
-
@current_component.set_form_col # XXX
|
352
|
-
@current_component.repaint # OMG this could happen before we've set row and col
|
353
|
-
# XXX compo should do set_form_row and col if it has that
|
354
|
-
end
|
355
|
-
#
|
356
|
-
def set_form_col
|
357
|
-
return if @current_component.nil?
|
358
|
-
$log.debug " #{@name} CONTAINER EMPTY set_form_col calling sfc for #{@current_component.name} "
|
359
|
-
# already called from above.
|
360
|
-
#@current_component.set_form_col
|
361
|
-
end
|
362
|
-
# leave the component we are on.
|
363
|
-
# This should be followed by all containers, so that the on_leave action
|
364
|
-
# of earlier comp can be displayed, such as dimming components selections
|
365
|
-
def leave_current_component
|
366
|
-
@current_component.on_leave
|
367
|
-
# NOTE this is required, since repaint will just not happen otherwise
|
368
|
-
# Some components are erroneously repainting all, after setting this to true so it is
|
369
|
-
# working there.
|
370
|
-
@current_component.repaint_required true
|
371
|
-
$log.debug " after on_leave RCONT XXX #{@current_component.focussed} #{@current_component.name}"
|
372
|
-
@current_component.repaint
|
373
|
-
end
|
374
|
-
|
375
|
-
# is focus on first component FIXME check for focusable
|
376
|
-
def on_first_component?
|
377
|
-
@current_component == @focusables.first
|
378
|
-
end
|
379
|
-
# is focus on last component FIXME check for focusable
|
380
|
-
def on_last_component?
|
381
|
-
@current_component == @focusables.last
|
382
|
-
end
|
383
|
-
# set focus on given component
|
384
|
-
# Sometimes you have the handle to component, and you want to move focus to it
|
385
|
-
def goto_component comp
|
386
|
-
return if comp == @current_component
|
387
|
-
leave_current_component
|
388
|
-
@current_component = comp
|
389
|
-
set_form_row
|
390
|
-
end
|
391
|
-
|
392
|
-
# ADD HERE ABOVe
|
393
|
-
end # class
|
394
|
-
end # module
|
395
|
-
|
396
|
-
if __FILE__ == $PROGRAM_NAME
|
397
|
-
require 'rbcurse/app'
|
398
|
-
App.new do
|
399
|
-
f1 = field "name", :maxlen => 20, :display_length => 20, :bgcolor => :white,
|
400
|
-
:color => :black, :text => "abc", :label => " Name: ", :label_color_pair => @datacolor
|
401
|
-
f2 = field "email", :display_length => 20, :bgcolor => :white,
|
402
|
-
:color => :blue, :text => "me@google.com", :label => "Email: ", :label_color_pair => @datacolor
|
403
|
-
f3 = radio :group => :grp, :text => "red", :value => "RED", :color => :red
|
404
|
-
f4 = radio :group => :grp, :text => "blue", :value => "BLUE", :color => :blue
|
405
|
-
f5 = radio :group => :grp, :text => "green", :value => "GREEN", :color => :green
|
406
|
-
stack :margin_top => 2, :margin => 2 do
|
407
|
-
r = container :row => 1, :col => 2, :width => 80, :height => 20, :title => "A container"
|
408
|
-
r.add(f1)
|
409
|
-
r.add(f2)
|
410
|
-
r.add(f3,f4,f5)
|
411
|
-
sl = status_line
|
412
|
-
end # stack
|
413
|
-
|
414
|
-
end # app
|
415
|
-
end # if
|
data/lib/rbcurse/rdialogs.rb
DELETED
@@ -1,451 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
* Name: dialogs so user can do basic stuff in one line.
|
3
|
-
* Description:
|
4
|
-
* Author: rkumar
|
5
|
-
|
6
|
-
--------
|
7
|
-
* Date: 2008-12-30 12:22
|
8
|
-
* 2011-10-1 : moving print_error and print_status methods here as alternatives
|
9
|
-
to alert and confirm. Anyone who has included those will get these.
|
10
|
-
And this file is included in the base file.
|
11
|
-
|
12
|
-
Shucks, this file has no module. It's bare !
|
13
|
-
* License:
|
14
|
-
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
15
|
-
|
16
|
-
TODO:
|
17
|
-
Add one get_string(message, len, regex ...)
|
18
|
-
Add select_one (message, values, default)
|
19
|
-
=end
|
20
|
-
require 'logger'
|
21
|
-
require 'rbcurse/rwidget'
|
22
|
-
require 'rbcurse/rmessagebox'
|
23
|
-
|
24
|
-
##
|
25
|
-
# pops up a modal box with a message and an OK button.
|
26
|
-
# No return value.
|
27
|
-
# Usage:
|
28
|
-
# alert("You did not enter anything!")
|
29
|
-
# alert("You did not enter anything!", "title"=>"Wake Up")
|
30
|
-
# alert("You did not enter anything!", {"title"=>"Wake Up", "bgcolor"=>"blue", "color"=>"white"})
|
31
|
-
# block currently ignored. don't know what to do, can't pass it to MB since alread sending in a block
|
32
|
-
#
|
33
|
-
def alert text, config={}, &block
|
34
|
-
title = config['title'] || "Alert"
|
35
|
-
#instance_eval &block if block_given?
|
36
|
-
if text.is_a? RubyCurses::Variable # added 2011-09-20 incase variable passed
|
37
|
-
text = text.get_value
|
38
|
-
end
|
39
|
-
mb = RubyCurses::MessageBox.new nil, config do
|
40
|
-
title title
|
41
|
-
message text
|
42
|
-
button_type :ok
|
43
|
-
end
|
44
|
-
end
|
45
|
-
# confirms from user returning :YES or :NO
|
46
|
-
# Darn, should have returned boolean, now have to live with it.
|
47
|
-
def confirm text, config={}, &block
|
48
|
-
title = config['title'] || "Confirm"
|
49
|
-
#instance_eval &block if block_given?
|
50
|
-
mb = RubyCurses::MessageBox.new nil, config do
|
51
|
-
title title
|
52
|
-
message text
|
53
|
-
button_type :yes_no
|
54
|
-
end
|
55
|
-
return mb.selected_index == 0 ? :YES : :NO
|
56
|
-
end
|
57
|
-
|
58
|
-
##
|
59
|
-
# allows user entry of a string.
|
60
|
-
# In config you may pass Field related properties such as chars_allowed, valid_regex, values, etc.
|
61
|
-
def get_string(message, len=50, default="", config={})
|
62
|
-
|
63
|
-
config["input_config"] = {}
|
64
|
-
config["input_config"]["maxlen"] = len
|
65
|
-
config["maxlen"]=len
|
66
|
-
title = config["title"] || "Input required"
|
67
|
-
mb = RubyCurses::MessageBox.new nil, config do
|
68
|
-
title title
|
69
|
-
message message
|
70
|
-
type :input
|
71
|
-
button_type :ok
|
72
|
-
default_value default
|
73
|
-
end
|
74
|
-
return mb.input_value
|
75
|
-
end
|
76
|
-
|
77
|
-
##
|
78
|
-
# Added 2009-02-05 13:16
|
79
|
-
# get a string from user with some additional checkboxes and optionally supply default values
|
80
|
-
# Usage:
|
81
|
-
#sel, inp, hash = get_string_with_options("Enter a filter pattern", 20, "*", {"checkboxes" => ["case sensitive","reverse"], "checkbox_defaults"=>[true, false]})
|
82
|
-
# sel, inp, hash = get_string_with_options("Enter a filter pattern", 20, "*", {"checkboxes" => ["case sensitive","reverse"]})
|
83
|
-
# $log.debug " POPUP: #{sel}: #{inp}, #{hash['case sensitive']}, #{hash['reverse']}"
|
84
|
-
#
|
85
|
-
# @param: message to print,
|
86
|
-
# @param: length of entry field
|
87
|
-
# @param: default value of field
|
88
|
-
# @param: configuration of box or field
|
89
|
-
# checkboxes: array of strings to use as checkboxes
|
90
|
-
# checkbox_defaults : array of true/false default values for each cb
|
91
|
-
# @return: int 0 OK, 1 cancel pressed
|
92
|
-
# @return: string value entered
|
93
|
-
# @return: hash of strings and booleans for checkboxes and values
|
94
|
-
#
|
95
|
-
def get_string_with_options(message, len=20, default="", config={})
|
96
|
-
title = config["title"] || "Input required"
|
97
|
-
input_config = config["input_config"] || {}
|
98
|
-
checks = config["checkboxes"]
|
99
|
-
checkbox_defaults = config["checkbox_defaults"] || []
|
100
|
-
|
101
|
-
height = config["height"] || 1
|
102
|
-
display_length = config["display_length"] || 30
|
103
|
-
|
104
|
-
r = 3
|
105
|
-
c = 4
|
106
|
-
mform = RubyCurses::Form.new nil
|
107
|
-
message_label = RubyCurses::Label.new mform, {'text' => message, "name"=>"message_label","row" => r, "col" => c, "display_length" => display_length, "height" => height, "attr"=>"reverse"}
|
108
|
-
|
109
|
-
r += 1
|
110
|
-
input = RubyCurses::Field.new mform, input_config do
|
111
|
-
name "input"
|
112
|
-
row r
|
113
|
-
col c
|
114
|
-
display_length display_length
|
115
|
-
maxlen len
|
116
|
-
set_buffer default
|
117
|
-
end
|
118
|
-
if !checks.nil?
|
119
|
-
r += 2
|
120
|
-
checks.each_with_index do |cbtext,ix|
|
121
|
-
field = RubyCurses::CheckBox.new mform do
|
122
|
-
text cbtext
|
123
|
-
name cbtext
|
124
|
-
value checkbox_defaults[ix]||false
|
125
|
-
color 'black'
|
126
|
-
bgcolor 'white'
|
127
|
-
row r
|
128
|
-
col c
|
129
|
-
end
|
130
|
-
r += 1
|
131
|
-
end
|
132
|
-
end
|
133
|
-
radios = config["radiobuttons"]
|
134
|
-
if !radios.nil?
|
135
|
-
radio_default = config["radio_default"] || radios[0]
|
136
|
-
radio = RubyCurses::Variable.new radio_default
|
137
|
-
r += 2
|
138
|
-
radios.each_with_index do |cbtext,ix|
|
139
|
-
field = RubyCurses::RadioButton.new mform do
|
140
|
-
variable radio
|
141
|
-
text cbtext
|
142
|
-
value cbtext
|
143
|
-
color 'black'
|
144
|
-
bgcolor 'white'
|
145
|
-
row r
|
146
|
-
col c
|
147
|
-
end
|
148
|
-
r += 1
|
149
|
-
end
|
150
|
-
end
|
151
|
-
mb = RubyCurses::MessageBox.new mform do
|
152
|
-
title title
|
153
|
-
button_type :ok_cancel
|
154
|
-
default_button 0
|
155
|
-
end
|
156
|
-
hash = {}
|
157
|
-
if !checks.nil?
|
158
|
-
checks.each do |c|
|
159
|
-
hash[c] = mform.by_name[c].getvalue
|
160
|
-
end
|
161
|
-
end
|
162
|
-
hash["radio"] = radio.get_value unless radio.nil?
|
163
|
-
# returns button index (0 = OK), value of field, hash containing values of checkboxes
|
164
|
-
return mb.selected_index, mform.by_name['input'].getvalue, hash
|
165
|
-
end
|
166
|
-
|
167
|
-
# ------------------------ We've Moved here from window class ---------------- #
|
168
|
-
# #
|
169
|
-
# Moving some methods from window. They no longer require having a window. #
|
170
|
-
# #
|
171
|
-
# ---------------------------------------------------------------------------- #
|
172
|
-
#
|
173
|
-
#
|
174
|
-
|
175
|
-
# new version with a window created on 2011-10-1 12:37 AM
|
176
|
-
# Now can be separate from window class, needing nothing, just a util class
|
177
|
-
# prints a status message and pauses for a char
|
178
|
-
def print_status_message text, aconfig={}, &block
|
179
|
-
_print_message :status, text, aconfig, &block
|
180
|
-
end
|
181
|
-
# new version with a window created on 2011-10-1 12:30 AM
|
182
|
-
# Now can be separate from window class, needing nothing, just a util class
|
183
|
-
# Why are we dealing with $error_message, that was due to old idea which failed
|
184
|
-
# scrap it and send the message.
|
185
|
-
def print_error_message text, aconfig={}, &block
|
186
|
-
_print_message :error, text, aconfig, &block
|
187
|
-
end
|
188
|
-
def _create_footer_window h = 2 , w = Ncurses.COLS, t = Ncurses.LINES-2, l = 0
|
189
|
-
ewin = VER::Window.new(h, w , t, l)
|
190
|
-
end
|
191
|
-
# @param [:symbol] :error or :status kind of message
|
192
|
-
# @private
|
193
|
-
def _print_message type, text, aconfig={}, &block
|
194
|
-
case text
|
195
|
-
when RubyCurses::Variable # added 2011-09-20 incase variable passed
|
196
|
-
text = text.get_value
|
197
|
-
when Exception
|
198
|
-
text = text.to_s
|
199
|
-
end
|
200
|
-
# NOTE we are polluting global namespace
|
201
|
-
aconfig.each_pair { |k,v| instance_variable_set("@#{k}",v) }
|
202
|
-
ewin = _create_footer_window #*@layout
|
203
|
-
r = 0; c = 1;
|
204
|
-
case type
|
205
|
-
when :error
|
206
|
-
@color ||= 'red'
|
207
|
-
@bgcolor ||= 'black'
|
208
|
-
else
|
209
|
-
@color ||= :white
|
210
|
-
@bgcolor ||= :black
|
211
|
-
end
|
212
|
-
color_pair = get_color($promptcolor, @color, @bgcolor)
|
213
|
-
ewin.bkgd(Ncurses.COLOR_PAIR(color_pair));
|
214
|
-
ewin.printstring r, c, text, color_pair
|
215
|
-
ewin.printstring r+1, c, "Press a key", color_pair
|
216
|
-
ewin.wrefresh
|
217
|
-
ewin.getchar
|
218
|
-
ewin.destroy
|
219
|
-
end
|
220
|
-
#
|
221
|
-
# Alternative to confirm dialog, if you want this look and feel, at last 2 lines of screen
|
222
|
-
# @param [String] text to prompt
|
223
|
-
# @return [true, false] 'y' is true, all else if false
|
224
|
-
def confirm_window text, aconfig={}, &block
|
225
|
-
case text
|
226
|
-
when RubyCurses::Variable # added 2011-09-20 incase variable passed
|
227
|
-
text = text.get_value
|
228
|
-
when Exception
|
229
|
-
text = text.to_s
|
230
|
-
end
|
231
|
-
ewin = _create_footer_window
|
232
|
-
r = 0; c = 1;
|
233
|
-
aconfig.each_pair { |k,v| instance_variable_set("@#{k}",v) }
|
234
|
-
@color ||= :white
|
235
|
-
@bgcolor ||= :black
|
236
|
-
color_pair = get_color($promptcolor, @color, @bgcolor)
|
237
|
-
ewin.bkgd(Ncurses.COLOR_PAIR(color_pair));
|
238
|
-
ewin.printstring r, c, text, color_pair
|
239
|
-
ewin.printstring r+1, c, "[y/n]", color_pair
|
240
|
-
ewin.wrefresh
|
241
|
-
#retval = false
|
242
|
-
retval = :NO # consistent with confirm
|
243
|
-
begin
|
244
|
-
ch = ewin.getchar
|
245
|
-
retval = :YES if ch.chr == 'y'
|
246
|
-
ensure
|
247
|
-
ewin.destroy
|
248
|
-
end
|
249
|
-
retval
|
250
|
-
end
|
251
|
-
# class created to display multiple messages without asking for user to hit a key
|
252
|
-
# returns a window to which one can keep calling printstring with 0 or 1 as row.
|
253
|
-
# destroy when finished.
|
254
|
-
# Also, one can pause if one wants, or linger.
|
255
|
-
# This is meant to be a replacement for the message_immediate and message_raw
|
256
|
-
# I was trying out in App.rb. 2011-10-1 1:27 AM
|
257
|
-
# Testing from test2.rb
|
258
|
-
# TODO: add option of putting progress_bar
|
259
|
-
class StatusWindow
|
260
|
-
attr_reader :h, :w, :top, :left # height, width, top row, left col of window
|
261
|
-
attr_reader :win
|
262
|
-
attr_accessor :color_pair
|
263
|
-
def initialize config={}, &block
|
264
|
-
@color_pair = config[:color_pair]
|
265
|
-
@row_offset = config[:row_offset] || 0
|
266
|
-
@col_offset = config[:col_offset] || 0
|
267
|
-
create_window *config[:layout]
|
268
|
-
end
|
269
|
-
def create_window h = 2 , w = Ncurses.COLS-0, t = Ncurses.LINES-2, l = 0
|
270
|
-
return @win if @win
|
271
|
-
@win = VER::Window.new(h, w , t, l)
|
272
|
-
@h = h ; @w = w; @top = t ; @left = l
|
273
|
-
@color_pair ||= get_color($promptcolor, 'white','black')
|
274
|
-
@win.bkgd(Ncurses.COLOR_PAIR(@color_pair));
|
275
|
-
@win
|
276
|
-
end
|
277
|
-
# creates a color pair based on given bg and fg colors as strings
|
278
|
-
#def set_colors bgcolor, fgcolor='white'
|
279
|
-
#@color_pair = get_color($datacolor, 'white','black')
|
280
|
-
#end
|
281
|
-
# prints a string on given row (0 or 1)
|
282
|
-
def printstring r, c, text, color_pair=@color_pair
|
283
|
-
create_window unless @win
|
284
|
-
show unless @visible
|
285
|
-
r = @h-1 if r > @h-1
|
286
|
-
#@win.printstring r, c, ' '*@w, @color_pair
|
287
|
-
# FIXME this padding overwrites the border and the offset means next line wiped
|
288
|
-
# However, now it may now totally clear a long line.
|
289
|
-
@win.printstring r+@row_offset, c+@col_offset, "%-*s" % [@w-(@col_offset*2)-c, text], color_pair
|
290
|
-
@win.wrefresh
|
291
|
-
end
|
292
|
-
# print given strings from first first column onwards
|
293
|
-
def print *textarray
|
294
|
-
create_window unless @win
|
295
|
-
show unless @visible
|
296
|
-
c = 1
|
297
|
-
textarray.each_with_index { |s, i|
|
298
|
-
@win.printstring i+@row_offset, c+@col_offset, "%-*s" % [@w-(@col_offset*2)-c, s], @color_pair
|
299
|
-
}
|
300
|
-
@win.wrefresh
|
301
|
-
end
|
302
|
-
def pause; @win.getchar; end
|
303
|
-
# pauses with the message, but doesn't ask the user to press a key.
|
304
|
-
# If he does, the key should be used by underlying window.
|
305
|
-
# Do not call destroy if you call linger, it does the destroy.
|
306
|
-
def linger caller_window=nil
|
307
|
-
begin
|
308
|
-
if caller_window
|
309
|
-
ch = @win.getchar
|
310
|
-
caller_window.ungetch(ch) # will this be available to underlying window XXX i think not !!
|
311
|
-
else
|
312
|
-
sleep 1
|
313
|
-
end
|
314
|
-
ensure
|
315
|
-
destroy
|
316
|
-
end
|
317
|
-
end
|
318
|
-
# caller must destroy after he's finished printing messages, unless
|
319
|
-
# user calls linger
|
320
|
-
def destroy; @win.destroy if @win; @win = nil; end
|
321
|
-
def hide
|
322
|
-
@win.hide
|
323
|
-
@visible = false
|
324
|
-
end
|
325
|
-
def show
|
326
|
-
@win.show unless @visible
|
327
|
-
@visible = true
|
328
|
-
end
|
329
|
-
end
|
330
|
-
# returns instance of a status_window for sending multiple
|
331
|
-
# statuses during some process
|
332
|
-
def status_window aconfig={}, &block
|
333
|
-
return StatusWindow.new aconfig
|
334
|
-
end
|
335
|
-
# this is a popup dialog box on which statuses can be printed as a process is taking place.
|
336
|
-
# I am reusing StatusWindow and so there's an issue since I've put a box, so in clearing
|
337
|
-
# the line, I might overwrite the box
|
338
|
-
def progress_dialog aconfig={}, &block
|
339
|
-
aconfig[:layout] = [10,60,10,20]
|
340
|
-
window = status_window aconfig
|
341
|
-
height = 10; width = 60
|
342
|
-
window.win.print_border_mb 1,2, height, width, $normalcolor, FFI::NCurses::A_REVERSE
|
343
|
-
return window
|
344
|
-
end
|
345
|
-
#
|
346
|
-
# Display a popup and return the seliected index from list
|
347
|
-
# Config includes row and col and title of window
|
348
|
-
# You may also pass bgcolor and color
|
349
|
-
# @since 1.4.1 2011-11-1
|
350
|
-
def popuplist list, config={}, &block
|
351
|
-
require 'rbcurse/rbasiclistbox'
|
352
|
-
|
353
|
-
max_visible_items = config[:max_visible_items]
|
354
|
-
row = config[:row] || 5
|
355
|
-
col = config[:col] || 5
|
356
|
-
relative_to = config[:relative_to]
|
357
|
-
if relative_to
|
358
|
-
layout = relative_to.form.window.layout
|
359
|
-
row += layout[:top]
|
360
|
-
col += layout[:left]
|
361
|
-
end
|
362
|
-
config.delete :relative_to
|
363
|
-
width = config[:width] || longest_in_list(list)+2 # borders take 2
|
364
|
-
height = config[:height]
|
365
|
-
height ||= [max_visible_items || 10+2, list.length+2].min
|
366
|
-
#layout(1+height, width+4, row, col)
|
367
|
-
layout = { :height => 0+height, :width => 0+width, :top => row, :left => col }
|
368
|
-
window = VER::Window.new(layout)
|
369
|
-
form = RubyCurses::Form.new window
|
370
|
-
|
371
|
-
listconfig = config[:listconfig] || {}
|
372
|
-
listconfig[:list] = list
|
373
|
-
listconfig[:width] = width
|
374
|
-
listconfig[:height] = height
|
375
|
-
listconfig[:selection_mode] = :single
|
376
|
-
listconfig.merge!(config)
|
377
|
-
listconfig.delete(:row);
|
378
|
-
listconfig.delete(:col);
|
379
|
-
# trying to pass populists block to listbox
|
380
|
-
lb = RubyCurses::BasicListbox.new form, listconfig, &block
|
381
|
-
#
|
382
|
-
# added next line so caller can configure listbox with
|
383
|
-
# events such as ENTER_ROW, LEAVE_ROW or LIST_SELECTION_EVENT or PRESS
|
384
|
-
# 2011-11-11
|
385
|
-
#yield lb if block_given? # No it won't work since this returns
|
386
|
-
window.bkgd(Ncurses.COLOR_PAIR($reversecolor));
|
387
|
-
window.wrefresh
|
388
|
-
Ncurses::Panel.update_panels
|
389
|
-
form.repaint
|
390
|
-
window.wrefresh
|
391
|
-
begin
|
392
|
-
while((ch = window.getchar()) != 999 )
|
393
|
-
case ch
|
394
|
-
when -1
|
395
|
-
next
|
396
|
-
when ?\C-q.getbyte(0)
|
397
|
-
break
|
398
|
-
else
|
399
|
-
lb.handle_key ch
|
400
|
-
form.repaint
|
401
|
-
if ch == 13 || ch == 10
|
402
|
-
return lb.current_index
|
403
|
-
# if multiple selection, then return list of selected_indices and don't catch 32
|
404
|
-
elsif ch == 32 # if single selection
|
405
|
-
return lb.current_index
|
406
|
-
end
|
407
|
-
#yield ch if block_given?
|
408
|
-
end
|
409
|
-
end
|
410
|
-
ensure
|
411
|
-
window.destroy
|
412
|
-
end
|
413
|
-
return nil
|
414
|
-
end
|
415
|
-
# returns length of longest
|
416
|
-
def longest_in_list list #:nodoc:
|
417
|
-
longest = list.inject(0) do |memo,word|
|
418
|
-
memo >= word.length ? memo : word.length
|
419
|
-
end
|
420
|
-
longest
|
421
|
-
end
|
422
|
-
#
|
423
|
-
=begin
|
424
|
-
http://www.kammerl.de/ascii/AsciiSignature.php
|
425
|
-
___
|
426
|
-
|__ \
|
427
|
-
) |
|
428
|
-
/ /
|
429
|
-
|_|
|
430
|
-
(_)
|
431
|
-
|
432
|
-
_
|
433
|
-
| |
|
434
|
-
| |
|
435
|
-
| |
|
436
|
-
|_|
|
437
|
-
(_)
|
438
|
-
|
439
|
-
|
440
|
-
_____ _ _____
|
441
|
-
| __ \ | | / ____|
|
442
|
-
| |__) | _| |__ _ _ | | _ _ _ __ ___ ___ ___
|
443
|
-
| _ / | | | '_ \| | | | | | | | | | '__/ __|/ _ \/ __|
|
444
|
-
| | \ \ |_| | |_) | |_| | | |___| |_| | | \__ \ __/\__ \
|
445
|
-
|_| \_\__,_|_.__/ \__, | \_____\__,_|_| |___/\___||___/
|
446
|
-
__/ |
|
447
|
-
|___/
|
448
|
-
|
449
|
-
=end
|
450
|
-
|
451
|
-
|