rbcurse 1.3.0 → 1.4.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/CHANGELOG +33 -0
- data/README.markdown +7 -1
- data/TODO2.txt +21 -15
- data/VERSION +1 -1
- data/examples/abasiclist.rb +2 -2
- data/examples/alpmenu.rb +1 -1
- data/examples/app.rb +0 -1
- data/examples/appdirtree.rb +4 -2
- data/examples/appemail.rb +7 -3
- data/examples/appemaillb.rb +1 -1
- data/examples/appgcompose.rb +2 -2
- data/examples/appgmail.rb +1 -1
- data/examples/appmethods.rb +20 -2
- data/examples/atree.rb +9 -1
- data/examples/dbdemo.rb +460 -0
- data/examples/dirtree.rb +1 -1
- data/examples/menu1.rb +37 -5
- data/examples/multispl.rb +1 -1
- data/examples/rfe.rb +9 -2
- data/examples/splitp.rb +1 -1
- data/examples/sqlc.rb +6 -10
- data/examples/sqlm.rb +2 -20
- data/examples/sqlt.rb +408 -0
- data/examples/term2.rb +1 -1
- data/examples/test2.rb +169 -97
- data/examples/testapp.rb +1 -1
- data/examples/testapp2.rb +1 -1
- data/examples/testkeypress.rb +4 -2
- data/examples/testtable.rb +6 -0
- data/examples/testtpane.rb +35 -23
- data/examples/testvimsplit.rb +3 -2
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/action.rb +8 -0
- data/lib/rbcurse/app.rb +39 -23
- data/lib/rbcurse/extras/bottomline.rb +101 -13
- data/lib/rbcurse/extras/directorylist.rb +14 -5
- data/lib/rbcurse/extras/divider.rb +1 -1
- data/lib/rbcurse/extras/listselectable.rb +42 -8
- data/lib/rbcurse/extras/masterdetail.rb +2 -2
- data/lib/rbcurse/extras/scrollbar.rb +11 -2
- data/lib/rbcurse/extras/statusline.rb +56 -0
- data/lib/rbcurse/extras/stdscrwindow.rb +11 -0
- data/lib/rbcurse/extras/tabular.rb +2 -1
- data/lib/rbcurse/extras/tabularwidget.rb +60 -17
- data/lib/rbcurse/extras/viewer.rb +16 -4
- data/lib/rbcurse/keylabelprinter.rb +34 -4
- data/lib/rbcurse/listeditable.rb +5 -1
- data/lib/rbcurse/listkeys.rb +1 -1
- data/lib/rbcurse/listscrollable.rb +15 -8
- data/lib/rbcurse/rbasiclistbox.rb +44 -23
- data/lib/rbcurse/rcommandwindow.rb +8 -14
- data/lib/rbcurse/rdialogs.rb +187 -2
- data/lib/rbcurse/rlistbox.rb +38 -19
- data/lib/rbcurse/rmenu.rb +313 -93
- data/lib/rbcurse/rmessagebox.rb +3 -2
- data/lib/rbcurse/rmulticontainer.rb +5 -3
- data/lib/rbcurse/rmultisplit.rb +2 -11
- data/lib/rbcurse/rmultitextview.rb +4 -5
- data/lib/rbcurse/rtabbedpane.rb +223 -69
- data/lib/rbcurse/rtable.rb +6 -10
- data/lib/rbcurse/rtextarea.rb +57 -36
- data/lib/rbcurse/rtextview.rb +12 -15
- data/lib/rbcurse/rtree.rb +79 -22
- data/lib/rbcurse/rvimsplit.rb +16 -25
- data/lib/rbcurse/rwidget.rb +376 -523
- data/lib/rbcurse/tree/treecellrenderer.rb +24 -11
- data/lib/rbcurse/tree/treemodel.rb +1 -1
- data/lib/ver/window.rb +130 -66
- metadata +5 -3
- data/examples/term.rb +0 -48
data/examples/testapp.rb
CHANGED
@@ -24,7 +24,7 @@ class Testy
|
|
24
24
|
app = App.new
|
25
25
|
$log.debug " APP : value #{value}" if $log.debug?
|
26
26
|
header = app.app_header "rbcurse #{Rbcurse::VERSION} " , :text_center => " #{@value} Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
|
27
|
-
app.message "Press
|
27
|
+
app.message "Press F10 to exit from here #{@value} "
|
28
28
|
|
29
29
|
app.stack :margin_top => 2, :margin => 5, :width => 30 do |s|
|
30
30
|
app.label "Hello: ", :attr => :reverse
|
data/examples/testapp2.rb
CHANGED
@@ -30,7 +30,7 @@ class Testy
|
|
30
30
|
App.new do |app|
|
31
31
|
$log.debug " APP : value #{value}" if $log.debug?
|
32
32
|
header = app.app_header "rbcurse #{Rbcurse::VERSION} ", :text_center => " #{@value} Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
|
33
|
-
app.message "Press
|
33
|
+
app.message "Press F10 to exit from here #{@value} "
|
34
34
|
|
35
35
|
app.stack :margin_top => 2, :margin => 5, :width => 30 do |s|
|
36
36
|
app.label "Hello: ", :attr => :reverse
|
data/examples/testkeypress.rb
CHANGED
@@ -36,8 +36,10 @@ if $0 == __FILE__
|
|
36
36
|
auto_scroll true
|
37
37
|
title_attrib (Ncurses::A_REVERSE | Ncurses::A_BOLD)
|
38
38
|
end
|
39
|
-
|
40
|
-
|
39
|
+
help = "q to quit. Check keys. F1..10, C-a..z, Alt a-zA-Z0-9, C-left,rt, Sh-F5..10 .: #{$0}"
|
40
|
+
help1 = "Press in quick succession: 1) M-[, w and (2) M-[, M-w. (3) M-Sh-O, w."
|
41
|
+
RubyCurses::Label.new @form, {'text' => help, "row" => 21, "col" => 2, "color" => "yellow"}
|
42
|
+
RubyCurses::Label.new @form, {'text' => help1, "row" => 22, "col" => 2, "color" => "green"}
|
41
43
|
|
42
44
|
@form.repaint
|
43
45
|
@window.wrefresh
|
data/examples/testtable.rb
CHANGED
@@ -232,6 +232,7 @@ if $0 == __FILE__
|
|
232
232
|
@window.wrefresh
|
233
233
|
Ncurses::Panel.update_panels
|
234
234
|
while((ch = @window.getchar()) != ?\C-q.getbyte(0) )
|
235
|
+
begin
|
235
236
|
colcount = tcm.column_count-1
|
236
237
|
s = keycode_tos ch
|
237
238
|
keylabel.text = "Pressed #{ch} , #{s}"
|
@@ -248,6 +249,11 @@ if $0 == __FILE__
|
|
248
249
|
|
249
250
|
@form.repaint
|
250
251
|
@window.wrefresh
|
252
|
+
rescue => ex
|
253
|
+
$log.debug( ex) if ex
|
254
|
+
$log.debug(ex.backtrace.join("\n")) if ex
|
255
|
+
alert ex.to_s
|
256
|
+
end
|
251
257
|
end
|
252
258
|
end
|
253
259
|
rescue => ex
|
data/examples/testtpane.rb
CHANGED
@@ -15,9 +15,6 @@
|
|
15
15
|
# M-l in button form will scroll. M-h to scroll left.
|
16
16
|
# dd to kill a tab, u to undo kill, or p/P to paste deleted tab
|
17
17
|
#
|
18
|
-
#$LOAD_PATH << "/Users/rahul/work/projects/rbcurse/"
|
19
|
-
require 'rubygems'
|
20
|
-
#require 'ncurses' # FFI
|
21
18
|
require 'logger'
|
22
19
|
require 'rbcurse'
|
23
20
|
require 'rbcurse/rtabbedpane'
|
@@ -45,13 +42,16 @@ class TestTabbedPane
|
|
45
42
|
col 8
|
46
43
|
#button_type :ok
|
47
44
|
end
|
45
|
+
@tab1 = @tp.add_tab "&TextView" #, textview
|
46
|
+
f1 = @tp.form(@tab1)
|
48
47
|
|
49
|
-
textview = TextView.new do
|
48
|
+
textview = TextView.new f1 do
|
50
49
|
name "myView"
|
51
|
-
row
|
50
|
+
row 0
|
52
51
|
col 0
|
53
|
-
|
52
|
+
width w-0
|
54
53
|
#height h-4
|
54
|
+
height h-2
|
55
55
|
title "README.mrku"
|
56
56
|
title_attrib 'bold'
|
57
57
|
print_footer true
|
@@ -61,20 +61,19 @@ class TestTabbedPane
|
|
61
61
|
textview.set_content content #, :WRAP_WORD
|
62
62
|
#textview.show_caret = true
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
#f1
|
64
|
+
#@tab1 = @tp.add_tab "&TextView" #, textview
|
65
|
+
#f1 = @tp.form(@tab1)
|
66
|
+
#textview.set_form(f1)
|
67
|
+
#@tp.configure_component(textview)
|
67
68
|
|
68
69
|
|
69
70
|
|
70
71
|
#f2 = @tab2.form
|
72
|
+
#@tab2 = @tp.add_tab "&Settings" #, texta
|
73
|
+
#f2 = @tp.form(@tab2)
|
71
74
|
r = 4
|
72
75
|
texta = TextArea.new do
|
73
|
-
name
|
74
|
-
#row r
|
75
|
-
#col 2
|
76
|
-
#width w-5
|
77
|
-
#height h-5
|
76
|
+
name "myText"
|
78
77
|
title "EditMe.txt"
|
79
78
|
title_attrib 'bold'
|
80
79
|
print_footer true
|
@@ -105,9 +104,25 @@ class TestTabbedPane
|
|
105
104
|
col 5
|
106
105
|
end
|
107
106
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
107
|
+
x = RubyCurses::Field.new f3 do
|
108
|
+
name 'username'
|
109
|
+
row row+6
|
110
|
+
bgcolor 'white'
|
111
|
+
color 'black'
|
112
|
+
col 15
|
113
|
+
display_length 20
|
114
|
+
set_label Label.new f3, {'text' => 'User Name', 'mnemonic'=> 'u'}
|
115
|
+
end
|
116
|
+
x = RubyCurses::Field.new f3 do
|
117
|
+
name 'nick'
|
118
|
+
row row+7
|
119
|
+
bgcolor 'white'
|
120
|
+
color 'black'
|
121
|
+
col 15
|
122
|
+
display_length 10
|
123
|
+
set_label Label.new f3, {'text' => 'Nick Name', 'mnemonic'=> 'n'}
|
124
|
+
end
|
125
|
+
|
111
126
|
data = [["Pathetique",3,"Tchaikovsky",3.21, true, "WIP"],
|
112
127
|
["Ali Maula Ali Maula",3,"NFAK",3.47, true, "WIP"],
|
113
128
|
["Tera Hijr Mera Nasib",92,"Razia Sultan",412, true, "Fin"],
|
@@ -138,17 +153,14 @@ class TestTabbedPane
|
|
138
153
|
# We can skip sizing too for large components, so comp will fill the TP.
|
139
154
|
atable = Table.new do
|
140
155
|
name "mytable"
|
141
|
-
#row row
|
142
|
-
#col 0
|
143
|
-
#width 76
|
144
|
-
#height h - 4
|
145
156
|
#title "A Table"
|
146
157
|
#title_attrib (Ncurses::A_REVERSE | Ncurses::A_BOLD)
|
147
158
|
cell_editing_allowed true
|
148
159
|
editing_policy :EDITING_AUTO
|
149
160
|
set_data data, colnames
|
150
161
|
end
|
151
|
-
tab3
|
162
|
+
tab3 = @tp.add_tab "S&ongs", atable
|
163
|
+
#tab3.component = atable
|
152
164
|
sel_col = Variable.new 0
|
153
165
|
sel_col.value = 0
|
154
166
|
tcm = atable.get_table_column_model
|
@@ -160,7 +172,7 @@ class TestTabbedPane
|
|
160
172
|
tcm.column(3).width 7
|
161
173
|
tcm.column(4).width 5
|
162
174
|
tcm.column(5).width 6
|
163
|
-
@help = "F1 to quit. M-s M-t M-e M-o, TAB
|
175
|
+
@help = "F1 to quit. M-s M-t M-e M-o, TAB. M-x to add tab #{$0} M-h/M-l to scroll tabs"
|
164
176
|
RubyCurses::Label.new @form, {'text' => @help, "row" => r+h+2, "col" => 2, "color" => "yellow"}
|
165
177
|
|
166
178
|
# M-x when inside the buttons form will create a new tab
|
data/examples/testvimsplit.rb
CHANGED
@@ -46,6 +46,7 @@ class Tester
|
|
46
46
|
@vim.add lb1, :FIRST, :AUTO #nil #0.7:AUTO
|
47
47
|
@vim.add ["mercury","venus","earth","mars","jupiter", "saturn"], :FIRST, :AUTO
|
48
48
|
@vim.add alist, :FIRST, 0.4, stfl
|
49
|
+
#@vim.add alist, :FIRST, nil, stfl
|
49
50
|
@vim.add alist.shuffle, :FIRST, nil, stfl
|
50
51
|
@vim.add lb2, :SECOND, :AUTO
|
51
52
|
@vim.add str, :SECOND, :AUTO
|
@@ -69,14 +70,14 @@ class Tester
|
|
69
70
|
k_button.command { |form| @vim.decrease_weight }
|
70
71
|
|
71
72
|
#
|
72
|
-
@help = "
|
73
|
+
@help = "F10 to quit. "
|
73
74
|
RubyCurses::Label.new @form, {'text' => @help, "row" => 1, "col" => 2, "color" => "yellow"}
|
74
75
|
@form.repaint
|
75
76
|
@window.wrefresh
|
76
77
|
Ncurses::Panel.update_panels
|
77
78
|
ctr = 0
|
78
79
|
row = 2
|
79
|
-
while((ch = @window.getchar()) !=
|
80
|
+
while((ch = @window.getchar()) != Ncurses::KEY_F10 )
|
80
81
|
ret = @form.handle_key(ch)
|
81
82
|
@window.wrefresh
|
82
83
|
#ret = @vim.handle_key ch
|
data/lib/rbcurse.rb
CHANGED
data/lib/rbcurse/action.rb
CHANGED
@@ -3,6 +3,14 @@ require 'rbcurse/rwidget'
|
|
3
3
|
include RubyCurses
|
4
4
|
module RubyCurses
|
5
5
|
## encapsulates behaviour allowing centralization
|
6
|
+
# == Example
|
7
|
+
# a = Action.new("&New Row") { commands }
|
8
|
+
# a.accelerator "Alt N"
|
9
|
+
# menu.add(a)
|
10
|
+
# b = Button.new form do
|
11
|
+
# action a
|
12
|
+
# ...
|
13
|
+
# end
|
6
14
|
class Action < Proc
|
7
15
|
include EventHandler
|
8
16
|
include ConfigSetup
|
data/lib/rbcurse/app.rb
CHANGED
@@ -9,7 +9,6 @@ Todo:
|
|
9
9
|
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
10
10
|
|
11
11
|
=end
|
12
|
-
#require 'ncurses'
|
13
12
|
require 'logger'
|
14
13
|
require 'rbcurse'
|
15
14
|
|
@@ -19,9 +18,8 @@ $tt.name = "$tt"
|
|
19
18
|
require 'forwardable'
|
20
19
|
module Kernel
|
21
20
|
extend Forwardable
|
22
|
-
def_delegators :$tt, :ask, :say, :agree, :choose, :numbered_menu, :display_text, :display_text_interactive, :display_list, :say_with_pause
|
21
|
+
def_delegators :$tt, :ask, :say, :agree, :choose, :numbered_menu, :display_text, :display_text_interactive, :display_list, :say_with_pause, :hide_bottomline
|
23
22
|
end
|
24
|
-
#include Ncurses # FFI 2011-09-8
|
25
23
|
include RubyCurses
|
26
24
|
include RubyCurses::Utils
|
27
25
|
include Io
|
@@ -83,9 +81,6 @@ module RubyCurses
|
|
83
81
|
|
84
82
|
extend Forwardable
|
85
83
|
def_delegators :$tt, :ask, :say, :agree, :choose, :numbered_menu, :display_text, :display_text_interactive, :display_list
|
86
|
-
#@tt = Bottomline.new @window, @message_row
|
87
|
-
#extend Forwardable
|
88
|
-
#def_delegators :@tt, :ask, :say, :agree, :choose
|
89
84
|
|
90
85
|
# TODO: i should be able to pass window coords here in config
|
91
86
|
# :title
|
@@ -122,11 +117,12 @@ module RubyCurses
|
|
122
117
|
colors = Ncurses.COLORS
|
123
118
|
$log.debug "START #{colors} colors --------- #{$0} win: #{@window} "
|
124
119
|
end
|
120
|
+
=begin
|
121
|
+
# trying without 2011-10-8
|
125
122
|
require 'rbcurse/extras/stdscrwindow'
|
126
123
|
awin = StdscrWindow.new
|
127
124
|
$tt.window = awin; $tt.message_row = @message_row
|
128
|
-
|
129
|
-
#$tt.window = @window; $tt.message_row = @message_row
|
125
|
+
=end
|
130
126
|
end
|
131
127
|
def logger; return $log; end
|
132
128
|
def close
|
@@ -134,6 +130,7 @@ module RubyCurses
|
|
134
130
|
@window.destroy if !@window.nil?
|
135
131
|
$log.debug " INSIDE CLOSE, #{@stop_ncurses_on_close} "
|
136
132
|
if @stop_ncurses_on_close
|
133
|
+
$tt.destroy # added on 2011-10-9 since we created a window, but only hid it after use
|
137
134
|
VER::stop_ncurses
|
138
135
|
$log.debug " CLOSING NCURSES"
|
139
136
|
end
|
@@ -187,19 +184,24 @@ module RubyCurses
|
|
187
184
|
# updates a global var with text. Calling app has to set up a Variable with that name and attach to
|
188
185
|
# a label so it can be printed.
|
189
186
|
def message text
|
187
|
+
$status_message.value = text # trying out 2011-10-9
|
190
188
|
@message.value = text
|
191
189
|
end
|
192
190
|
def message_row row
|
193
|
-
|
191
|
+
raise "Please use create_message_label first as message_label is no longer default behaviour" unless @message_label
|
192
|
+
@message_label.row = row
|
194
193
|
end
|
195
194
|
# during a process, when you wish to update status, since ordinarily the thread is busy
|
196
195
|
# and form does not get control back, so the window won't refresh.
|
197
196
|
# NOTE: use this only if +message+ is not working
|
198
197
|
# XXX Not sure if this is working after move to ffi-ncurses, check the demos
|
199
198
|
def message_immediate text
|
199
|
+
$status_message.value = text # trying out 2011-10-9 user needs to use in statusline command
|
200
200
|
message text
|
201
|
-
@message_label
|
202
|
-
|
201
|
+
if @message_label
|
202
|
+
@message_label.repaint
|
203
|
+
@window.refresh
|
204
|
+
end
|
203
205
|
end
|
204
206
|
# NOTE XXX using stdscr results in the screen going black if a dialog
|
205
207
|
# or other window is popped up, this was great but has not worked out.
|
@@ -208,23 +210,29 @@ module RubyCurses
|
|
208
210
|
# so at end of printing raw_messages, use message() for final status.
|
209
211
|
# Usage: application is inside a long processing loop and wishes to print ongoing status
|
210
212
|
# (similar to message_immediate) but faster and less involved
|
213
|
+
# @deprecated since it uses stdscr. Use say_with_pause or use rdialogs status_window, see test2.rb
|
211
214
|
def raw_message text
|
215
|
+
$log.warn "WARNING: don't use this method as it uses stdscr. Use rdialogs statuswindow."
|
216
|
+
row = @message_label ? @message_label.row : Ncurses.LINES-1
|
212
217
|
# experimentally trying stdscr instead of label
|
213
218
|
scr = FFI::NCurses.stdscr
|
214
219
|
text = "%-80s" % text
|
215
|
-
Ncurses.mvprintw
|
220
|
+
Ncurses.mvprintw row ,0, text
|
216
221
|
#@_stext ||= ""
|
217
222
|
#@_stext << text
|
218
223
|
## appending is quite a pain, maybe we should make it separate.
|
219
224
|
#stext = "%-80s" % @_stext
|
220
|
-
#Ncurses.mvprintw
|
225
|
+
#Ncurses.mvprintw row ,0, stext[-80..-1]
|
221
226
|
#scr.refresh() # NW w FFI XXX
|
222
227
|
#FFI::NCurses.refresh
|
223
228
|
end
|
224
229
|
# shows a simple progress bar on last row, using stdscr
|
225
230
|
# @param [Float, Array<Fixnum,Fixnum>] percentage, or part/total
|
226
231
|
# If Array of two numbers is given then also print part/total on left of bar
|
232
|
+
# @deprecated - don't use stdscr at all, use rdialogs status_window (see test2.rb)
|
227
233
|
def raw_progress arg
|
234
|
+
$log.warning "WARNING: don't use this method as it uses stdscr"
|
235
|
+
row = @message_label ? @message_label.row : Ncurses.LINES-1
|
228
236
|
s = nil
|
229
237
|
case arg
|
230
238
|
when Array
|
@@ -241,8 +249,8 @@ module RubyCurses
|
|
241
249
|
startcol = endcol - 12
|
242
250
|
stext = ("=" * (pc*10).to_i)
|
243
251
|
text = "[" + "%-10s" % stext + "]"
|
244
|
-
Ncurses.mvprintw(
|
245
|
-
Ncurses.mvprintw
|
252
|
+
Ncurses.mvprintw( row ,startcol-10, s) if s
|
253
|
+
Ncurses.mvprintw row ,startcol, text
|
246
254
|
#scr.refresh() # XXX FFI NW
|
247
255
|
|
248
256
|
end
|
@@ -410,7 +418,7 @@ module RubyCurses
|
|
410
418
|
alert "#{self.class} does not respond to #{cmd} "
|
411
419
|
ret = false
|
412
420
|
ret = execute_this(cmd, *cmdline) if respond_to?(:execute_this, true)
|
413
|
-
|
421
|
+
say_with_pause("#{self.class} does not respond to #{cmd} ", :color_pair => $promptcolor) unless ret
|
414
422
|
# should be able to say in red as error
|
415
423
|
end
|
416
424
|
end
|
@@ -726,10 +734,13 @@ module RubyCurses
|
|
726
734
|
require 'rbcurse/applicationheader'
|
727
735
|
header = ApplicationHeader.new @form, title, config, &block
|
728
736
|
end
|
737
|
+
|
738
|
+
# prints pine-like key labels
|
729
739
|
def dock labels, config={}, &block
|
730
740
|
require 'rbcurse/keylabelprinter'
|
731
741
|
klp = RubyCurses::KeyLabelPrinter.new @form, labels, config, &block
|
732
742
|
end
|
743
|
+
|
733
744
|
def link *args, &block
|
734
745
|
require 'rbcurse/extras/rlink'
|
735
746
|
config = {}
|
@@ -1060,16 +1071,18 @@ module RubyCurses
|
|
1060
1071
|
return cmd if opts.include? cmd
|
1061
1072
|
matches = opts.grep Regexp.new("^#{cmd}")
|
1062
1073
|
end
|
1074
|
+
# Now i am not creating this unless user wants it. Pls avoid it.
|
1075
|
+
# Use either say_with_pause, or put $status_message in command of statusline
|
1076
|
+
# @deprecated
|
1077
|
+
def create_message_label row=Ncurses.LINES-1
|
1078
|
+
@message_label = RubyCurses::Label.new @form, {:text_variable => @message, :name=>"message_label",:row => row, :col => 0, :display_length => Ncurses.COLS, :height => 1, :color => :white}
|
1079
|
+
end
|
1063
1080
|
def run &block
|
1064
1081
|
begin
|
1065
1082
|
|
1066
1083
|
# check if user has passed window coord in config, else root window
|
1067
1084
|
@window = VER::Window.root_window
|
1068
|
-
#$tt.window = @window; $tt.message_row = @message_row
|
1069
1085
|
awin = @window
|
1070
|
-
#require 'rbcurse/extras/stdscrwindow'
|
1071
|
-
#awin = StdscrWindow.new
|
1072
|
-
#$tt.window = awin; $tt.message_row = @message_row
|
1073
1086
|
catch(:close) do
|
1074
1087
|
@form = Form.new @window
|
1075
1088
|
@form.bind_key([?\C-x, ?c]) { suspend(false) do
|
@@ -1103,7 +1116,7 @@ module RubyCurses
|
|
1103
1116
|
rcmd = _resolve_command(opts, cmd) if !opts.include?(cmd)
|
1104
1117
|
if rcmd.size == 1
|
1105
1118
|
cmd = rcmd.first
|
1106
|
-
|
1119
|
+
elsif !rcmd.empty?
|
1107
1120
|
say_with_pause "Cannot resolve #{cmd}. Matches are: #{rcmd} "
|
1108
1121
|
end
|
1109
1122
|
end
|
@@ -1121,14 +1134,17 @@ module RubyCurses
|
|
1121
1134
|
end
|
1122
1135
|
end
|
1123
1136
|
else
|
1124
|
-
|
1137
|
+
say_with_pause("Command [#{cmd}] not supported by #{self.class} ", :color_pair => $promptcolor)
|
1125
1138
|
end
|
1126
1139
|
end
|
1127
1140
|
}
|
1128
1141
|
@form.bind_key(KEY_F1){ display_app_help }
|
1142
|
+
@form.bind_key([?q,?q]){ throw :close } if $log.debug?
|
1143
|
+
|
1129
1144
|
@message = Variable.new
|
1130
1145
|
@message.value = ""
|
1131
|
-
|
1146
|
+
$status_message ||= Variable.new # remember there are multiple levels of apps
|
1147
|
+
$status_message.value = ""
|
1132
1148
|
$error_message.update_command { @message.set_value($error_message.value) }
|
1133
1149
|
if block
|
1134
1150
|
begin
|
@@ -15,6 +15,11 @@ require 'pathname'
|
|
15
15
|
|
16
16
|
May later use a Label and Field.
|
17
17
|
|
18
|
+
NOTE : Pls avoid directly using this class. I am trying to redo this so ask, agree and say
|
19
|
+
can create their own window and be done with it. The hurdle in that is that ask calls
|
20
|
+
say, so when to close the window is not clear within say. Some shakeup is expected by
|
21
|
+
1.4.0 or so.
|
22
|
+
|
18
23
|
=end
|
19
24
|
module RubyCurses
|
20
25
|
|
@@ -83,7 +88,20 @@ module RubyCurses
|
|
83
88
|
attr_accessor :name # for debugging
|
84
89
|
def initialize win=nil, row=nil
|
85
90
|
@window = win
|
86
|
-
|
91
|
+
#@window.wrefresh
|
92
|
+
#Ncurses::Panel.update_panels
|
93
|
+
#@message_row = row
|
94
|
+
@message_row = 0 # 2011-10-8
|
95
|
+
end
|
96
|
+
#
|
97
|
+
# create a window at bottom and show and hide it.
|
98
|
+
# Causing a stack overflow since Window creates a bottomline too !
|
99
|
+
#
|
100
|
+
def _create_footer_window h = 1 , w = Ncurses.COLS, t = Ncurses.LINES-1, l = 0
|
101
|
+
ewin = VER::Window.new(h, w , t, l)
|
102
|
+
#ewin.bkgd(Ncurses.COLOR_PAIR($promptcolor));
|
103
|
+
@window = ewin
|
104
|
+
return ewin
|
87
105
|
end
|
88
106
|
|
89
107
|
class QuestionError < StandardError
|
@@ -947,7 +965,10 @@ module RubyCurses
|
|
947
965
|
end
|
948
966
|
end
|
949
967
|
def ask(question, answer_type=String, &details)
|
950
|
-
|
968
|
+
$log.debug "XXXX inside ask win #{@window} "
|
969
|
+
#@window.show #unless @window.visible?
|
970
|
+
@window ||= _create_footer_window
|
971
|
+
|
951
972
|
@question ||= Question.new(question, answer_type, &details)
|
952
973
|
say(@question) #unless @question.echo == true
|
953
974
|
|
@@ -961,6 +982,7 @@ module RubyCurses
|
|
961
982
|
end
|
962
983
|
|
963
984
|
begin
|
985
|
+
# FIXME a C-c still returns default to user !
|
964
986
|
@answer = @question.answer_or_default(get_response)
|
965
987
|
unless @question.valid_answer?(@answer)
|
966
988
|
explain_error(:not_valid)
|
@@ -1010,10 +1032,38 @@ module RubyCurses
|
|
1010
1032
|
rescue Question::NoAutoCompleteMatch
|
1011
1033
|
explain_error(:no_completion)
|
1012
1034
|
retry
|
1035
|
+
rescue Interrupt
|
1036
|
+
$log.warn "User interrupted ask() get_response does not want operation to proceed"
|
1037
|
+
return nil
|
1013
1038
|
ensure
|
1014
1039
|
@question = nil # Reset Question object.
|
1040
|
+
hide # assuming this method made it visible, not sure if this is called.
|
1041
|
+
end
|
1042
|
+
end
|
1043
|
+
#
|
1044
|
+
# bottomline user has to hide window if he called say().
|
1045
|
+
# Call this if you find the window persists after using some method from here
|
1046
|
+
# usually say or ask.
|
1047
|
+
#
|
1048
|
+
# @param [int, float] time to sleep before hiding window.
|
1049
|
+
#
|
1050
|
+
def hide wait=nil
|
1051
|
+
if @window
|
1052
|
+
sleep(wait) if wait
|
1053
|
+
@window.hide
|
1054
|
+
@window.wrefresh
|
1055
|
+
#Ncurses::Panel.update_panels
|
1015
1056
|
end
|
1016
1057
|
end
|
1058
|
+
alias :hide_bottomline :hide
|
1059
|
+
#
|
1060
|
+
# destroy window, to be called by app when shutting down
|
1061
|
+
# since we are normally hiding the window only.
|
1062
|
+
def destroy
|
1063
|
+
$log.debug "bottomline destroy... #{@window} "
|
1064
|
+
@window.destroy if @window
|
1065
|
+
@window = nil
|
1066
|
+
end
|
1017
1067
|
|
1018
1068
|
#
|
1019
1069
|
# The basic output method for HighLine objects.
|
@@ -1025,14 +1075,21 @@ module RubyCurses
|
|
1025
1075
|
# question. Also, ansi color constants will not work. Be careful what ruby code
|
1026
1076
|
# you pass in.
|
1027
1077
|
#
|
1078
|
+
# NOTE: This uses a window, so it will persist in the last row. You must call
|
1079
|
+
# hide_bottomline to remove the window. It is preferable to call say_with_pause
|
1080
|
+
# from user programs
|
1081
|
+
#
|
1028
1082
|
def say statement, config={}
|
1083
|
+
@window ||= _create_footer_window
|
1084
|
+
#@window.show unless @window.visible? # this will need to be hidden manually NOTE
|
1085
|
+
$log.debug "XXX: inside say win #{@window} !"
|
1029
1086
|
case statement
|
1030
1087
|
when Question
|
1031
1088
|
|
1032
1089
|
if config.has_key? :color_pair
|
1033
1090
|
$log.debug "INSIDE QUESTION 2 " if $log.debug?
|
1034
1091
|
else
|
1035
|
-
$log.debug "XXXX SAY using #{statement.color_pair} " if $log.debug?
|
1092
|
+
$log.debug "XXXX SAY using colorpair: #{statement.color_pair} " if $log.debug?
|
1036
1093
|
config[:color_pair] = statement.color_pair
|
1037
1094
|
end
|
1038
1095
|
else
|
@@ -1041,15 +1098,22 @@ module RubyCurses
|
|
1041
1098
|
statement = statement.to_str
|
1042
1099
|
template = ERB.new(statement, nil, "%")
|
1043
1100
|
statement = template.result(binding)
|
1044
|
-
|
1101
|
+
|
1045
1102
|
@prompt_length = statement.length # required by ask since it prints after
|
1046
1103
|
@statement = statement #
|
1047
1104
|
clear_line
|
1048
1105
|
print_str statement, config
|
1049
1106
|
end
|
1107
|
+
#
|
1108
|
+
# display some text at bottom and wait for a key before hiding window
|
1109
|
+
#
|
1050
1110
|
def say_with_pause statement, config={}
|
1111
|
+
@window ||= _create_footer_window
|
1051
1112
|
say statement, config
|
1113
|
+
@window.wrefresh
|
1114
|
+
Ncurses::Panel.update_panels
|
1052
1115
|
ch=@window.getchar()
|
1116
|
+
hide
|
1053
1117
|
end
|
1054
1118
|
# A helper method for sending the output stream and error and repeat
|
1055
1119
|
# of the question.
|
@@ -1065,10 +1129,14 @@ module RubyCurses
|
|
1065
1129
|
end
|
1066
1130
|
end
|
1067
1131
|
|
1132
|
+
#
|
1133
|
+
# Internal method for printing a string
|
1134
|
+
#
|
1068
1135
|
def print_str(text, config={})
|
1069
1136
|
win = config.fetch(:window, @window) # assuming its in App
|
1070
|
-
x = config.fetch :x, @message_row # Ncurses.LINES-1
|
1137
|
+
x = config.fetch :x, 0 # @message_row # Ncurses.LINES-1, 0 since one line window 2011-10-8
|
1071
1138
|
y = config.fetch :y, 0
|
1139
|
+
$log.debug "XXX: print_str #{win} with text : #{text} at #{x} #{y} "
|
1072
1140
|
color = config[:color_pair] || $datacolor
|
1073
1141
|
raise "no window for ask print in #{self.class} name: #{name} " unless win
|
1074
1142
|
color=Ncurses.COLOR_PAIR(color);
|
@@ -1151,12 +1219,14 @@ module RubyCurses
|
|
1151
1219
|
curpos -= 1 if curpos > 0
|
1152
1220
|
len -= 1 if len > @prompt_length
|
1153
1221
|
win.move r, c+len # since getchar is not going back on del and bs wmove to move FFIWINDOW
|
1222
|
+
win.wrefresh
|
1154
1223
|
next
|
1155
1224
|
when KEY_RIGHT
|
1156
1225
|
if curpos < str.length
|
1157
1226
|
curpos += 1 #if curpos < str.length
|
1158
1227
|
len += 1
|
1159
1228
|
win.move r, c+len # since getchar is not going back on del and bs
|
1229
|
+
win.wrefresh
|
1160
1230
|
end
|
1161
1231
|
next
|
1162
1232
|
when ?\C-a.getbyte(0)
|
@@ -1323,6 +1393,7 @@ module RubyCurses
|
|
1323
1393
|
print_str(@question.echo * str.length, :y => @prompt_length+0)
|
1324
1394
|
end
|
1325
1395
|
win.move r, c+len # more for arrow keys, curpos may not be end
|
1396
|
+
win.wrefresh # 2011-10-10
|
1326
1397
|
prevchar = ch
|
1327
1398
|
end
|
1328
1399
|
$log.debug "XXXW bottomline: after while loop"
|
@@ -1374,6 +1445,9 @@ module RubyCurses
|
|
1374
1445
|
if ret == 0
|
1375
1446
|
return @question.change_case(@question.remove_whitespace(str))
|
1376
1447
|
end
|
1448
|
+
if ret == -1
|
1449
|
+
raise Interrupt
|
1450
|
+
end
|
1377
1451
|
return ""
|
1378
1452
|
end
|
1379
1453
|
def agree( yes_or_no_question, character = nil )
|
@@ -1441,22 +1515,28 @@ module RubyCurses
|
|
1441
1515
|
end
|
1442
1516
|
# Allows a selection in which options are shown over prompt. As user types
|
1443
1517
|
# options are narrowed down.
|
1518
|
+
# NOTE: For a directory we are not showing a slash, so currently you
|
1519
|
+
# have to enter the slash manually when searching.
|
1444
1520
|
# FIXME we can put remarks in fron as in memacs such as [No matches] or [single completion]
|
1445
1521
|
# @param [Array] a list of items to select from
|
1446
1522
|
# NOTE: if you use this please copy it to your app. This does not conform to highline's
|
1447
1523
|
# choose, and I'd like to somehow get it to be identical.
|
1448
1524
|
#
|
1449
1525
|
def choose list1, config={}
|
1526
|
+
dirlist = true
|
1450
1527
|
case list1
|
1451
1528
|
when NilClass
|
1452
|
-
list1 = Dir.glob("*")
|
1529
|
+
#list1 = Dir.glob("*")
|
1530
|
+
list1 = Dir.glob("*").collect { |f| File.directory?(f) ? f+"/" : f }
|
1453
1531
|
when String
|
1454
|
-
list1 = Dir.glob(list1)
|
1532
|
+
list1 = Dir.glob(list1).collect { |f| File.directory?(f) ? f+"/" : f }
|
1455
1533
|
when Array
|
1534
|
+
dirlist = false
|
1456
1535
|
# let it be, that's how it should come
|
1457
1536
|
else
|
1458
1537
|
# Dir listing as default
|
1459
|
-
list1 = Dir.glob("*")
|
1538
|
+
#list1 = Dir.glob("*")
|
1539
|
+
list1 = Dir.glob("*").collect { |f| File.directory?(f) ? f+"/" : f }
|
1460
1540
|
end
|
1461
1541
|
require 'rbcurse/rcommandwindow'
|
1462
1542
|
prompt = config[:prompt] || "Choose: "
|
@@ -1466,12 +1546,24 @@ module RubyCurses
|
|
1466
1546
|
w = rc.window
|
1467
1547
|
rc.display_menu list1
|
1468
1548
|
# earlier wmove bombed, now move is (window.rb 121)
|
1469
|
-
str = ask(prompt) { |q| q.change_proc = Proc.new { |str| w.wmove(1,1) ; w.wclrtobot;
|
1549
|
+
str = ask(prompt) { |q| q.change_proc = Proc.new { |str| w.wmove(1,1) ; w.wclrtobot;
|
1550
|
+
l = list1.select{|e| e.index(str)==0} ;
|
1551
|
+
if (l.size == 0 || str[-1]=='/') && dirlist
|
1552
|
+
# used to help complete directories so we can drill up and down
|
1553
|
+
#l = Dir.glob(str+"*")
|
1554
|
+
l = Dir.glob(str +"*").collect { |f| File.directory?(f) ? f+"/" : f }
|
1555
|
+
end
|
1556
|
+
rc.display_menu l;
|
1557
|
+
l
|
1558
|
+
} }
|
1470
1559
|
# need some validation here that its in the list TODO
|
1471
1560
|
ensure
|
1472
1561
|
rc.destroy
|
1473
1562
|
rc = nil
|
1563
|
+
hide_bottomline # since we called ask() we need to close bottomline
|
1474
1564
|
end
|
1565
|
+
hide_bottomline # since we called ask() we need to close bottomline
|
1566
|
+
return str
|
1475
1567
|
end
|
1476
1568
|
def display_text_interactive text, config={}
|
1477
1569
|
require 'rbcurse/rcommandwindow'
|
@@ -1630,10 +1722,6 @@ if __FILE__ == $PROGRAM_NAME
|
|
1630
1722
|
App.new do
|
1631
1723
|
header = app_header "rbcurse 1.2.0", :text_center => "**** Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
|
1632
1724
|
message "Press F1 to exit from here"
|
1633
|
-
######## $tt.window = @window; $tt.message_row = @message_row
|
1634
|
-
#@tt = Bottomline.new @window, @message_row
|
1635
|
-
#extend Forwardable
|
1636
|
-
#def_delegators :@tt, :ask, :say, :agree, :choose
|
1637
1725
|
|
1638
1726
|
#stack :margin_top => 2, :margin => 5, :width => 30 do
|
1639
1727
|
#end # stack
|