rbcurse 1.4.1 → 1.5.0.pre1
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 +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/action.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'rbcurse/rwidget'
|
2
|
-
#include Ncurses # FFI 2011-09-8
|
3
|
-
include RubyCurses
|
4
|
-
module RubyCurses
|
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
|
14
|
-
class Action < Proc
|
15
|
-
include EventHandler
|
16
|
-
include ConfigSetup
|
17
|
-
# name used on button or menu
|
18
|
-
dsl_property :name
|
19
|
-
dsl_property :enabled
|
20
|
-
dsl_accessor :tooltip_text
|
21
|
-
dsl_accessor :help_text
|
22
|
-
dsl_accessor :mnemonic
|
23
|
-
dsl_accessor :accelerator
|
24
|
-
|
25
|
-
def initialize name, config={}, &block
|
26
|
-
super &block
|
27
|
-
@name = name
|
28
|
-
@name.freeze
|
29
|
-
@enabled = true
|
30
|
-
config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
|
31
|
-
@_events = [:FIRE]
|
32
|
-
end
|
33
|
-
def call
|
34
|
-
return unless @enabled
|
35
|
-
fire_handler :FIRE, self
|
36
|
-
super
|
37
|
-
end
|
38
|
-
end # class
|
39
|
-
end # module
|
40
|
-
|
data/lib/rbcurse/app.rb
DELETED
@@ -1,1374 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
* Name: App
|
3
|
-
* Description: Experimental Application class
|
4
|
-
* Author: rkumar (arunachalesha)
|
5
|
-
* file created 2010-09-04 22:10
|
6
|
-
Todo:
|
7
|
-
--------
|
8
|
-
* License:
|
9
|
-
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
10
|
-
|
11
|
-
=end
|
12
|
-
require 'logger'
|
13
|
-
require 'rbcurse'
|
14
|
-
|
15
|
-
require 'rbcurse/extras/bottomline'
|
16
|
-
$tt ||= RubyCurses::Bottomline.new
|
17
|
-
$tt.name = "$tt"
|
18
|
-
require 'forwardable'
|
19
|
-
module Kernel
|
20
|
-
extend Forwardable
|
21
|
-
def_delegators :$tt, :ask, :say, :agree, :choose, :numbered_menu, :display_text, :display_text_interactive, :display_list, :say_with_pause, :hide_bottomline, :say_with_wait
|
22
|
-
end
|
23
|
-
include RubyCurses
|
24
|
-
include RubyCurses::Utils
|
25
|
-
include Io
|
26
|
-
module RubyCurses
|
27
|
-
extend self
|
28
|
-
|
29
|
-
##
|
30
|
-
#
|
31
|
-
# @since 1.2.0
|
32
|
-
# TODO -
|
33
|
-
# / combo
|
34
|
-
# - popup
|
35
|
-
# - promptmenu
|
36
|
-
# - stack and flow should be objects in Form/App?, put in widget when creating
|
37
|
-
# - box / rect
|
38
|
-
# - para looks like a label that is more than one line, and calculates rows itself based on text
|
39
|
-
# - multicontainer
|
40
|
-
# - multitextview, multisplit
|
41
|
-
# - tabbedpane
|
42
|
-
# / table - more work regarding vim keys, also editable
|
43
|
-
# - margin - is left offset
|
44
|
-
# http://lethain.com/entry/2007/oct/15/getting-started-shoes-os-x/
|
45
|
-
#
|
46
|
-
|
47
|
-
class Widget
|
48
|
-
def changed *args, &block
|
49
|
-
bind :CHANGED, *args, &block
|
50
|
-
end
|
51
|
-
def leave *args, &block
|
52
|
-
bind :LEAVE, *args, &block
|
53
|
-
end
|
54
|
-
def enter *args, &block
|
55
|
-
bind :ENTER, *args, &block
|
56
|
-
end
|
57
|
-
# actually we already have command() for buttons
|
58
|
-
def click *args, &block
|
59
|
-
bind :PRESS, *args, &block
|
60
|
-
end
|
61
|
-
end
|
62
|
-
class CheckBox
|
63
|
-
# a little dicey XXX
|
64
|
-
def text(*val)
|
65
|
-
if val.empty?
|
66
|
-
@value ? @onvalue : @offvalue
|
67
|
-
else
|
68
|
-
super
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
# This is the Application class which does the job of setting up the
|
73
|
-
# environment, and closing it at the end.
|
74
|
-
class App
|
75
|
-
attr_reader :config
|
76
|
-
attr_reader :form
|
77
|
-
attr_reader :window
|
78
|
-
attr_writer :quit_key
|
79
|
-
# the row on which to prompt user for any inputs
|
80
|
-
#attr_accessor :prompt_row # 2011-10-17 14:06:22
|
81
|
-
|
82
|
-
extend Forwardable
|
83
|
-
def_delegators :$tt, :ask, :say, :agree, :choose, :numbered_menu, :display_text, :display_text_interactive, :display_list
|
84
|
-
|
85
|
-
# TODO: i should be able to pass window coords here in config
|
86
|
-
# :title
|
87
|
-
def initialize config={}, &block
|
88
|
-
#$log.debug " inside constructor of APP #{config} "
|
89
|
-
@config = config
|
90
|
-
@app_row = @app_col = 0
|
91
|
-
@stack = [] # stack's coordinates
|
92
|
-
@flowstack = []
|
93
|
-
@variables = {}
|
94
|
-
# if we are creating child objects then we will not use outer form. this object will manage
|
95
|
-
@current_object = []
|
96
|
-
@_system_commands = %w{ bind_global bind_component field_help_text }
|
97
|
-
|
98
|
-
init_vars
|
99
|
-
$log.debug "XXX APP CONFIG: #{@config} " if $log.debug?
|
100
|
-
run &block
|
101
|
-
end
|
102
|
-
def init_vars
|
103
|
-
@quit_key ||= FFI::NCurses::KEY_F10
|
104
|
-
# actually this should be maintained inside ncurses pack, so not loaded 2 times.
|
105
|
-
# this way if we call an app from existing program, App won't start ncurses.
|
106
|
-
unless $ncurses_started
|
107
|
-
init_ncurses
|
108
|
-
end
|
109
|
-
$lastline = Ncurses.LINES - 1
|
110
|
-
#@message_row = Ncurses.LINES-1
|
111
|
-
#@prompt_row = @message_row # hope to use for ask etc # 2011-10-17 14:06:27
|
112
|
-
unless $log
|
113
|
-
path = File.join(ENV["LOGDIR"] || "./" ,"rbc13.log")
|
114
|
-
file = File.open(path, File::WRONLY|File::TRUNC|File::CREAT)
|
115
|
-
$log = Logger.new(path)
|
116
|
-
$log.level = Logger::DEBUG # change to warn when you've tested your app.
|
117
|
-
colors = Ncurses.COLORS
|
118
|
-
$log.debug "START #{colors} colors --------- #{$0} win: #{@window} "
|
119
|
-
end
|
120
|
-
end
|
121
|
-
def logger; return $log; end
|
122
|
-
def close
|
123
|
-
raw_message_destroy
|
124
|
-
$log.debug " INSIDE CLOSE, #{@stop_ncurses_on_close} "
|
125
|
-
@window.destroy if !@window.nil?
|
126
|
-
$log.debug " INSIDE CLOSE, #{@stop_ncurses_on_close} "
|
127
|
-
if @stop_ncurses_on_close
|
128
|
-
$tt.destroy # added on 2011-10-9 since we created a window, but only hid it after use
|
129
|
-
VER::stop_ncurses
|
130
|
-
$log.debug " CLOSING NCURSES"
|
131
|
-
end
|
132
|
-
#p $error_message.value unless $error_message.value.nil?
|
133
|
-
$log.debug " CLOSING APP"
|
134
|
-
#end
|
135
|
-
end
|
136
|
-
# not sure, but user shuld be able to trap keystrokes if he wants
|
137
|
-
# but do i still call handle_key if he does, or give him total control.
|
138
|
-
# But loop is already called by framework
|
139
|
-
def loop &block
|
140
|
-
@form.repaint
|
141
|
-
@window.wrefresh
|
142
|
-
Ncurses::Panel.update_panels
|
143
|
-
@break_key = ?\C-q.getbyte(0)
|
144
|
-
while((ch = @window.getchar()) != @quit_key )
|
145
|
-
break if ch == @break_key
|
146
|
-
|
147
|
-
if @keyblock
|
148
|
-
str = keycode_tos ch
|
149
|
-
@keyblock.call(str.gsub(/-/, "_").to_sym) # not used ever
|
150
|
-
end
|
151
|
-
|
152
|
-
yield ch if block # <<<----
|
153
|
-
@form.handle_key ch
|
154
|
-
#@form.repaint # was this duplicate ?? handle calls repaint not needed
|
155
|
-
@window.wrefresh
|
156
|
-
end
|
157
|
-
end
|
158
|
-
# if calling loop separately better to call this, since it will shut off ncurses
|
159
|
-
# and print error on screen.
|
160
|
-
def safe_loop &block
|
161
|
-
begin
|
162
|
-
loop &block
|
163
|
-
rescue => ex
|
164
|
-
$log.debug( "APP.rb rescue reached ")
|
165
|
-
$log.debug( ex) if ex
|
166
|
-
$log.debug(ex.backtrace.join("\n")) if ex
|
167
|
-
ensure
|
168
|
-
close
|
169
|
-
# putting it here allows it to be printed on screen, otherwise it was not showing at all.
|
170
|
-
if ex
|
171
|
-
puts "========== EXCEPTION =========="
|
172
|
-
p ex
|
173
|
-
puts "==============================="
|
174
|
-
puts(ex.backtrace.join("\n"))
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
# returns a symbol of the key pressed
|
179
|
-
# e.g. :C_c for Ctrl-C
|
180
|
-
# :Space, :bs, :M_d etc
|
181
|
-
def keypress &block
|
182
|
-
@keyblock = block
|
183
|
-
end
|
184
|
-
# updates a global var with text. Calling app has to set up a Variable with that name and attach to
|
185
|
-
# a label so it can be printed.
|
186
|
-
def message text
|
187
|
-
$status_message.value = text # trying out 2011-10-9
|
188
|
-
#@message.value = text # 2011-10-17 14:07:01
|
189
|
-
end
|
190
|
-
# @deprecated please use {#status_line} instead of a message label
|
191
|
-
def message_row row
|
192
|
-
raise "Please use create_message_label first as message_label is no longer default behaviour" unless @message_label
|
193
|
-
@message_label.row = row
|
194
|
-
end
|
195
|
-
# during a process, when you wish to update status, since ordinarily the thread is busy
|
196
|
-
# and form does not get control back, so the window won't refresh.
|
197
|
-
# This will only update on keystroke since it uses statusline
|
198
|
-
# @deprecated please use {#status_line} instead of a message label
|
199
|
-
def message_immediate text
|
200
|
-
$log.warn "DEPRECATED, use message(), or say_with_pause, or say"
|
201
|
-
$status_message.value = text # trying out 2011-10-9 user needs to use in statusline command
|
202
|
-
# 2011-10-17 knocking off label, should be printed on status_line
|
203
|
-
end
|
204
|
-
# Usage: application is inside a long processing loop and wishes to print ongoing status
|
205
|
-
# NOTE: if you use this, you must use raw_message_destroy at some stage, after processing
|
206
|
-
# or on_leave of object.
|
207
|
-
# @deprecated Use say_with_pause or use rdialogs status_window, see test2.rb
|
208
|
-
def raw_message text, config={}, &blk
|
209
|
-
$raw_window ||= one_line_window last_line(), config, &blk
|
210
|
-
width = $raw_window.width == 0 ? FFI::NCurses.COLS : $raw_window.width
|
211
|
-
text = "%-*s" % [width, text]
|
212
|
-
|
213
|
-
$raw_window.attron(Ncurses.COLOR_PAIR($normalcolor) )
|
214
|
-
$raw_window.printstring 0,0,text, $normalcolor #, 'normal' if @title
|
215
|
-
$raw_window.wrefresh
|
216
|
-
|
217
|
-
end
|
218
|
-
def raw_message_destroy
|
219
|
-
if $raw_window
|
220
|
-
$raw_window.destroy
|
221
|
-
$raw_window = nil
|
222
|
-
end
|
223
|
-
end
|
224
|
-
# shows a simple progress bar on last row, using stdscr
|
225
|
-
# @param [Float, Array<Fixnum,Fixnum>] percentage, or part/total
|
226
|
-
# If Array of two numbers is given then also print part/total on left of bar
|
227
|
-
# @deprecated - don't use stdscr at all, use rdialogs status_window (see test2.rb)
|
228
|
-
def raw_progress arg
|
229
|
-
$log.warning "WARNING: don't use this method as it uses stdscr"
|
230
|
-
row = @message_label ? @message_label.row : Ncurses.LINES-1
|
231
|
-
s = nil
|
232
|
-
case arg
|
233
|
-
when Array
|
234
|
-
#calculate percentage
|
235
|
-
pc = (arg[0]*1.0)/arg[1]
|
236
|
-
# print items/total also
|
237
|
-
s = "%-10s" % "(#{arg[0]}/#{arg[1]})"
|
238
|
-
when
|
239
|
-
Float
|
240
|
-
pc = arg
|
241
|
-
end
|
242
|
-
scr = Ncurses.stdscr
|
243
|
-
endcol = Ncurses.COLS-1
|
244
|
-
startcol = endcol - 12
|
245
|
-
stext = ("=" * (pc*10).to_i)
|
246
|
-
text = "[" + "%-10s" % stext + "]"
|
247
|
-
Ncurses.mvprintw( row ,startcol-10, s) if s
|
248
|
-
Ncurses.mvprintw row ,startcol, text
|
249
|
-
#scr.refresh() # XXX FFI NW
|
250
|
-
|
251
|
-
end
|
252
|
-
# used only by LiveConsole, if enables in an app, usually only during testing.
|
253
|
-
def get_binding
|
254
|
-
return binding()
|
255
|
-
end
|
256
|
-
#
|
257
|
-
# suspends curses so you can play around on the shell
|
258
|
-
# or in cooked mode like Vim does. Expects a block to be passed.
|
259
|
-
# Purpose: you can print some stuff without creating a window, or
|
260
|
-
# just run shell commands without coming out.
|
261
|
-
# NOTE: if you pass clear as true, then the screen will be cleared
|
262
|
-
# and you can use puts or print to print. You may have to flush.
|
263
|
-
# However, with clear as false, the screen will not be cleared. You
|
264
|
-
# will have to print using printw, and if you expect user input
|
265
|
-
# you must do a "system /bin/stty sane"
|
266
|
-
# If you print stuff, you will have to put a getch() or system("read")
|
267
|
-
# to pause the screen.
|
268
|
-
def suspend clear=true
|
269
|
-
return unless block_given?
|
270
|
-
Ncurses.def_prog_mode
|
271
|
-
if clear
|
272
|
-
Ncurses.endwin
|
273
|
-
# NOTE: avoid false since screen remains half off
|
274
|
-
# too many issues
|
275
|
-
else
|
276
|
-
system "/bin/stty sane"
|
277
|
-
end
|
278
|
-
yield if block_given?
|
279
|
-
Ncurses.reset_prog_mode
|
280
|
-
if !clear
|
281
|
-
# Hope we don't screw your terminal up with this constantly.
|
282
|
-
VER::stop_ncurses
|
283
|
-
VER::start_ncurses
|
284
|
-
#@form.reset_all # not required
|
285
|
-
end
|
286
|
-
@form.repaint
|
287
|
-
@window.wrefresh
|
288
|
-
Ncurses::Panel.update_panels
|
289
|
-
end
|
290
|
-
def get_all_commands
|
291
|
-
opts = @_system_commands.dup
|
292
|
-
if respond_to? :get_commands
|
293
|
-
opts.push(*get_commands())
|
294
|
-
end
|
295
|
-
opts
|
296
|
-
end
|
297
|
-
def display_app_help
|
298
|
-
if respond_to? :help_text
|
299
|
-
arr = help_text
|
300
|
-
else
|
301
|
-
arr = []
|
302
|
-
arr << " NO HELP SPECIFIED FOR APP "
|
303
|
-
arr << " "
|
304
|
-
arr << " --- General help --- "
|
305
|
-
arr << " F10 - exit application "
|
306
|
-
arr << " Alt-x - select commands "
|
307
|
-
arr << " : - select commands "
|
308
|
-
arr << " "
|
309
|
-
end
|
310
|
-
case arr
|
311
|
-
when String
|
312
|
-
arr = arr.split("\n")
|
313
|
-
when Array
|
314
|
-
end
|
315
|
-
w = arr.max_by(&:length).length
|
316
|
-
|
317
|
-
require 'rbcurse/extras/viewer'
|
318
|
-
RubyCurses::Viewer.view(arr, :layout => [2, 10, [4+arr.size, 24].min, w+2],:close_key => KEY_RETURN, :title => "<Enter> to close", :print_footer => true) do |t|
|
319
|
-
# you may configure textview further here.
|
320
|
-
#t.suppress_borders true
|
321
|
-
#t.color = :black
|
322
|
-
#t.bgcolor = :white
|
323
|
-
# or
|
324
|
-
t.attr = :reverse
|
325
|
-
end
|
326
|
-
end
|
327
|
-
# bind a key to a method at global (form) level
|
328
|
-
# Note that individual component may be overriding this.
|
329
|
-
# FIXME: why are we using rawmessage and then getchar when ask would suffice
|
330
|
-
def bind_global
|
331
|
-
opts = get_all_commands
|
332
|
-
cmd = ask("Select a command (TAB for choices) : ", opts)
|
333
|
-
if cmd.nil? || cmd == ""
|
334
|
-
say_with_pause "Aborted."
|
335
|
-
return
|
336
|
-
end
|
337
|
-
key = []
|
338
|
-
str = ""
|
339
|
-
raw_message "Enter one or 2 keys. Finish with ENTER. Enter first key:"
|
340
|
-
#raw_message "Enter first key:"
|
341
|
-
ch = @window.getchar()
|
342
|
-
raw_message_destroy
|
343
|
-
if [KEY_ENTER, 10, 13, ?\C-g.getbyte(0)].include? ch
|
344
|
-
say_with_pause "Aborted."
|
345
|
-
return
|
346
|
-
end
|
347
|
-
key << ch
|
348
|
-
str << keycode_tos(ch)
|
349
|
-
raw_message "Enter second key or hit return:"
|
350
|
-
ch = @window.getchar()
|
351
|
-
raw_message_destroy
|
352
|
-
if ch == 3 || ch == ?\C-g.getbyte(0)
|
353
|
-
say_with_pause "Aborted."
|
354
|
-
return
|
355
|
-
end
|
356
|
-
if ch == 10 || ch == KEY_ENTER || ch == 13
|
357
|
-
else
|
358
|
-
key << ch
|
359
|
-
str << keycode_tos(ch)
|
360
|
-
end
|
361
|
-
if !key.empty?
|
362
|
-
say_with_pause "Binding #{cmd} to #{str} "
|
363
|
-
key = key[0] if key.size == 1
|
364
|
-
#@form.bind_key(key, cmd.to_sym) # not finding it, getting called by that comp
|
365
|
-
@form.bind_key(key){ send(cmd.to_sym) }
|
366
|
-
end
|
367
|
-
#message "Bound #{str} to #{cmd} "
|
368
|
-
raw_message_destroy
|
369
|
-
end
|
370
|
-
def bind_component
|
371
|
-
say_with_pause "Todo. <press>"
|
372
|
-
# the idea here is to get the current component
|
373
|
-
# and bind some keys to some methods.
|
374
|
-
# however, how do we divine the methods we can map to
|
375
|
-
# and also in some cases the components itself has multiple components
|
376
|
-
end
|
377
|
-
# displays help_text associated with field. 2011-10-15
|
378
|
-
def field_help_text
|
379
|
-
f = @form.get_current_field
|
380
|
-
if f.respond_to?('help_text')
|
381
|
-
h = f.help_text
|
382
|
-
alert "#{h}"
|
383
|
-
else
|
384
|
-
alert "Could not get field #{f} or does not respond to helptext"
|
385
|
-
end
|
386
|
-
end
|
387
|
-
# prompts user for a command. we need to get this back to the calling app
|
388
|
-
# or have some block stuff TODO
|
389
|
-
# Actually, this is naive, you would want to pass some values in like current data value
|
390
|
-
# or lines ??
|
391
|
-
# Also may want command completion, or help so all commands can be displayed
|
392
|
-
def get_command_from_user choices=["quit"]
|
393
|
-
#code, str = rbgetstr(@window, $lastline, 0, "", 80, :default => ":")
|
394
|
-
#return unless code == 0
|
395
|
-
@_command_history ||= Array.new
|
396
|
-
str = ask("Cmd: ", choices) { |q| q.default = @_previous_command; q.history = @_command_history }
|
397
|
-
@_command_history << str unless @_command_history.include? str
|
398
|
-
# shell the command
|
399
|
-
if str =~ /^!/
|
400
|
-
str = str[1..-1]
|
401
|
-
suspend(false) {
|
402
|
-
#system(str);
|
403
|
-
$log.debug "XXX STR #{str} " if $log.debug?
|
404
|
-
|
405
|
-
output=`#{str}`
|
406
|
-
system("echo ' ' ");
|
407
|
-
$log.debug "XXX output #{output} " if $log.debug?
|
408
|
-
system("echo '#{output}' ");
|
409
|
-
system("echo Press Enter to continue.");
|
410
|
-
system("read");
|
411
|
-
}
|
412
|
-
return nil # i think
|
413
|
-
else
|
414
|
-
# TODO
|
415
|
-
# here's where we can take internal commands
|
416
|
-
#alert "[#{str}] string did not match :!"
|
417
|
-
str = str.to_s #= str[1..-1]
|
418
|
-
cmdline = str.split
|
419
|
-
cmd = cmdline.shift #.to_sym
|
420
|
-
return unless cmd # added 2011-09-11 FFI
|
421
|
-
if respond_to?(cmd, true)
|
422
|
-
if cmd == "close"
|
423
|
-
throw :close # other seg faults in del_panel window.destroy executes 2x
|
424
|
-
else
|
425
|
-
res = send cmd, *cmdline
|
426
|
-
end
|
427
|
-
else
|
428
|
-
alert "#{self.class} does not respond to #{cmd} "
|
429
|
-
ret = false
|
430
|
-
ret = execute_this(cmd, *cmdline) if respond_to?(:execute_this, true)
|
431
|
-
say_with_pause("#{self.class} does not respond to #{cmd} ", :color_pair => $promptcolor) unless ret
|
432
|
-
# should be able to say in red as error
|
433
|
-
end
|
434
|
-
end
|
435
|
-
end
|
436
|
-
#
|
437
|
-
# @group methods to create widgets easily
|
438
|
-
#
|
439
|
-
# process arguments based on datatype, perhaps making configuration
|
440
|
-
# of some components easier for caller avoiding too much boiler plate code
|
441
|
-
#
|
442
|
-
# create a field
|
443
|
-
def field *args, &block
|
444
|
-
config = {}
|
445
|
-
events = [ :CHANGED, :LEAVE, :ENTER, :CHANGE ]
|
446
|
-
block_event = :CHANGED # LEAVE, ENTER, CHANGE
|
447
|
-
|
448
|
-
_process_args args, config, block_event, events
|
449
|
-
config.delete(:title)
|
450
|
-
_position config
|
451
|
-
# hope next line doesn't bonk anything
|
452
|
-
config[:display_length] ||= @stack.last.width if @stack.last # added here not sure 2010-11-17 18:43
|
453
|
-
field = Field.new @form, config
|
454
|
-
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
455
|
-
if block
|
456
|
-
field.bind(block_event, &block)
|
457
|
-
end
|
458
|
-
return field
|
459
|
-
end
|
460
|
-
#instance_eval &block if block_given?
|
461
|
-
# or
|
462
|
-
#@blk = block # for later execution using @blk.call()
|
463
|
-
#colorlabel = Label.new @form, {'text' => "Select a color:", "row" => row, "col" => col, "color"=>"cyan", "mnemonic" => 'S'}
|
464
|
-
#var = RubyCurses::Label.new @form, {'text_variable' => $results, "row" => r, "col" => fc}
|
465
|
-
|
466
|
-
def label *args
|
467
|
-
events = block_event = nil
|
468
|
-
config = {}
|
469
|
-
_process_args args, config, block_event, events
|
470
|
-
config[:text] ||= config[:name]
|
471
|
-
config[:height] ||= 1
|
472
|
-
config.delete(:title)
|
473
|
-
_position(config)
|
474
|
-
label = Label.new @form, config
|
475
|
-
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
476
|
-
return label
|
477
|
-
end
|
478
|
-
alias :text :label
|
479
|
-
def button *args, &block
|
480
|
-
config = {}
|
481
|
-
events = [ :PRESS, :LEAVE, :ENTER ]
|
482
|
-
block_event = :PRESS
|
483
|
-
|
484
|
-
_process_args args, config, block_event, events
|
485
|
-
config[:text] ||= config[:name]
|
486
|
-
config.delete(:title)
|
487
|
-
# flow gets precedence over stack
|
488
|
-
_position(config)
|
489
|
-
button = Button.new @form, config
|
490
|
-
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
491
|
-
if block
|
492
|
-
button.bind(block_event, &block)
|
493
|
-
end
|
494
|
-
return button
|
495
|
-
end
|
496
|
-
#
|
497
|
-
# create a list
|
498
|
-
# Since we are mouseless, one can traverse without selection. So we have a different
|
499
|
-
# way of selecting row/s and traversal. XXX this aspect of LB's has always troubled me hugely.
|
500
|
-
def list_box *args, &block
|
501
|
-
config = {}
|
502
|
-
# TODO confirm events
|
503
|
-
# listdataevent has interval added and interval removed, due to multiple
|
504
|
-
# selection, we have to make that simple for user here.
|
505
|
-
events = [ :LEAVE, :ENTER, :ENTER_ROW, :LEAVE_ROW, :LIST_DATA_EVENT ]
|
506
|
-
# TODO how to do this so he gets selected row easily
|
507
|
-
block_event = :ENTER_ROW
|
508
|
-
|
509
|
-
_process_args args, config, block_event, events
|
510
|
-
# naive defaults, since list could be large or have very long items
|
511
|
-
# usually user will provide
|
512
|
-
if !config.has_key? :height
|
513
|
-
ll = 0
|
514
|
-
ll = config[:list].length + 2 if config.has_key? :list
|
515
|
-
config[:height] ||= ll
|
516
|
-
config[:height] = 15 if config[:height] > 20
|
517
|
-
end
|
518
|
-
if @current_object.empty?
|
519
|
-
$log.debug "1 APP LB w: #{config[:width]} ,#{config[:name]} "
|
520
|
-
config[:width] ||= @stack.last.width if @stack.last
|
521
|
-
$log.debug "2 APP LB w: #{config[:width]} "
|
522
|
-
config[:width] ||= longest_in_list(config[:list])+2
|
523
|
-
$log.debug "3 APP LB w: #{config[:width]} "
|
524
|
-
end
|
525
|
-
# if no width given, expand to flows width XXX SHOULD BE NOT EXPAND ?
|
526
|
-
#config[:width] ||= @stack.last.width if @stack.last
|
527
|
-
#if config.has_key? :choose
|
528
|
-
config[:default_values] = config.delete :choose
|
529
|
-
# we make the default single unless specified
|
530
|
-
config[:selection_mode] = :single unless config.has_key? :selection_mode
|
531
|
-
if @current_object.empty?
|
532
|
-
if @instack
|
533
|
-
# most likely you won't have row and col. should we check or just go ahead
|
534
|
-
col = @stack.last.margin
|
535
|
-
config[:row] = @app_row
|
536
|
-
config[:col] = col
|
537
|
-
@app_row += config[:height] # this needs to take into account height of prev object
|
538
|
-
end
|
539
|
-
end
|
540
|
-
useform = nil
|
541
|
-
useform = @form if @current_object.empty?
|
542
|
-
field = Listbox.new useform, config
|
543
|
-
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
544
|
-
if block
|
545
|
-
# this way you can't pass params to the block
|
546
|
-
field.bind(block_event, &block)
|
547
|
-
end
|
548
|
-
return field
|
549
|
-
end
|
550
|
-
|
551
|
-
# toggle button
|
552
|
-
def toggle *args, &block
|
553
|
-
config = {}
|
554
|
-
# TODO confirm events
|
555
|
-
events = [ :PRESS, :LEAVE, :ENTER ]
|
556
|
-
block_event = :PRESS
|
557
|
-
_process_args args, config, block_event, events
|
558
|
-
config[:text] ||= longest_in_list2( [config[:onvalue], config[:offvalue]])
|
559
|
-
#config[:onvalue] # needed for flow, we need a better way FIXME
|
560
|
-
_position(config)
|
561
|
-
toggle = ToggleButton.new @form, config
|
562
|
-
if block
|
563
|
-
toggle.bind(block_event, &block)
|
564
|
-
end
|
565
|
-
return toggle
|
566
|
-
end
|
567
|
-
# check button
|
568
|
-
def check *args, &block
|
569
|
-
config = {}
|
570
|
-
# TODO confirm events
|
571
|
-
events = [ :PRESS, :LEAVE, :ENTER ]
|
572
|
-
block_event = :PRESS
|
573
|
-
_process_args args, config, block_event, events
|
574
|
-
_position(config)
|
575
|
-
toggle = CheckBox.new @form, config
|
576
|
-
if block
|
577
|
-
toggle.bind(block_event, &block)
|
578
|
-
end
|
579
|
-
return toggle
|
580
|
-
end
|
581
|
-
# radio button
|
582
|
-
def radio *args, &block
|
583
|
-
config = {}
|
584
|
-
# TODO confirm events
|
585
|
-
events = [ :PRESS, :LEAVE, :ENTER ]
|
586
|
-
block_event = :PRESS
|
587
|
-
_process_args args, config, block_event, events
|
588
|
-
a = config[:group]
|
589
|
-
# FIXME we should check if user has set a varialbe in :variable.
|
590
|
-
# we should create a variable, so he can use it if he wants.
|
591
|
-
if @variables.has_key? a
|
592
|
-
v = @variables[a]
|
593
|
-
else
|
594
|
-
v = Variable.new
|
595
|
-
@variables[a] = v
|
596
|
-
end
|
597
|
-
config[:variable] = v
|
598
|
-
config.delete(:group)
|
599
|
-
_position(config)
|
600
|
-
radio = RadioButton.new @form, config
|
601
|
-
if block
|
602
|
-
radio.bind(block_event, &block)
|
603
|
-
end
|
604
|
-
return radio
|
605
|
-
end
|
606
|
-
# editable text area
|
607
|
-
def textarea *args, &block
|
608
|
-
require 'rbcurse/rtextarea'
|
609
|
-
config = {}
|
610
|
-
# TODO confirm events many more
|
611
|
-
events = [ :CHANGE, :LEAVE, :ENTER ]
|
612
|
-
block_event = events[0]
|
613
|
-
_process_args args, config, block_event, events
|
614
|
-
config[:width] = config[:display_length] unless config.has_key? :width
|
615
|
-
_position(config)
|
616
|
-
# if no width given, expand to flows width
|
617
|
-
config[:width] ||= @stack.last.width if @stack.last
|
618
|
-
useform = nil
|
619
|
-
useform = @form if @current_object.empty?
|
620
|
-
w = TextArea.new useform, config
|
621
|
-
if block
|
622
|
-
w.bind(block_event, &block)
|
623
|
-
end
|
624
|
-
return w
|
625
|
-
end
|
626
|
-
# similar definitions for textview and resultsettextview
|
627
|
-
# NOTE This is not allowing me to send blocks,
|
628
|
-
# so do not use for containers
|
629
|
-
{
|
630
|
-
'rbcurse/rtextview' => 'TextView',
|
631
|
-
'rbcurse/experimental/resultsettextview' => 'ResultsetTextView',
|
632
|
-
'rbcurse/rcontainer' => 'Container',
|
633
|
-
'rbcurse/extras/rcontainer2' => 'Container2',
|
634
|
-
}.each_pair {|k,p|
|
635
|
-
eval(
|
636
|
-
"def #{p.downcase} *args, &block
|
637
|
-
require \"#{k}\"
|
638
|
-
config = {}
|
639
|
-
# TODO confirm events many more
|
640
|
-
events = [ :PRESS, :LEAVE, :ENTER ]
|
641
|
-
block_event = events[0]
|
642
|
-
_process_args args, config, block_event, events
|
643
|
-
config[:width] = config[:display_length] unless config.has_key? :width
|
644
|
-
_position(config)
|
645
|
-
# if no width given, expand to flows width
|
646
|
-
config[:width] ||= @stack.last.width if @stack.last
|
647
|
-
raise \"height needed for #{p.downcase}\" if !config.has_key? :height
|
648
|
-
useform = nil
|
649
|
-
useform = @form if @current_object.empty?
|
650
|
-
w = #{p}.new useform, config
|
651
|
-
if block
|
652
|
-
w.bind(block_event, &block)
|
653
|
-
end
|
654
|
-
return w
|
655
|
-
end"
|
656
|
-
)
|
657
|
-
}
|
658
|
-
# progress bar
|
659
|
-
def progress *args, &block
|
660
|
-
require 'rbcurse/rprogress'
|
661
|
-
config = {}
|
662
|
-
# TODO confirm events many more
|
663
|
-
events = [ :CHANGE, :LEAVE, :ENTER ]
|
664
|
-
block_event = nil
|
665
|
-
_process_args args, config, block_event, events
|
666
|
-
config[:width] = config[:display_length] || 10 unless config.has_key? :width
|
667
|
-
_position(config)
|
668
|
-
w = Progress.new @form, config
|
669
|
-
#if block
|
670
|
-
#w.bind(block_event, &block)
|
671
|
-
#end
|
672
|
-
return w
|
673
|
-
end
|
674
|
-
|
675
|
-
# table widget
|
676
|
-
# @example
|
677
|
-
# data = [["Roger",16,"SWI"], ["Phillip",1, "DEU"]]
|
678
|
-
# colnames = ["Name", "Wins", "Place"]
|
679
|
-
# t = table :width => 40, :height => 10, :columns => colnames, :data => data, :estimate_widths => true
|
680
|
-
# other options are :column_widths => [12,4,12]
|
681
|
-
# :size_to_fit => true
|
682
|
-
def table *args, &block
|
683
|
-
require 'rbcurse/rtable'
|
684
|
-
config = {}
|
685
|
-
# TODO confirm events many more
|
686
|
-
events = [ :ENTER_ROW, :LEAVE, :ENTER ]
|
687
|
-
block_event = events[0]
|
688
|
-
_process_args args, config, block_event, events
|
689
|
-
# if user is leaving out width, then we don't want it in config
|
690
|
-
# else Widget will put a value of 10 as default, overriding what we've calculated
|
691
|
-
if config.has_key? :display_length
|
692
|
-
config[:width] = config[:display_length] unless config.has_key? :width
|
693
|
-
end
|
694
|
-
ext = config.delete :extended_keys
|
695
|
-
|
696
|
-
model = nil
|
697
|
-
_position(config)
|
698
|
-
# if no width given, expand to flows width
|
699
|
-
config[:width] ||= @stack.last.width if @stack.last
|
700
|
-
w = Table.new @form, config
|
701
|
-
if ext
|
702
|
-
require 'rbcurse/extras/tableextended'
|
703
|
-
# so we can increase and decrease column width using keys
|
704
|
-
w.extend TableExtended
|
705
|
-
w.bind_key(?w){ w.next_column }
|
706
|
-
w.bind_key(?b){ w.previous_column }
|
707
|
-
w.bind_key(?+) { w.increase_column }
|
708
|
-
w.bind_key(?-) { w.decrease_column }
|
709
|
-
w.bind_key([?d, ?d]) { w.table_model.delete_at w.current_index }
|
710
|
-
w.bind_key(?u) { w.table_model.undo w.current_index}
|
711
|
-
end
|
712
|
-
if block
|
713
|
-
w.bind(block_event, &block)
|
714
|
-
end
|
715
|
-
return w
|
716
|
-
end
|
717
|
-
# print a title on first row
|
718
|
-
def title string, config={}
|
719
|
-
## TODO center it
|
720
|
-
@window.printstring 1, 30, string, $normalcolor, 'reverse'
|
721
|
-
end
|
722
|
-
# print a sutitle on second row
|
723
|
-
def subtitle string, config={}
|
724
|
-
@window.printstring 2, 30, string, $datacolor, 'normal'
|
725
|
-
end
|
726
|
-
# menu bar
|
727
|
-
def menubar &block
|
728
|
-
require 'rbcurse/rmenu'
|
729
|
-
RubyCurses::MenuBar.new &block
|
730
|
-
end
|
731
|
-
|
732
|
-
# creates a blank row
|
733
|
-
def blank rows=1, config={}
|
734
|
-
@app_row += rows
|
735
|
-
end
|
736
|
-
# displays a horizontal line
|
737
|
-
# takes col (column to start from) from current stack
|
738
|
-
# take row from app_row
|
739
|
-
#
|
740
|
-
# requires width to be passed in config, else defaults to 20
|
741
|
-
# @example
|
742
|
-
# hline :width => 55
|
743
|
-
def hline config={}
|
744
|
-
row = config[:row] || @app_row
|
745
|
-
width = config[:width] || 20
|
746
|
-
_position config
|
747
|
-
col = config[:col] || 1
|
748
|
-
@color_pair = config[:color_pair] || $datacolor
|
749
|
-
@attrib = config[:attrib] || Ncurses::A_NORMAL
|
750
|
-
@window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)
|
751
|
-
@window.mvwhline( row, col, FFI::NCurses::ACS_HLINE, width)
|
752
|
-
@window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)
|
753
|
-
@app_row += 1
|
754
|
-
end
|
755
|
-
def app_header title, config={}, &block
|
756
|
-
require 'rbcurse/applicationheader'
|
757
|
-
header = ApplicationHeader.new @form, title, config, &block
|
758
|
-
end
|
759
|
-
|
760
|
-
# prints pine-like key labels
|
761
|
-
def dock labels, config={}, &block
|
762
|
-
require 'rbcurse/keylabelprinter'
|
763
|
-
klp = RubyCurses::KeyLabelPrinter.new @form, labels, config, &block
|
764
|
-
end
|
765
|
-
|
766
|
-
def link *args, &block
|
767
|
-
require 'rbcurse/extras/rlink'
|
768
|
-
config = {}
|
769
|
-
events = [ :PRESS, :LEAVE, :ENTER ]
|
770
|
-
block_event = :PRESS
|
771
|
-
_process_args args, config, block_event, events
|
772
|
-
_position(config)
|
773
|
-
config[:text] ||= config.delete :title
|
774
|
-
config[:highlight_foreground] = "yellow"
|
775
|
-
config[:highlight_background] = "red"
|
776
|
-
toggle = Link.new @form, config
|
777
|
-
if block
|
778
|
-
toggle.bind(block_event, toggle, &block)
|
779
|
-
end
|
780
|
-
return toggle
|
781
|
-
end
|
782
|
-
def menulink *args, &block
|
783
|
-
require 'rbcurse/extras/rmenulink'
|
784
|
-
config = {}
|
785
|
-
events = [ :PRESS, :LEAVE, :ENTER ]
|
786
|
-
block_event = :PRESS
|
787
|
-
_process_args args, config, block_event, events
|
788
|
-
_position(config)
|
789
|
-
config[:text] ||= config.delete :title
|
790
|
-
config[:highlight_foreground] = "yellow"
|
791
|
-
config[:highlight_background] = "red"
|
792
|
-
toggle = MenuLink.new @form, config
|
793
|
-
if block
|
794
|
-
toggle.bind(block_event, toggle, &block)
|
795
|
-
end
|
796
|
-
return toggle
|
797
|
-
end
|
798
|
-
def splitpane *args, &block
|
799
|
-
require 'rbcurse/rsplitpane2'
|
800
|
-
config = {}
|
801
|
-
events = [ :PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
802
|
-
block_event = events[0]
|
803
|
-
_process_args args, config, block_event, events
|
804
|
-
_position(config)
|
805
|
-
# if no width given, expand to flows width
|
806
|
-
config[:width] ||= @stack.last.width if @stack.last
|
807
|
-
config.delete :title
|
808
|
-
useform = nil
|
809
|
-
useform = @form if @current_object.empty?
|
810
|
-
|
811
|
-
w = SplitPane.new useform, config
|
812
|
-
#if block
|
813
|
-
#w.bind(block_event, w, &block)
|
814
|
-
#end
|
815
|
-
if block_given?
|
816
|
-
@current_object << w
|
817
|
-
#instance_eval &block if block_given?
|
818
|
-
yield w
|
819
|
-
@current_object.pop
|
820
|
-
end
|
821
|
-
return w
|
822
|
-
end
|
823
|
-
def multisplit *args, &block
|
824
|
-
require 'rbcurse/rmultisplit'
|
825
|
-
config = {}
|
826
|
-
events = [ :PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
827
|
-
block_event = events[0]
|
828
|
-
_process_args args, config, block_event, events
|
829
|
-
_position(config)
|
830
|
-
# if no width given, expand to flows width
|
831
|
-
config[:width] ||= @stack.last.width if @stack.last
|
832
|
-
config.delete :title
|
833
|
-
useform = nil
|
834
|
-
useform = @form if @current_object.empty?
|
835
|
-
|
836
|
-
w = MultiSplit.new useform, config
|
837
|
-
#if block
|
838
|
-
#w.bind(block_event, w, &block)
|
839
|
-
#end
|
840
|
-
if block_given?
|
841
|
-
@current_object << w
|
842
|
-
#instance_eval &block if block_given?
|
843
|
-
yield w
|
844
|
-
@current_object.pop
|
845
|
-
end
|
846
|
-
return w
|
847
|
-
end
|
848
|
-
def tree *args, &block
|
849
|
-
require 'rbcurse/rtree'
|
850
|
-
config = {}
|
851
|
-
events = [:TREE_WILL_EXPAND_EVENT, :TREE_EXPANDED_EVENT, :TREE_SELECTION_EVENT, :PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
852
|
-
block_event = nil
|
853
|
-
_process_args args, config, block_event, events
|
854
|
-
config[:height] ||= 10
|
855
|
-
_position(config)
|
856
|
-
# if no width given, expand to flows width
|
857
|
-
config[:width] ||= @stack.last.width if @stack.last
|
858
|
-
#config.delete :title
|
859
|
-
useform = nil
|
860
|
-
useform = @form if @current_object.empty?
|
861
|
-
|
862
|
-
w = Tree.new useform, config, &block
|
863
|
-
return w
|
864
|
-
end
|
865
|
-
def vimsplit *args, &block
|
866
|
-
require 'rbcurse/rvimsplit'
|
867
|
-
config = {}
|
868
|
-
#TODO check these
|
869
|
-
events = [:PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
870
|
-
block_event = nil
|
871
|
-
_process_args args, config, block_event, events
|
872
|
-
config[:height] ||= 10
|
873
|
-
_position(config)
|
874
|
-
# if no width given, expand to flows width
|
875
|
-
config[:width] ||= @stack.last.width if @stack.last
|
876
|
-
#config.delete :title
|
877
|
-
useform = nil
|
878
|
-
useform = @form if @current_object.empty?
|
879
|
-
|
880
|
-
w = VimSplit.new useform, config # NO BLOCK GIVEN
|
881
|
-
if block_given?
|
882
|
-
@current_object << w
|
883
|
-
#instance_eval &block if block_given?
|
884
|
-
yield w
|
885
|
-
@current_object.pop
|
886
|
-
end
|
887
|
-
return w
|
888
|
-
end
|
889
|
-
# create a readonly list
|
890
|
-
def basiclist *args, &block
|
891
|
-
require 'rbcurse/rbasiclistbox'
|
892
|
-
config = {}
|
893
|
-
#TODO check these
|
894
|
-
events = [ :LEAVE, :ENTER, :ENTER_ROW, :LEAVE_ROW, :LIST_DATA_EVENT ]
|
895
|
-
# TODO how to do this so he gets selected row easily
|
896
|
-
block_event = :ENTER_ROW
|
897
|
-
_process_args args, config, block_event, events
|
898
|
-
# some guesses at a sensible height for listbox
|
899
|
-
if !config.has_key? :height
|
900
|
-
ll = 0
|
901
|
-
ll = config[:list].length + 2 if config.has_key? :list
|
902
|
-
config[:height] ||= ll
|
903
|
-
config[:height] = 15 if config[:height] > 20
|
904
|
-
end
|
905
|
-
_position(config)
|
906
|
-
# if no width given, expand to flows width
|
907
|
-
config[:width] ||= @stack.last.width if @stack.last
|
908
|
-
config[:width] ||= longest_in_list(config[:list])+2
|
909
|
-
#config.delete :title
|
910
|
-
#config[:default_values] = config.delete :choose
|
911
|
-
config[:selection_mode] = :single unless config.has_key? :selection_mode
|
912
|
-
useform = nil
|
913
|
-
useform = @form if @current_object.empty?
|
914
|
-
|
915
|
-
w = BasicListbox.new useform, config # NO BLOCK GIVEN
|
916
|
-
if block_given?
|
917
|
-
field.bind(block_event, &block)
|
918
|
-
end
|
919
|
-
return w
|
920
|
-
end
|
921
|
-
def master_detail *args, &block
|
922
|
-
require 'rbcurse/extras/masterdetail'
|
923
|
-
config = {}
|
924
|
-
events = [:PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
925
|
-
block_event = nil
|
926
|
-
_process_args args, config, block_event, events
|
927
|
-
#config[:height] ||= 10
|
928
|
-
_position(config)
|
929
|
-
# if no width given, expand to flows width
|
930
|
-
config[:width] ||= @stack.last.width if @stack.last
|
931
|
-
#config.delete :title
|
932
|
-
useform = nil
|
933
|
-
useform = @form if @current_object.empty?
|
934
|
-
|
935
|
-
w = MasterDetail.new useform, config # NO BLOCK GIVEN
|
936
|
-
if block_given?
|
937
|
-
@current_object << w
|
938
|
-
yield_or_eval &block
|
939
|
-
@current_object.pop
|
940
|
-
end
|
941
|
-
return w
|
942
|
-
end
|
943
|
-
# creates a simple readonly table, that allows users to click on rows
|
944
|
-
# and also on the header. Header clicking is for column-sorting.
|
945
|
-
def tabular_widget *args, &block
|
946
|
-
require 'rbcurse/extras/tabularwidget'
|
947
|
-
config = {}
|
948
|
-
events = [:PROPERTY_CHANGE, :LEAVE, :ENTER, :CHANGE, :ENTER_ROW, :PRESS ]
|
949
|
-
block_event = nil
|
950
|
-
_process_args args, config, block_event, events
|
951
|
-
config[:height] ||= 10 # not sure if this should be here
|
952
|
-
_position(config)
|
953
|
-
# if no width given, expand to stack width
|
954
|
-
config[:width] ||= @stack.last.width if @stack.last
|
955
|
-
#config.delete :title
|
956
|
-
useform = nil
|
957
|
-
useform = @form if @current_object.empty?
|
958
|
-
|
959
|
-
w = TabularWidget.new useform, config # NO BLOCK GIVEN
|
960
|
-
if block_given?
|
961
|
-
@current_object << w
|
962
|
-
yield_or_eval &block
|
963
|
-
@current_object.pop
|
964
|
-
end
|
965
|
-
return w
|
966
|
-
end
|
967
|
-
# scrollbar attached to the right of a parent object
|
968
|
-
def scrollbar *args, &block
|
969
|
-
require 'rbcurse/extras/scrollbar'
|
970
|
-
config = {}
|
971
|
-
events = [:PROPERTY_CHANGE, :LEAVE, :ENTER ] # # none really at present
|
972
|
-
block_event = nil
|
973
|
-
_process_args args, config, block_event, events
|
974
|
-
raise "parent needed for scrollbar" if !config.has_key? :parent
|
975
|
-
useform = nil
|
976
|
-
useform = @form if @current_object.empty?
|
977
|
-
sb = Scrollbar.new useform, config
|
978
|
-
end
|
979
|
-
# divider used to resize neighbouring components TOTEST XXX
|
980
|
-
def divider *args, &block
|
981
|
-
require 'rbcurse/extras/divider'
|
982
|
-
config = {}
|
983
|
-
events = [:PROPERTY_CHANGE, :LEAVE, :ENTER, :DRAG_EVENT ] # # none really at present
|
984
|
-
block_event = nil
|
985
|
-
_process_args args, config, block_event, events
|
986
|
-
useform = nil
|
987
|
-
useform = @form if @current_object.empty?
|
988
|
-
sb = Divider.new useform, config
|
989
|
-
end
|
990
|
-
# creates a simple readonly table, that allows users to click on rows
|
991
|
-
# and also on the header. Header clicking is for column-sorting.
|
992
|
-
def combo *args, &block
|
993
|
-
require 'rbcurse/rcombo'
|
994
|
-
config = {}
|
995
|
-
events = [:PROPERTY_CHANGE, :LEAVE, :ENTER, :CHANGE, :ENTER_ROW, :PRESS ] # XXX
|
996
|
-
block_event = nil
|
997
|
-
_process_args args, config, block_event, events
|
998
|
-
_position(config)
|
999
|
-
# if no width given, expand to flows width
|
1000
|
-
config[:width] ||= @stack.last.width if @stack.last
|
1001
|
-
#config.delete :title
|
1002
|
-
useform = nil
|
1003
|
-
useform = @form if @current_object.empty?
|
1004
|
-
|
1005
|
-
w = ComboBox.new useform, config # NO BLOCK GIVEN
|
1006
|
-
if block_given?
|
1007
|
-
@current_object << w
|
1008
|
-
yield_or_eval &block
|
1009
|
-
@current_object.pop
|
1010
|
-
end
|
1011
|
-
return w
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
# ADD new widget above this
|
1015
|
-
|
1016
|
-
# @endgroup
|
1017
|
-
|
1018
|
-
# @group positioning of components
|
1019
|
-
|
1020
|
-
# line up vertically whatever comes in, ignoring r and c
|
1021
|
-
# margin_top to add to margin of existing stack (if embedded) such as extra spacing
|
1022
|
-
# margin to add to margin of existing stack, or window (0)
|
1023
|
-
# NOTE: since these coordins are calculated at start
|
1024
|
-
# therefore if window resized i can't recalculate.
|
1025
|
-
Stack = Struct.new(:margin_top, :margin, :width)
|
1026
|
-
def stack config={}, &block
|
1027
|
-
@instack = true
|
1028
|
-
mt = config[:margin_top] || 1
|
1029
|
-
mr = config[:margin] || 0
|
1030
|
-
# must take into account margin
|
1031
|
-
defw = Ncurses.COLS - mr
|
1032
|
-
config[:width] = defw if config[:width] == :EXPAND
|
1033
|
-
w = config[:width] || [50, defw].min
|
1034
|
-
s = Stack.new(mt, mr, w)
|
1035
|
-
@app_row += mt
|
1036
|
-
mr += @stack.last.margin if @stack.last
|
1037
|
-
@stack << s
|
1038
|
-
yield_or_eval &block if block_given?
|
1039
|
-
@stack.pop
|
1040
|
-
@instack = false if @stack.empty?
|
1041
|
-
@app_row = 0 if @stack.empty?
|
1042
|
-
end
|
1043
|
-
# keep adding to right of previous and when no more space
|
1044
|
-
# move down and continue fitting in.
|
1045
|
-
# Useful for button positioning. Currently, we can use a second flow
|
1046
|
-
# to get another row.
|
1047
|
-
# TODO: move down when row filled
|
1048
|
-
# TODO: align right, center
|
1049
|
-
def flow config={}, &block
|
1050
|
-
@inflow = true
|
1051
|
-
mt = config[:margin_top] || 0
|
1052
|
-
@app_row += mt
|
1053
|
-
col = @flowstack.last || @stack.last.margin || @app_col
|
1054
|
-
col += config[:margin] || 0
|
1055
|
-
@flowstack << col
|
1056
|
-
@flowcol = col
|
1057
|
-
yield_or_eval &block if block_given?
|
1058
|
-
@flowstack.pop
|
1059
|
-
@inflow = false if @flowstack.empty?
|
1060
|
-
end
|
1061
|
-
|
1062
|
-
private
|
1063
|
-
def quit
|
1064
|
-
throw(:close)
|
1065
|
-
end
|
1066
|
-
# Initialize curses
|
1067
|
-
def init_ncurses
|
1068
|
-
VER::start_ncurses # this is initializing colors via ColorMap.setup
|
1069
|
-
#$ncurses_started = true
|
1070
|
-
@stop_ncurses_on_close = true
|
1071
|
-
end
|
1072
|
-
|
1073
|
-
# returns length of longest
|
1074
|
-
def longest_in_list list #:nodoc:
|
1075
|
-
longest = list.inject(0) do |memo,word|
|
1076
|
-
memo >= word.length ? memo : word.length
|
1077
|
-
end
|
1078
|
-
longest
|
1079
|
-
end
|
1080
|
-
# returns longest item
|
1081
|
-
# rows = list.max_by(&:length)
|
1082
|
-
#
|
1083
|
-
def longest_in_list2 list #:nodoc:
|
1084
|
-
longest = list.inject(list[0]) do |memo,word|
|
1085
|
-
memo.length >= word.length ? memo : word
|
1086
|
-
end
|
1087
|
-
longest
|
1088
|
-
end
|
1089
|
-
|
1090
|
-
# if partial command entered then returns matches
|
1091
|
-
def _resolve_command opts, cmd
|
1092
|
-
return cmd if opts.include? cmd
|
1093
|
-
matches = opts.grep Regexp.new("^#{cmd}")
|
1094
|
-
end
|
1095
|
-
# Now i am not creating this unless user wants it. Pls avoid it.
|
1096
|
-
# Use either say_with_pause, or put $status_message in command of statusline
|
1097
|
-
# @deprecated please use {#status_line} instead of a message label
|
1098
|
-
def create_message_label row=Ncurses.LINES-1
|
1099
|
-
@message_label = RubyCurses::Label.new @form, {:text_variable => @message, :name=>"message_label",:row => row, :col => 0, :display_length => Ncurses.COLS, :height => 1, :color => :white}
|
1100
|
-
end
|
1101
|
-
|
1102
|
-
def run &block
|
1103
|
-
begin
|
1104
|
-
|
1105
|
-
# check if user has passed window coord in config, else root window
|
1106
|
-
@window = VER::Window.root_window
|
1107
|
-
awin = @window
|
1108
|
-
catch(:close) do
|
1109
|
-
@form = Form.new @window
|
1110
|
-
@form.bind_key([?\C-x, ?c]) { suspend(false) do
|
1111
|
-
system("tput cup 26 0")
|
1112
|
-
system("tput ed")
|
1113
|
-
system("echo Enter C-d to return to application")
|
1114
|
-
system (ENV['PS1']='\s-\v\$ ')
|
1115
|
-
system(ENV['SHELL']);
|
1116
|
-
end
|
1117
|
-
}
|
1118
|
-
# this is a very rudimentary default command executer, it does not
|
1119
|
-
# allow tab completion. App should use M-x with names of commands
|
1120
|
-
# as in appgmail
|
1121
|
-
@form.bind_key(?:) {
|
1122
|
-
str = get_command_from_user
|
1123
|
-
}
|
1124
|
-
|
1125
|
-
@form.bind_key(?\M-x){
|
1126
|
-
# TODO previous command to be default
|
1127
|
-
opts = get_all_commands()
|
1128
|
-
@_command_history ||= Array.new
|
1129
|
-
# previous command should be in opts, otherwise it is not in this context
|
1130
|
-
cmd = ask("Command: ", opts){ |q| q.default = @_previous_command; q.history = @_command_history }
|
1131
|
-
if cmd.nil? || cmd == ""
|
1132
|
-
else
|
1133
|
-
@_command_history << cmd unless @_command_history.include? cmd
|
1134
|
-
cmdline = cmd.split
|
1135
|
-
cmd = cmdline.shift
|
1136
|
-
# check if command is a substring of a larger command
|
1137
|
-
if !opts.include?(cmd)
|
1138
|
-
rcmd = _resolve_command(opts, cmd) if !opts.include?(cmd)
|
1139
|
-
if rcmd.size == 1
|
1140
|
-
cmd = rcmd.first
|
1141
|
-
elsif !rcmd.empty?
|
1142
|
-
say_with_pause "Cannot resolve #{cmd}. Matches are: #{rcmd} "
|
1143
|
-
end
|
1144
|
-
end
|
1145
|
-
if respond_to?(cmd, true)
|
1146
|
-
@_previous_command = cmd
|
1147
|
-
#raw_message "calling #{cmd} "
|
1148
|
-
begin
|
1149
|
-
send cmd, *cmdline
|
1150
|
-
rescue => exc
|
1151
|
-
$log.error "ERR EXC: send throwing an exception now. Duh. IMAP keeps crashing haha !! #{exc} " if $log.debug?
|
1152
|
-
if exc
|
1153
|
-
$log.debug( exc)
|
1154
|
-
$log.debug(exc.backtrace.join("\n"))
|
1155
|
-
say_with_pause exc.to_s
|
1156
|
-
end
|
1157
|
-
end
|
1158
|
-
else
|
1159
|
-
say_with_pause("Command [#{cmd}] not supported by #{self.class} ", :color_pair => $promptcolor)
|
1160
|
-
end
|
1161
|
-
end
|
1162
|
-
}
|
1163
|
-
@form.bind_key(KEY_F1){ display_app_help }
|
1164
|
-
@form.bind_key([?q,?q]){ throw :close } if $log.debug?
|
1165
|
-
|
1166
|
-
#@message = Variable.new
|
1167
|
-
#@message.value = ""
|
1168
|
-
$status_message ||= Variable.new # remember there are multiple levels of apps
|
1169
|
-
$status_message.value = ""
|
1170
|
-
#$error_message.update_command { @message.set_value($error_message.value) }
|
1171
|
-
if block
|
1172
|
-
begin
|
1173
|
-
#yield(self, @window, @form)
|
1174
|
-
#instance_eval &block if block_given?
|
1175
|
-
yield_or_eval &block if block_given? # modified 2010-11-17 20:36
|
1176
|
-
loop
|
1177
|
-
rescue => ex
|
1178
|
-
$log.debug( "APP.rb rescue reached ")
|
1179
|
-
$log.debug( ex) if ex
|
1180
|
-
$log.debug(ex.backtrace.join("\n")) if ex
|
1181
|
-
ensure
|
1182
|
-
close
|
1183
|
-
# putting it here allows it to be printed on screen, otherwise it was not showing at all.
|
1184
|
-
if ex
|
1185
|
-
puts "========== EXCEPTION =========="
|
1186
|
-
p ex
|
1187
|
-
puts "==============================="
|
1188
|
-
puts(ex.backtrace.join("\n"))
|
1189
|
-
end
|
1190
|
-
end
|
1191
|
-
nil
|
1192
|
-
else
|
1193
|
-
#@close_on_terminate = true
|
1194
|
-
self
|
1195
|
-
end #if block
|
1196
|
-
end
|
1197
|
-
end
|
1198
|
-
end
|
1199
|
-
# TODO
|
1200
|
-
# process args, all widgets should call this
|
1201
|
-
def _process_args args, config, block_event, events #:nodoc:
|
1202
|
-
args.each do |arg|
|
1203
|
-
case arg
|
1204
|
-
when Array
|
1205
|
-
# we can use r,c, w, h
|
1206
|
-
row, col, display_length, height = arg
|
1207
|
-
config[:row] = row
|
1208
|
-
config[:col] = col
|
1209
|
-
config[:display_length] = display_length if display_length
|
1210
|
-
config[:width] = display_length if display_length
|
1211
|
-
# width for most XXX ?
|
1212
|
-
config[:height] = height if height
|
1213
|
-
when Hash
|
1214
|
-
config.merge!(arg)
|
1215
|
-
if block_event
|
1216
|
-
block_event = config.delete(:block_event){ block_event }
|
1217
|
-
raise "Invalid event. Use #{events}" unless events.include? block_event
|
1218
|
-
end
|
1219
|
-
when String
|
1220
|
-
config[:name] = arg
|
1221
|
-
config[:title] = arg # some may not have title
|
1222
|
-
#config[:text] = arg # some may not have title
|
1223
|
-
end
|
1224
|
-
end
|
1225
|
-
end # _process
|
1226
|
-
# position object based on whether in a flow or stack.
|
1227
|
-
# @app_row is prepared for next object based on this objects ht
|
1228
|
-
def _position config #:nodoc:
|
1229
|
-
unless @current_object.empty?
|
1230
|
-
$log.debug " WWWW returning from position #{@current_object.last} "
|
1231
|
-
return
|
1232
|
-
end
|
1233
|
-
if @inflow
|
1234
|
-
#col = @flowstack.last
|
1235
|
-
config[:row] = @app_row
|
1236
|
-
config[:col] = @flowcol
|
1237
|
-
$log.debug " YYYY config #{config} "
|
1238
|
-
if config[:text]
|
1239
|
-
@flowcol += config[:text].length + 5 # 5 came from buttons
|
1240
|
-
else
|
1241
|
-
@flowcol += (config[:length] || 10) + 5 # trying out for combo
|
1242
|
-
end
|
1243
|
-
elsif @instack
|
1244
|
-
# most likely you won't have row and col. should we check or just go ahead
|
1245
|
-
# what if he has put it 2011-10-19 as in a container
|
1246
|
-
col = @stack.last.margin
|
1247
|
-
config[:row] ||= @app_row
|
1248
|
-
config[:col] ||= col
|
1249
|
-
@app_row += config[:height] || 1 #unless config[:no_advance]
|
1250
|
-
# TODO need to allow stack to have its spacing, but we don't have an object as yet.
|
1251
|
-
end
|
1252
|
-
end
|
1253
|
-
end # class
|
1254
|
-
end # module
|
1255
|
-
if $0 == __FILE__
|
1256
|
-
include RubyCurses
|
1257
|
-
#app = App.new
|
1258
|
-
#window = app.window
|
1259
|
-
#window.printstring 2, 30, "Demo of Listbox - rbcurse", $normalcolor, 'reverse'
|
1260
|
-
#app.logger.info "beforegetch"
|
1261
|
-
#window.getch
|
1262
|
-
#app.close
|
1263
|
-
# this was the yield example, but now we've moved to instance eval
|
1264
|
-
App.new do
|
1265
|
-
@window.printstring 0, 30, "Demo of Listbox - rbcurse", $normalcolor, 'reverse'
|
1266
|
-
@window.printstring 1, 30, "Hit F1 to quit", $datacolor, 'normal'
|
1267
|
-
form = @form
|
1268
|
-
fname = "Search"
|
1269
|
-
r, c = 7, 30
|
1270
|
-
c += fname.length + 1
|
1271
|
-
#field1 = field( [r,c, 30], fname, :bgcolor => "cyan", :block_event => :CHANGE) do |fld|
|
1272
|
-
stack :margin_top => 2, :margin => 10 do
|
1273
|
-
lbl = label({:text => fname, :color=>'white',:bgcolor=>'red', :mnemonic=> 's'})
|
1274
|
-
field1 = field( [r,c, 30], fname, :bgcolor => "cyan",:block_event => :CHANGE) do |fld|
|
1275
|
-
message("You entered #{fld.getvalue}. To quit enter quit and tab out")
|
1276
|
-
if fld.getvalue == "quit"
|
1277
|
-
logger.info "you typed quit!"
|
1278
|
-
throw :close
|
1279
|
-
end
|
1280
|
-
end
|
1281
|
-
#field1.set_label Label.new @form, {:text => fname, :color=>'white',:bgcolor=>'red', :mnemonic=> 's'}
|
1282
|
-
field1.set_label( lbl )
|
1283
|
-
field1.enter do
|
1284
|
-
message "you entered this field"
|
1285
|
-
end
|
1286
|
-
|
1287
|
-
stack :margin_top => 2, :margin => 0 do
|
1288
|
-
#label( [8, 30, 60],{:text => "A label", :color=>'white',:bgcolor=>'blue'} )
|
1289
|
-
end
|
1290
|
-
|
1291
|
-
@bluelabel = label( [8, 30, 60],{:text => "B label", :color=>'white',:bgcolor=>'blue'} )
|
1292
|
-
|
1293
|
-
stack :margin_top => 2, :margin => 0 do
|
1294
|
-
toggle :onvalue => " Toggle Down ", :offvalue => " Untoggle ", :mnemonic => 'T', :value => true
|
1295
|
-
|
1296
|
-
toggle :onvalue => " On ", :offvalue => " Off ", :value => true do |e|
|
1297
|
-
alert "You pressed me #{e.state}"
|
1298
|
-
end
|
1299
|
-
check :text => "Check me!", :onvalue => "Checked", :offvalue => "Unchecked", :value => true do |e|
|
1300
|
-
# this works but long and complicated
|
1301
|
-
#@bluelabel.text = e.item.getvalue ? e.item.onvalue : e.item.offvalue
|
1302
|
-
@bluelabel.text = e.item.text
|
1303
|
-
end
|
1304
|
-
radio :text => "red", :value => "RED", :color => "red", :group => :colors
|
1305
|
-
radio :text => "green", :value => "GREEN", :color => "green", :group => :colors
|
1306
|
-
flow do
|
1307
|
-
button_row = 17
|
1308
|
-
ok_button = button( [button_row,30], "OK", {:mnemonic => 'O'}) do
|
1309
|
-
alert("About to dump data into log file!")
|
1310
|
-
message "Dumped data to log file"
|
1311
|
-
end
|
1312
|
-
|
1313
|
-
# using ampersand to set mnemonic
|
1314
|
-
cancel_button = button( [button_row, 40], "&Cancel" ) do
|
1315
|
-
if confirm("Do your really want to quit?")== :YES
|
1316
|
-
#throw(:close);
|
1317
|
-
quit
|
1318
|
-
else
|
1319
|
-
message "Quit aborted"
|
1320
|
-
end
|
1321
|
-
end # cancel
|
1322
|
-
button "Don't know"
|
1323
|
-
end
|
1324
|
-
flow :margin_top => 2 do
|
1325
|
-
button "Another"
|
1326
|
-
button "Line"
|
1327
|
-
end
|
1328
|
-
stack :margin_top => 2, :margin => 0 do
|
1329
|
-
@pbar = progress :width => 20, :bgcolor => 'white', :color => 'red'
|
1330
|
-
@pbar1 = progress :width => 20, :style => :old
|
1331
|
-
end
|
1332
|
-
end
|
1333
|
-
end # stack
|
1334
|
-
# lets make another column
|
1335
|
-
stack :margin_top => 2, :margin => 70 do
|
1336
|
-
l = label "Column 2"
|
1337
|
-
f1 = field "afield", :bgcolor => 'white', :color => 'black'
|
1338
|
-
list_box "A list", :list => ["Square", "Oval", "Rectangle", "Somethinglarge"], :choose => ["Square"]
|
1339
|
-
lb = list_box "Another", :list => ["Square", "Oval", "Rectangle", "Somethinglarge"] do |list|
|
1340
|
-
#f1.set_buffer list.text
|
1341
|
-
#f1.text list.text
|
1342
|
-
f1.text = list.text
|
1343
|
-
l.text = list.text.upcase
|
1344
|
-
end
|
1345
|
-
t = textarea :height => 10 do |e|
|
1346
|
-
#@bluelabel.text = e.to_s.tr("\n",' ')
|
1347
|
-
@bluelabel.text = e.text.gsub("\n"," ")
|
1348
|
-
len = e.source.get_text.length
|
1349
|
-
len = len % 20 if len > 20
|
1350
|
-
$log.debug " PBAR len of text is #{len}: #{len/20.0} "
|
1351
|
-
@pbar.fraction(len/20.0)
|
1352
|
-
@pbar1.fraction(len/20.0)
|
1353
|
-
i = ((len/20.0)*100).to_i
|
1354
|
-
@pbar.text = "completed:#{i}"
|
1355
|
-
end
|
1356
|
-
t.leave do |c|
|
1357
|
-
@bluelabel.text = c.get_text.gsub("\n"," ")
|
1358
|
-
end
|
1359
|
-
|
1360
|
-
end
|
1361
|
-
|
1362
|
-
# Allow user to get the keys
|
1363
|
-
keypress do |key|
|
1364
|
-
if key == :C_c
|
1365
|
-
message "You tried to cancel"
|
1366
|
-
#throw :close
|
1367
|
-
quit
|
1368
|
-
else
|
1369
|
-
#app.message "You pressed #{key}, #{char} "
|
1370
|
-
message "You pressed #{key}"
|
1371
|
-
end
|
1372
|
-
end
|
1373
|
-
end
|
1374
|
-
end
|