rbcurse 1.5.0 → 1.5.2
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/Makefile +21 -0
- data/Manifest.txt +6 -0
- data/README.markdown +6 -4
- data/TODO +372 -0
- data/TODO2.txt +121 -0
- data/VERSION +1 -1
- data/examples/README.txt +67 -0
- data/examples/abasiclist.rb +33 -0
- data/examples/alpmenu.rb +42 -0
- data/examples/app.rb +859 -0
- data/examples/app.sample +17 -0
- data/examples/appdirtree.rb +74 -0
- data/examples/appemail.rb +191 -0
- data/examples/appemaillb.rb +308 -0
- data/examples/appgcompose.rb +315 -0
- data/examples/atree.rb +64 -0
- data/examples/common/file.rb +40 -0
- data/examples/common/rmail.rb +257 -0
- data/examples/data.txt +683 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +60 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +495 -0
- data/examples/deprecated/appgmail.rb +952 -0
- data/examples/deprecated/splitp.rb +56 -0
- data/examples/deprecated/testscrolllb.rb +86 -0
- data/examples/deprecated/testscrollp.rb +88 -0
- data/examples/deprecated/testscrollta.rb +80 -0
- data/examples/deprecated/testscrolltable.rb +165 -0
- data/examples/deprecated/testsplit.rb +87 -0
- data/examples/deprecated/testsplit2.rb +123 -0
- data/examples/deprecated/testsplit3.rb +215 -0
- data/examples/deprecated/testsplit3_1.rb +244 -0
- data/examples/deprecated/testsplit3a.rb +215 -0
- data/examples/deprecated/testsplit3b.rb +237 -0
- data/examples/deprecated/testsplitta.rb +148 -0
- data/examples/deprecated/testsplittv.rb +142 -0
- data/examples/deprecated/testsplittvv.rb +144 -0
- data/examples/deprecated/testtpane.rb +215 -0
- data/examples/deprecated/testtpane2.rb +145 -0
- data/examples/deprecated/testtpanetable.rb +203 -0
- data/examples/dirtree.rb +88 -0
- data/examples/experimental/resultsetdemo.rb +280 -0
- data/examples/experimental/testmform.rb +35 -0
- data/examples/experimental/testscroller.rb +117 -0
- data/examples/experimental/teststackflow.rb +111 -0
- data/examples/menu1.rb +112 -0
- data/examples/multispl.rb +86 -0
- data/examples/newmessagebox.rb +131 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +121 -0
- data/examples/qdfilechooser.rb +68 -0
- data/examples/rfe.rb +1239 -0
- data/examples/rfe_renderer.rb +121 -0
- data/examples/sqlc.rb +454 -0
- data/examples/sqlm.rb +437 -0
- data/examples/sqlt.rb +408 -0
- data/examples/status.txt +68 -0
- data/examples/table1.rb +24 -0
- data/examples/term2.rb +84 -0
- data/examples/test1.rb +239 -0
- data/examples/test2.rb +674 -0
- data/examples/testapp.rb +44 -0
- data/examples/testapp2.rb +58 -0
- data/examples/testchars.rb +137 -0
- data/examples/testcombo.rb +91 -0
- data/examples/testkeypress.rb +66 -0
- data/examples/testlistbox.rb +113 -0
- data/examples/testmenu.rb +101 -0
- data/examples/testmulticomp.rb +70 -0
- data/examples/testmulticontainer.rb +94 -0
- data/examples/testmultispl.rb +199 -0
- data/examples/testree.rb +106 -0
- data/examples/testtable.rb +264 -0
- data/examples/testtabp.rb +107 -0
- data/examples/testtodo.rb +584 -0
- data/examples/testvimsplit.rb +112 -0
- data/examples/testwsshortcuts.rb +64 -0
- data/examples/testwsshortcuts2.rb +126 -0
- data/examples/todo.db +0 -0
- data/examples/todo.yml +191 -0
- data/examples/viewtodo.rb +574 -0
- data/lib/rbcurse/deprecated/README.markdown +12 -0
- data/lib/rbcurse/deprecated/rpad.rb +375 -0
- data/lib/rbcurse/deprecated/rscrollpane.rb +512 -0
- data/lib/rbcurse/deprecated/rsplitpane.rb +894 -0
- data/lib/rbcurse/deprecated/rsplitpane2.rb +1009 -0
- data/lib/rbcurse/deprecated/rviewport.rb +204 -0
- data/lib/rbcurse/deprecated/widgets/mapper.rb +130 -0
- data/lib/rbcurse/deprecated/widgets/rmessagebox.rb +348 -0
- data/lib/rbcurse/deprecated/widgets/rtabbedpane.rb +1158 -0
- data/lib/rbcurse/deprecated/widgets/rtabbedwindow.rb +167 -0
- data/lib/rbcurse/deprecated/widgets/scrollable.rb +301 -0
- data/lib/rbcurse/deprecated/widgets/stdscrwindow.rb +309 -0
- data/lib/ver/keyboard2.rb +170 -0
- data/test/test_rbcurse.rb +0 -0
- metadata +131 -9
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.5.
|
1
|
+
1.5.2
|
data/examples/README.txt
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
README
|
3
|
+
------
|
4
|
+
|
5
|
+
### For ruby 1.9.2, 2010-08-23 11:48
|
6
|
+
|
7
|
+
Changes in 1.9.2 require the following changes:
|
8
|
+
- $: no longer includes ".".
|
9
|
+
Fixed 2 examples.
|
10
|
+
- hash_update: cannot update hash during iteration
|
11
|
+
Modified rwidget.rb and rtable.rb
|
12
|
+
|
13
|
+
### IMPORTANT
|
14
|
+
|
15
|
+
1. If you are trying out the examples from a folder that does not have
|
16
|
+
write access (e.g. /opt/local/lib...), then you may have to run the
|
17
|
+
examples, with "sudo", since a log file is created. Or else, you could
|
18
|
+
copy the examples elsewhere, or change to location of the log file
|
19
|
+
(view.log) before running.
|
20
|
+
|
21
|
+
sudo ruby test2.rb
|
22
|
+
|
23
|
+
Update: Added an environment variable named LOGDIR. So you may do:
|
24
|
+
|
25
|
+
LOGDIR=~/ ruby test2.rb
|
26
|
+
|
27
|
+
or just set LOGDIR
|
28
|
+
|
29
|
+
export LOGDIR=~/tmp
|
30
|
+
|
31
|
+
2. Please change directory to the examples folder before executing, since
|
32
|
+
some data files, or local programs may be loaded.
|
33
|
+
|
34
|
+
## sqlc.rb
|
35
|
+
|
36
|
+
A sql client using tabbedpanes.
|
37
|
+
|
38
|
+
This uses a file testd.db that can be downloaded (check file for
|
39
|
+
location) or created using:
|
40
|
+
|
41
|
+
sqlite3 testd.db < data.txt
|
42
|
+
|
43
|
+
Enter an sql query in the textbox. Click Run.
|
44
|
+
|
45
|
+
Or Press Enter on the name of a table in the tables listing. Its
|
46
|
+
contents will be shown in a new tab in the tabbedpane.
|
47
|
+
|
48
|
+
Or Press Space on a table. Its columns are shown below. Now select
|
49
|
+
columns and then click Construct. Selected columns will be used to
|
50
|
+
construct a query. Press Run to execute it.
|
51
|
+
|
52
|
+
If you are inside a table, use Alt-TAb to exit.
|
53
|
+
|
54
|
+
## sqlm.rb
|
55
|
+
|
56
|
+
Identical to sqlc.rb. This demo uses a multi-container for multiple
|
57
|
+
resultsets instead of a tabbedpane.
|
58
|
+
|
59
|
+
* * * * *
|
60
|
+
|
61
|
+
Please check the examples with test*.rb - since they are updated.
|
62
|
+
At the time of writing, viewtodo.rb may not be functional since I
|
63
|
+
changed to structure of the yaml file.
|
64
|
+
|
65
|
+
## vim:tw=72:ai:formatoptions=tcqln:nocindent:
|
66
|
+
|
67
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rbcurse/core/util/app'
|
2
|
+
require 'rbcurse/core/widgets/rlist'
|
3
|
+
|
4
|
+
# just a simple test to ensure that rbasiclistbox is running inside a container.
|
5
|
+
App.new do
|
6
|
+
header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Basic List Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
|
7
|
+
message "Press F10 to escape from here"
|
8
|
+
|
9
|
+
#list = %W{ bhikshu boddisattva avalokiteswara mu mun kwan paramita prajna samadhi sutra shakyamuni }
|
10
|
+
list = File.open("data/brew.txt",'r').readlines
|
11
|
+
list2 = File.open("data/gemlist.txt",'r').readlines
|
12
|
+
lb = nil
|
13
|
+
vimsplit :row => 1, :col => 0, :suppress_borders => false, :width => 60, :height => Ncurses.LINES-2, :weight => 0.4, :orientation => :VERTICAL do |s|
|
14
|
+
lb = RubyCurses::List.new nil, :list => list, :suppress_borders => false
|
15
|
+
#lb = RubyCurses::List.new nil, :list => list, :show_selector => true, :row_selected_symbol => "*", :suppress_borders => false
|
16
|
+
#lb = RubyCurses::List.new nil, :list => list
|
17
|
+
#lb = list_box "A list", :list => list
|
18
|
+
lb.show_selector = false
|
19
|
+
#lb.row_selected_symbol = "*"
|
20
|
+
#lb = list_box "A list", :list => list
|
21
|
+
|
22
|
+
s.add lb, :FIRST
|
23
|
+
#lb2= RubyCurses::List.new nil, :list => list.shuffle, :justify => :center
|
24
|
+
lb2 = listbox :list => list2, :justify => :left, :suppress_borders => false
|
25
|
+
s.add lb2, :SECOND
|
26
|
+
label({:text => "checking overwrite from list", :row => 10, :col => 60})
|
27
|
+
label({:text => "checking overwrite from list 1", :row => 11, :col => 60})
|
28
|
+
end
|
29
|
+
label({:text => "Press F4 and F5 to test popup, space or enter to select", :row => Ncurses.LINES-1, :col => 0})
|
30
|
+
|
31
|
+
@form.bind_key(FFI::NCurses::KEY_F4) { row = lb.current_index+lb.row; col=lb.col+lb.current_value.length+1; ret = popuplist(%w[ andy berlioz strauss tchaiko matz beethoven], :row => row, :col => col, :title => "Names", :bgcolor => :blue, :color => :white) ; alert "got #{ret} "}
|
32
|
+
@form.bind_key(FFI::NCurses::KEY_F5) { list = %x[ls].split("\n");ret = popuplist(list, :title => "Files"); alert "Got #{ret} #{list[ret]} " }
|
33
|
+
end # app
|
data/examples/alpmenu.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rbcurse/core/util/app'
|
2
|
+
|
3
|
+
App.new do
|
4
|
+
#title "Demo of Menu - rbcurse"
|
5
|
+
#subtitle "Hit F1 to quit, F2 for menubar toggle"
|
6
|
+
header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Alpine Menu Demo", :text_right =>""
|
7
|
+
#message_row(27)
|
8
|
+
|
9
|
+
stack :margin_top => 10, :margin => 15 do
|
10
|
+
#w = "Messages".length + 1
|
11
|
+
w = 60
|
12
|
+
menulink "&View Todo", :width => w, :description => "View TODO in sqlite" do |s|
|
13
|
+
message "Pressed #{s.text} "
|
14
|
+
#require './viewtodo'; todo = ViewTodo::TodoApp.new; todo.run
|
15
|
+
end
|
16
|
+
blank
|
17
|
+
menulink "&Edit Todo", :width => w, :description => "Edit TODO in CSV" do |s|
|
18
|
+
message "Pressed #{s.text} "
|
19
|
+
#require './testtodo'; todo = TestTodo::TodoApp.new; todo.run
|
20
|
+
end
|
21
|
+
blank
|
22
|
+
menulink "&Messages", :width => w, :description => "View messages in current folder" do |s|
|
23
|
+
message "Pressed #{s.text} "
|
24
|
+
#load './menu1.rb'
|
25
|
+
end
|
26
|
+
blank
|
27
|
+
menulink "&Compose", :width => w, :description => "Compose a mail" do |s|
|
28
|
+
message "Pressed #{s.getvalue} "
|
29
|
+
end
|
30
|
+
blank
|
31
|
+
menulink "Setup", :mnemonic => "?", :width => w, :description => "Configure Alpine options" do |s|
|
32
|
+
message "Pressed #{s.text} "
|
33
|
+
end
|
34
|
+
blank
|
35
|
+
menulink "&Quit", :width => w, :description => "Quit this application" do |s|
|
36
|
+
quit
|
37
|
+
end
|
38
|
+
@form.bind(:ENTER) do |w|
|
39
|
+
header.text_right = w.text
|
40
|
+
end
|
41
|
+
end # stack
|
42
|
+
end # app
|
data/examples/app.rb
ADDED
@@ -0,0 +1,859 @@
|
|
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 'rubygems'
|
13
|
+
#require 'ncurses' # FFI
|
14
|
+
require 'logger'
|
15
|
+
require 'rbcurse'
|
16
|
+
|
17
|
+
#include Ncurses
|
18
|
+
include RubyCurses
|
19
|
+
include RubyCurses::Utils
|
20
|
+
module RubyCurses
|
21
|
+
extend self
|
22
|
+
|
23
|
+
# NOTE most of this has move to lib/rbcurse/core/util/app.rb
|
24
|
+
#
|
25
|
+
class Widget
|
26
|
+
def changed *args, &block
|
27
|
+
bind :CHANGED, *args, &block
|
28
|
+
end
|
29
|
+
def leave *args, &block
|
30
|
+
bind :LEAVE, *args, &block
|
31
|
+
end
|
32
|
+
def enter *args, &block
|
33
|
+
bind :ENTER, *args, &block
|
34
|
+
end
|
35
|
+
# actually we already have command() for buttons
|
36
|
+
def click *args, &block
|
37
|
+
bind :PRESS, *args, &block
|
38
|
+
end
|
39
|
+
end
|
40
|
+
#class Listbox
|
41
|
+
#def text
|
42
|
+
#return get_content()[@current_index]
|
43
|
+
#end
|
44
|
+
#end
|
45
|
+
class CheckBox
|
46
|
+
# a little dicey XXX
|
47
|
+
def text(*val)
|
48
|
+
if val.empty?
|
49
|
+
@value ? @onvalue : @offvalue
|
50
|
+
else
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
class App
|
56
|
+
attr_reader :config
|
57
|
+
attr_reader :form
|
58
|
+
attr_reader :window
|
59
|
+
attr_writer :quit_key
|
60
|
+
|
61
|
+
|
62
|
+
# i should be able to pass window coords here in config
|
63
|
+
# :title
|
64
|
+
def initialize config={}, &block
|
65
|
+
#$log.debug " inside constructor of APP #{config} "
|
66
|
+
@config = config
|
67
|
+
@app_row = @app_col = 0
|
68
|
+
@stack = [] # stack's coordinates
|
69
|
+
@flowstack = []
|
70
|
+
@variables = {}
|
71
|
+
# if we are creating child objects then we will not use outer form. this object will manage
|
72
|
+
@current_object = []
|
73
|
+
init_vars
|
74
|
+
run &block
|
75
|
+
end
|
76
|
+
def init_vars
|
77
|
+
@quit_key ||= KEY_F1
|
78
|
+
# actually this should be maintained inside ncurses pack, so not loaded 2 times.
|
79
|
+
# this way if we call an app from existing program, App won't start ncurses.
|
80
|
+
unless $ncurses_started
|
81
|
+
init_ncurses
|
82
|
+
end
|
83
|
+
unless $log
|
84
|
+
$log = Logger.new((File.join(ENV["LOGDIR"] || "./" ,"rbc13.log")))
|
85
|
+
$log.level = Logger::DEBUG
|
86
|
+
colors = Ncurses.COLORS
|
87
|
+
$log.debug "START #{colors} colors --------- #{$0}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
def logger; return $log; end
|
91
|
+
def close
|
92
|
+
$log.debug " INSIDE CLOSE, #{@stop_ncurses_on_close} "
|
93
|
+
@window.destroy if !@window.nil?
|
94
|
+
$log.debug " INSIDE CLOSE, #{@stop_ncurses_on_close} "
|
95
|
+
if @stop_ncurses_on_close
|
96
|
+
VER::stop_ncurses
|
97
|
+
$log.debug " CLOSING NCURSES"
|
98
|
+
end
|
99
|
+
#p $error_message.value unless $error_message.value.nil?
|
100
|
+
$log.debug " CLOSING APP"
|
101
|
+
#end
|
102
|
+
end
|
103
|
+
# not sure, but user shuld be able to trap keystrokes if he wants
|
104
|
+
# but do i still call handle_key if he does, or give him total control.
|
105
|
+
# But loop is already called by framework
|
106
|
+
def loop &block
|
107
|
+
@form.repaint
|
108
|
+
@window.wrefresh
|
109
|
+
Ncurses::Panel.update_panels
|
110
|
+
while((ch = @window.getchar()) != @quit_key )
|
111
|
+
str = keycode_tos ch
|
112
|
+
@keyblock.call(str.gsub(/-/, "_").to_sym) if @keyblock
|
113
|
+
$log.debug "#{ch} got (#{str})"
|
114
|
+
yield ch if block # <<<----
|
115
|
+
@form.handle_key ch
|
116
|
+
@form.repaint
|
117
|
+
@window.wrefresh
|
118
|
+
end
|
119
|
+
end
|
120
|
+
# returns a symbol of the key pressed
|
121
|
+
# e.g. :C_c for Ctrl-C
|
122
|
+
# :Space, :bs, :M_d etc
|
123
|
+
def keypress &block
|
124
|
+
@keyblock = block
|
125
|
+
end
|
126
|
+
# updates a global var with text. Calling app has to set up a Variable with that name and attach to
|
127
|
+
# a label so it can be printed.
|
128
|
+
def message text
|
129
|
+
@message.value = text
|
130
|
+
end
|
131
|
+
def message_row row
|
132
|
+
@message_label.row = row
|
133
|
+
end
|
134
|
+
#
|
135
|
+
# @group methods to create widgets easily
|
136
|
+
#
|
137
|
+
# process arguments based on datatype, perhaps making configuration
|
138
|
+
# of some components easier for caller avoiding too much boiler plate code
|
139
|
+
#
|
140
|
+
# create a field
|
141
|
+
def field *args, &block
|
142
|
+
config = {}
|
143
|
+
events = [ :CHANGED, :LEAVE, :ENTER, :CHANGE ]
|
144
|
+
block_event = :CHANGED # LEAVE, ENTER, CHANGE
|
145
|
+
|
146
|
+
args.each do |arg|
|
147
|
+
case arg
|
148
|
+
when Array
|
149
|
+
#puts "row, col #{arg[0]} #{arg[1]} "
|
150
|
+
# we can use r,c, w, h
|
151
|
+
row, col, display_length = arg
|
152
|
+
config[:row] = row
|
153
|
+
config[:col] = col
|
154
|
+
config[:display_length] = display_length if display_length
|
155
|
+
when Hash
|
156
|
+
config.merge!(arg)
|
157
|
+
block_event = config.delete(:block_event){ block_event }
|
158
|
+
raise "Invalid event. Use #{events}" unless events.include? block_event
|
159
|
+
#puts "hash #{config}"
|
160
|
+
when String
|
161
|
+
title = arg
|
162
|
+
config[:name] = title
|
163
|
+
end
|
164
|
+
end
|
165
|
+
if @instack
|
166
|
+
# most likely you won't have row and col. should we check or just go ahead
|
167
|
+
col = @stack.last.margin
|
168
|
+
config[:row] = @app_row
|
169
|
+
config[:col] = col
|
170
|
+
@app_row += 1
|
171
|
+
end
|
172
|
+
field = Field.new @form, config
|
173
|
+
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
174
|
+
if block
|
175
|
+
field.bind(block_event, &block)
|
176
|
+
end
|
177
|
+
return field
|
178
|
+
end
|
179
|
+
#instance_eval &block if block_given?
|
180
|
+
# or
|
181
|
+
#@blk = block # for later execution using @blk.call()
|
182
|
+
#colorlabel = Label.new @form, {'text' => "Select a color:", "row" => row, "col" => col, "color"=>"cyan", "mnemonic" => 'S'}
|
183
|
+
#var = RubyCurses::Label.new @form, {'text_variable' => $results, "row" => r, "col" => fc}
|
184
|
+
|
185
|
+
def label *args
|
186
|
+
block_event = nil
|
187
|
+
config = {}
|
188
|
+
|
189
|
+
args.each do |arg|
|
190
|
+
case arg
|
191
|
+
when Array
|
192
|
+
row, col, display_length, height = arg
|
193
|
+
config[:row] = row
|
194
|
+
config[:col] = col
|
195
|
+
config[:display_length] = display_length if display_length
|
196
|
+
config[:height] = height || 1
|
197
|
+
when Hash
|
198
|
+
config.merge!(arg)
|
199
|
+
when String
|
200
|
+
config[:text] = arg
|
201
|
+
end
|
202
|
+
end
|
203
|
+
config[:height] ||= 1
|
204
|
+
if @instack
|
205
|
+
# most likely you won't have row and col. should we check or just go ahead
|
206
|
+
col = @stack.last.margin
|
207
|
+
config[:row] = @app_row
|
208
|
+
config[:col] = col
|
209
|
+
@app_row += config[:height]
|
210
|
+
end
|
211
|
+
label = Label.new @form, config
|
212
|
+
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
213
|
+
return label
|
214
|
+
end
|
215
|
+
alias :text :label
|
216
|
+
def button *args, &block
|
217
|
+
config = {}
|
218
|
+
events = [ :PRESS, :LEAVE, :ENTER ]
|
219
|
+
block_event = :PRESS
|
220
|
+
|
221
|
+
#process_args args, config, block_event, events
|
222
|
+
args.each do |arg|
|
223
|
+
case arg
|
224
|
+
when Array
|
225
|
+
#puts "row, col #{arg[0]} #{arg[1]} "
|
226
|
+
# we can use r,c, w, h
|
227
|
+
row, col, display_length, height = arg
|
228
|
+
config[:row] = row
|
229
|
+
config[:col] = col
|
230
|
+
config[:display_length] = display_length if display_length
|
231
|
+
config[:height] = height if height
|
232
|
+
when Hash
|
233
|
+
config.merge!(arg)
|
234
|
+
block_event = config.delete(:block_event){ block_event }
|
235
|
+
raise "Invalid event. Use #{events}" unless events.include? block_event
|
236
|
+
#puts "hash #{config}"
|
237
|
+
when String
|
238
|
+
config[:text] = arg
|
239
|
+
config[:name] = arg
|
240
|
+
end
|
241
|
+
end
|
242
|
+
# flow gets precedence over stack
|
243
|
+
_position(config)
|
244
|
+
button = Button.new @form, config
|
245
|
+
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
246
|
+
if block
|
247
|
+
button.bind(block_event, &block)
|
248
|
+
end
|
249
|
+
return button
|
250
|
+
end
|
251
|
+
#
|
252
|
+
# create a list
|
253
|
+
# Since we are mouseless, one can traverse without selection. So we have a different
|
254
|
+
# way of selecting row/s and traversal. XXX this aspect of LB's has always troubled me hugely.
|
255
|
+
def list_box *args, &block
|
256
|
+
config = {}
|
257
|
+
# TODO confirm events
|
258
|
+
# listdataevent has interval added and interval removed, due to multiple
|
259
|
+
# selection, we have to make that simple for user here.
|
260
|
+
events = [ :LEAVE, :ENTER, :ENTER_ROW, :LEAVE_ROW, :LIST_DATA_EVENT ]
|
261
|
+
# TODO how to do this so he gets selected row easily
|
262
|
+
block_event = :ENTER_ROW
|
263
|
+
|
264
|
+
# TODO abstract this into a new method so no copying
|
265
|
+
args.each do |arg|
|
266
|
+
case arg
|
267
|
+
when Array
|
268
|
+
#puts "row, col #{arg[0]} #{arg[1]} "
|
269
|
+
# we can use r,c, w, h
|
270
|
+
row, col, display_length, height = arg
|
271
|
+
config[:row] = row
|
272
|
+
config[:col] = col
|
273
|
+
config[:display_length] = display_length if display_length
|
274
|
+
config[:height] = height if height
|
275
|
+
when Hash
|
276
|
+
config.merge!(arg)
|
277
|
+
block_event = config.delete(:block_event){ block_event }
|
278
|
+
raise "Invalid event. Use #{events}" unless events.include? block_event
|
279
|
+
#puts "hash #{config}"
|
280
|
+
when String
|
281
|
+
config[:name] = arg
|
282
|
+
config[:title] = arg
|
283
|
+
end
|
284
|
+
end
|
285
|
+
# naive defaults, since list could be large or have very long items
|
286
|
+
# usually user will provide
|
287
|
+
config[:height] ||= config[:list].length + 2
|
288
|
+
if @current_object.empty?
|
289
|
+
$log.debug "1 APP LB w: #{config[:width]} ,#{config[:name]} "
|
290
|
+
config[:width] ||= @stack.last.width if @stack.last
|
291
|
+
$log.debug "2 APP LB w: #{config[:width]} "
|
292
|
+
config[:width] ||= longest_in_list(config[:list])+2
|
293
|
+
$log.debug "3 APP LB w: #{config[:width]} "
|
294
|
+
end
|
295
|
+
# if no width given, expand to flows width XXX SHOULD BE NOT EXPAND ?
|
296
|
+
#config[:width] ||= @stack.last.width if @stack.last
|
297
|
+
#if config.has_key? :choose
|
298
|
+
config[:default_values] = config.delete :choose
|
299
|
+
# we make the default single unless specified
|
300
|
+
config[:selection_mode] = :single unless config.has_key? :selection_mode
|
301
|
+
if @current_object.empty?
|
302
|
+
if @instack
|
303
|
+
# most likely you won't have row and col. should we check or just go ahead
|
304
|
+
col = @stack.last.margin
|
305
|
+
config[:row] = @app_row
|
306
|
+
config[:col] = col
|
307
|
+
@app_row += config[:height] # this needs to take into account height of prev object
|
308
|
+
end
|
309
|
+
end
|
310
|
+
useform = nil
|
311
|
+
useform = @form if @current_object.empty?
|
312
|
+
field = Listbox.new useform, config
|
313
|
+
# shooz uses CHANGED, which is equivalent to our CHANGE. Our CHANGED means modified and exited
|
314
|
+
if block
|
315
|
+
# this way you can't pass params to the block
|
316
|
+
field.bind(block_event, &block)
|
317
|
+
end
|
318
|
+
return field
|
319
|
+
end
|
320
|
+
|
321
|
+
# toggle button
|
322
|
+
def toggle *args, &block
|
323
|
+
config = {}
|
324
|
+
# TODO confirm events
|
325
|
+
events = [ :PRESS, :LEAVE, :ENTER ]
|
326
|
+
block_event = :PRESS
|
327
|
+
_process_args args, config, block_event, events
|
328
|
+
config[:text] ||= longest_in_list2( [config[:onvalue], config[:offvalue]])
|
329
|
+
#config[:onvalue] # needed for flow, we need a better way FIXME
|
330
|
+
_position(config)
|
331
|
+
toggle = ToggleButton.new @form, config
|
332
|
+
if block
|
333
|
+
toggle.bind(block_event, &block)
|
334
|
+
end
|
335
|
+
return toggle
|
336
|
+
end
|
337
|
+
# check button
|
338
|
+
def check *args, &block
|
339
|
+
config = {}
|
340
|
+
# TODO confirm events
|
341
|
+
events = [ :PRESS, :LEAVE, :ENTER ]
|
342
|
+
block_event = :PRESS
|
343
|
+
_process_args args, config, block_event, events
|
344
|
+
_position(config)
|
345
|
+
toggle = CheckBox.new @form, config
|
346
|
+
if block
|
347
|
+
toggle.bind(block_event, &block)
|
348
|
+
end
|
349
|
+
return toggle
|
350
|
+
end
|
351
|
+
# radio button
|
352
|
+
def radio *args, &block
|
353
|
+
config = {}
|
354
|
+
# TODO confirm events
|
355
|
+
events = [ :PRESS, :LEAVE, :ENTER ]
|
356
|
+
block_event = :PRESS
|
357
|
+
_process_args args, config, block_event, events
|
358
|
+
a = config[:group]
|
359
|
+
# FIXME we should check if user has set a varialbe in :variable.
|
360
|
+
# we should create a variable, so he can use it if he wants.
|
361
|
+
if @variables.has_key? a
|
362
|
+
v = @variables[a]
|
363
|
+
else
|
364
|
+
v = Variable.new
|
365
|
+
@variables[a] = v
|
366
|
+
end
|
367
|
+
config[:variable] = v
|
368
|
+
config.delete(:group)
|
369
|
+
_position(config)
|
370
|
+
radio = RadioButton.new @form, config
|
371
|
+
if block
|
372
|
+
radio.bind(block_event, &block)
|
373
|
+
end
|
374
|
+
return radio
|
375
|
+
end
|
376
|
+
# editable text area
|
377
|
+
def textarea *args, &block
|
378
|
+
require 'rbcurse/core/widgets/rtextarea'
|
379
|
+
config = {}
|
380
|
+
# TODO confirm events many more
|
381
|
+
events = [ :CHANGE, :LEAVE, :ENTER ]
|
382
|
+
block_event = events[0]
|
383
|
+
_process_args args, config, block_event, events
|
384
|
+
config[:width] = config[:display_length] unless config.has_key? :width
|
385
|
+
_position(config)
|
386
|
+
# if no width given, expand to flows width
|
387
|
+
config[:width] ||= @stack.last.width if @stack.last
|
388
|
+
useform = nil
|
389
|
+
useform = @form if @current_object.empty?
|
390
|
+
w = TextArea.new useform, config
|
391
|
+
if block
|
392
|
+
w.bind(block_event, &block)
|
393
|
+
end
|
394
|
+
return w
|
395
|
+
end
|
396
|
+
# progress bar
|
397
|
+
def progress *args, &block
|
398
|
+
require 'rbcurse/core/widgets/rprogress'
|
399
|
+
config = {}
|
400
|
+
# TODO confirm events many more
|
401
|
+
events = [ :CHANGE, :LEAVE, :ENTER ]
|
402
|
+
block_event = nil
|
403
|
+
_process_args args, config, block_event, events
|
404
|
+
config[:width] = config[:display_length] || 10 unless config.has_key? :width
|
405
|
+
_position(config)
|
406
|
+
w = Progress.new @form, config
|
407
|
+
#if block
|
408
|
+
#w.bind(block_event, &block)
|
409
|
+
#end
|
410
|
+
return w
|
411
|
+
end
|
412
|
+
|
413
|
+
# table widget
|
414
|
+
# @example
|
415
|
+
# data = [["Roger",16,"SWI"], ["Phillip",1, "DEU"]]
|
416
|
+
# colnames = ["Name", "Wins", "Place"]
|
417
|
+
# t = table :width => 40, :height => 10, :columns => colnames, :data => data, :estimate_widths => true
|
418
|
+
# other options are :column_widths => [12,4,12]
|
419
|
+
# :size_to_fit => true
|
420
|
+
def table *args, &block
|
421
|
+
require 'rbcurse/extras/widgets/rtable'
|
422
|
+
config = {}
|
423
|
+
# TODO confirm events many more
|
424
|
+
events = [ :ENTER_ROW, :LEAVE, :ENTER ]
|
425
|
+
block_event = events[0]
|
426
|
+
_process_args args, config, block_event, events
|
427
|
+
# if user is leaving out width, then we don't want it in config
|
428
|
+
# else Widget will put a value of 10 as default, overriding what we've calculated
|
429
|
+
if config.has_key? :display_length
|
430
|
+
config[:width] = config[:display_length] unless config.has_key? :width
|
431
|
+
end
|
432
|
+
ext = config.delete :extended_keys
|
433
|
+
|
434
|
+
model = nil
|
435
|
+
_position(config)
|
436
|
+
# if no width given, expand to flows width
|
437
|
+
config[:width] ||= @stack.last.width if @stack.last
|
438
|
+
w = Table.new @form, config
|
439
|
+
if ext
|
440
|
+
require 'rbcurse/extras/include/tableextended'
|
441
|
+
# so we can increase and decrease column width using keys
|
442
|
+
w.extend TableExtended
|
443
|
+
w.bind_key(?w){ w.next_column }
|
444
|
+
w.bind_key(?b){ w.previous_column }
|
445
|
+
w.bind_key(?+) { w.increase_column }
|
446
|
+
w.bind_key(?-) { w.decrease_column }
|
447
|
+
w.bind_key([?d, ?d]) { w.table_model.delete_at w.current_index }
|
448
|
+
w.bind_key(?u) { w.table_model.undo w.current_index}
|
449
|
+
end
|
450
|
+
if block
|
451
|
+
w.bind(block_event, &block)
|
452
|
+
end
|
453
|
+
return w
|
454
|
+
end
|
455
|
+
# print a title on first row
|
456
|
+
def title string, config={}
|
457
|
+
## TODO center it
|
458
|
+
@window.printstring 1, 30, string, $normalcolor, 'reverse'
|
459
|
+
end
|
460
|
+
# print a sutitle on second row
|
461
|
+
def subtitle string, config={}
|
462
|
+
@window.printstring 2, 30, string, $datacolor, 'normal'
|
463
|
+
end
|
464
|
+
# menu bar
|
465
|
+
def menubar &block
|
466
|
+
require 'rbcurse/core/widgets/rmenu'
|
467
|
+
RubyCurses::MenuBar.new &block
|
468
|
+
end
|
469
|
+
|
470
|
+
# creates a blank row
|
471
|
+
def blank rows=1, config={}
|
472
|
+
@app_row += rows
|
473
|
+
end
|
474
|
+
# displays a horizontal line
|
475
|
+
# takes col (column to start from) from current stack
|
476
|
+
# take row from app_row
|
477
|
+
#
|
478
|
+
# requires width to be passed in config, else defaults to 20
|
479
|
+
# @example
|
480
|
+
# hline :width => 55
|
481
|
+
def hline config={}
|
482
|
+
row = @app_row
|
483
|
+
width = config[:width] || 20
|
484
|
+
_position config
|
485
|
+
col = config[:col] || 1
|
486
|
+
@window.mvwhline( row, col, ACS_HLINE, width)
|
487
|
+
@app_row += 1
|
488
|
+
end
|
489
|
+
def app_header title, config={}, &block
|
490
|
+
require 'rbcurse/core/widgets/applicationheader'
|
491
|
+
header = ApplicationHeader.new @form, title, config, &block
|
492
|
+
end
|
493
|
+
def dock labels, config={}, &block
|
494
|
+
require 'rbcurse/core/widgets/keylabelprinter'
|
495
|
+
klp = RubyCurses::KeyLabelPrinter.new @form, labels, config, &block
|
496
|
+
end
|
497
|
+
def link *args, &block
|
498
|
+
require 'rbcurse/extras/widgets/rlink'
|
499
|
+
config = {}
|
500
|
+
events = [ :PRESS, :LEAVE, :ENTER ]
|
501
|
+
block_event = :PRESS
|
502
|
+
_process_args args, config, block_event, events
|
503
|
+
_position(config)
|
504
|
+
config[:text] ||= config.delete :title
|
505
|
+
config[:highlight_foreground] = "yellow"
|
506
|
+
config[:highlight_background] = "red"
|
507
|
+
toggle = Link.new @form, config
|
508
|
+
if block
|
509
|
+
toggle.bind(block_event, toggle, &block)
|
510
|
+
end
|
511
|
+
return toggle
|
512
|
+
end
|
513
|
+
def menulink *args, &block
|
514
|
+
require 'rbcurse/extras/widgets/rmenulink'
|
515
|
+
config = {}
|
516
|
+
events = [ :PRESS, :LEAVE, :ENTER ]
|
517
|
+
block_event = :PRESS
|
518
|
+
_process_args args, config, block_event, events
|
519
|
+
_position(config)
|
520
|
+
config[:text] ||= config.delete :title
|
521
|
+
config[:highlight_foreground] = "yellow"
|
522
|
+
config[:highlight_background] = "red"
|
523
|
+
toggle = MenuLink.new @form, config
|
524
|
+
if block
|
525
|
+
toggle.bind(block_event, toggle, &block)
|
526
|
+
end
|
527
|
+
return toggle
|
528
|
+
end
|
529
|
+
def splitpane *args, &block
|
530
|
+
require 'rbcurse/rsplitpane2'
|
531
|
+
config = {}
|
532
|
+
events = [ :PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
533
|
+
block_event = events[0]
|
534
|
+
_process_args args, config, block_event, events
|
535
|
+
_position(config)
|
536
|
+
# if no width given, expand to flows width
|
537
|
+
config[:width] ||= @stack.last.width if @stack.last
|
538
|
+
config.delete :title
|
539
|
+
useform = nil
|
540
|
+
useform = @form if @current_object.empty?
|
541
|
+
|
542
|
+
w = SplitPane.new useform, config
|
543
|
+
#if block
|
544
|
+
#w.bind(block_event, w, &block)
|
545
|
+
#end
|
546
|
+
if block_given?
|
547
|
+
@current_object << w
|
548
|
+
#instance_eval &block if block_given?
|
549
|
+
yield w
|
550
|
+
@current_object.pop
|
551
|
+
end
|
552
|
+
return w
|
553
|
+
end
|
554
|
+
def multisplit *args, &block
|
555
|
+
require 'rbcurse/extras/widgets/rmultisplit'
|
556
|
+
config = {}
|
557
|
+
events = [ :PROPERTY_CHANGE, :LEAVE, :ENTER ]
|
558
|
+
block_event = events[0]
|
559
|
+
_process_args args, config, block_event, events
|
560
|
+
_position(config)
|
561
|
+
# if no width given, expand to flows width
|
562
|
+
config[:width] ||= @stack.last.width if @stack.last
|
563
|
+
config.delete :title
|
564
|
+
useform = nil
|
565
|
+
useform = @form if @current_object.empty?
|
566
|
+
|
567
|
+
w = MultiSplit.new useform, config
|
568
|
+
#if block
|
569
|
+
#w.bind(block_event, w, &block)
|
570
|
+
#end
|
571
|
+
if block_given?
|
572
|
+
@current_object << w
|
573
|
+
#instance_eval &block if block_given?
|
574
|
+
yield w
|
575
|
+
@current_object.pop
|
576
|
+
end
|
577
|
+
return w
|
578
|
+
end
|
579
|
+
|
580
|
+
# ADD new widget above this
|
581
|
+
|
582
|
+
# @endgroup
|
583
|
+
|
584
|
+
# @group positioning of components
|
585
|
+
|
586
|
+
# line up vertically whatever comes in, ignoring r and c
|
587
|
+
# margin_top to add to margin of existing stack (if embedded) such as extra spacing
|
588
|
+
# margin to add to margin of existing stack, or window (0)
|
589
|
+
Stack = Struct.new(:margin_top, :margin, :width)
|
590
|
+
def stack config={}, &block
|
591
|
+
@instack = true
|
592
|
+
mt = config[:margin_top] || 1
|
593
|
+
mr = config[:margin] || 0
|
594
|
+
# must take into account margin
|
595
|
+
defw = Ncurses.COLS - mr
|
596
|
+
w = config[:width] || [50, defw].min
|
597
|
+
s = Stack.new(mt, mr, w)
|
598
|
+
@app_row += mt
|
599
|
+
mr += @stack.last.margin if @stack.last
|
600
|
+
#@stack << mr
|
601
|
+
@stack << s
|
602
|
+
instance_eval &block if block_given?
|
603
|
+
@stack.pop
|
604
|
+
@instack = false if @stack.empty?
|
605
|
+
@app_row = 0 if @stack.empty?
|
606
|
+
end
|
607
|
+
# keep adding to right of previous and when no more space
|
608
|
+
# move down and continue fitting in.
|
609
|
+
# Useful for button positioning. Currently, we can use a second flow
|
610
|
+
# to get another row.
|
611
|
+
# TODO: move down when row filled
|
612
|
+
# TODO: align right, center
|
613
|
+
def flow config={}, &block
|
614
|
+
@inflow = true
|
615
|
+
mt = config[:margin_top] || 0
|
616
|
+
@app_row += mt
|
617
|
+
col = @flowstack.last || @stack.last.margin || @app_col
|
618
|
+
col += config[:margin] || 0
|
619
|
+
@flowstack << col
|
620
|
+
@flowcol = col
|
621
|
+
instance_eval &block if block_given?
|
622
|
+
@flowstack.pop
|
623
|
+
@inflow = false if @flowstack.empty?
|
624
|
+
end
|
625
|
+
|
626
|
+
private
|
627
|
+
def quit
|
628
|
+
throw(:close)
|
629
|
+
end
|
630
|
+
# Initialize curses
|
631
|
+
def init_ncurses
|
632
|
+
VER::start_ncurses # this is initializing colors via ColorMap.setup
|
633
|
+
#$ncurses_started = true
|
634
|
+
@stop_ncurses_on_close = true
|
635
|
+
end
|
636
|
+
|
637
|
+
# returns length of longest
|
638
|
+
def longest_in_list list
|
639
|
+
longest = list.inject(0) do |memo,word|
|
640
|
+
memo >= word.length ? memo : word.length
|
641
|
+
end
|
642
|
+
longest
|
643
|
+
end
|
644
|
+
# returns longest item
|
645
|
+
def longest_in_list2 list
|
646
|
+
longest = list.inject(list[0]) do |memo,word|
|
647
|
+
memo.length >= word.length ? memo : word
|
648
|
+
end
|
649
|
+
longest
|
650
|
+
end
|
651
|
+
def run &block
|
652
|
+
begin
|
653
|
+
|
654
|
+
# check if user has passed window coord in config, else root window
|
655
|
+
@window = VER::Window.root_window
|
656
|
+
catch(:close) do
|
657
|
+
@form = Form.new @window
|
658
|
+
@message = Variable.new
|
659
|
+
@message.value = "Message Comes Here"
|
660
|
+
@message_label = RubyCurses::Label.new @form, {:text_variable => @message, :name=>"message_label",:row => 24, :col => 1, :display_length => 60, :height => 1, :color => 'cyan'}
|
661
|
+
$error_message.update_command { @message.set_value($error_message.value) }
|
662
|
+
if block
|
663
|
+
begin
|
664
|
+
#yield(self, @window, @form)
|
665
|
+
instance_eval &block if block_given?
|
666
|
+
loop
|
667
|
+
rescue => ex
|
668
|
+
$log.debug( "APP.rb rescue reached ")
|
669
|
+
$log.debug( ex) if ex
|
670
|
+
$log.debug(ex.backtrace.join("\n")) if ex
|
671
|
+
ensure
|
672
|
+
close
|
673
|
+
# putting it here allows it to be printed on screen, otherwise it was not showing at all.
|
674
|
+
if ex
|
675
|
+
puts "========== EXCEPTION =========="
|
676
|
+
p ex
|
677
|
+
puts "=========="
|
678
|
+
puts(ex.backtrace.join("\n"))
|
679
|
+
end
|
680
|
+
end
|
681
|
+
nil
|
682
|
+
else
|
683
|
+
#@close_on_terminate = true
|
684
|
+
self
|
685
|
+
end #if block
|
686
|
+
end
|
687
|
+
end
|
688
|
+
end
|
689
|
+
# TODO
|
690
|
+
# process args, all widgets should call this
|
691
|
+
def _process_args args, config, block_event, events
|
692
|
+
args.each do |arg|
|
693
|
+
case arg
|
694
|
+
when Array
|
695
|
+
# we can use r,c, w, h
|
696
|
+
row, col, display_length, height = arg
|
697
|
+
config[:row] = row
|
698
|
+
config[:col] = col
|
699
|
+
config[:display_length] = display_length if display_length
|
700
|
+
config[:width] = display_length if display_length
|
701
|
+
# width for most XXX ?
|
702
|
+
config[:height] = height if height
|
703
|
+
when Hash
|
704
|
+
config.merge!(arg)
|
705
|
+
if block_event
|
706
|
+
block_event = config.delete(:block_event){ block_event }
|
707
|
+
raise "Invalid event. Use #{events}" unless events.include? block_event
|
708
|
+
end
|
709
|
+
when String
|
710
|
+
config[:name] = arg
|
711
|
+
config[:title] = arg # some may not have title
|
712
|
+
#config[:text] = arg # some may not have title
|
713
|
+
end
|
714
|
+
end
|
715
|
+
end # _process
|
716
|
+
# position object based on whether in a flow or stack.
|
717
|
+
# @app_row is prepared for next object based on this objects ht
|
718
|
+
def _position config
|
719
|
+
unless @current_object.empty?
|
720
|
+
$log.debug " WWWW returning from position #{@current_object.last} "
|
721
|
+
return
|
722
|
+
end
|
723
|
+
if @inflow
|
724
|
+
#col = @flowstack.last
|
725
|
+
config[:row] = @app_row
|
726
|
+
config[:col] = @flowcol
|
727
|
+
$log.debug " YYYY config #{config} "
|
728
|
+
@flowcol += config[:text].length + 5 # 5 came from buttons
|
729
|
+
elsif @instack
|
730
|
+
# most likely you won't have row and col. should we check or just go ahead
|
731
|
+
col = @stack.last.margin
|
732
|
+
config[:row] = @app_row
|
733
|
+
config[:col] = col
|
734
|
+
@app_row += config[:height] || 1
|
735
|
+
# TODO need to allow stack to have its spacing, but we don't have an object as yet.
|
736
|
+
end
|
737
|
+
end
|
738
|
+
end # class
|
739
|
+
end # module
|
740
|
+
if $0 == __FILE__
|
741
|
+
include RubyCurses
|
742
|
+
#app = App.new
|
743
|
+
#window = app.window
|
744
|
+
#window.printstring 2, 30, "Demo of Listbox - rbcurse", $normalcolor, 'reverse'
|
745
|
+
#app.logger.info "beforegetch"
|
746
|
+
#window.getch
|
747
|
+
#app.close
|
748
|
+
# this was the yield example, but now we've moved to instance eval
|
749
|
+
App.new do
|
750
|
+
@window.printstring 0, 30, "Demo of Listbox - rbcurse", $normalcolor, 'reverse'
|
751
|
+
@window.printstring 1, 30, "Hit F1 to quit", $datacolor, 'normal'
|
752
|
+
form = @form
|
753
|
+
fname = "Search"
|
754
|
+
r, c = 7, 30
|
755
|
+
c += fname.length + 1
|
756
|
+
#field1 = field( [r,c, 30], fname, :bgcolor => "cyan", :block_event => :CHANGE) do |fld|
|
757
|
+
stack :margin_top => 2, :margin => 10 do
|
758
|
+
lbl = label({:text => fname, :color=>'white',:bgcolor=>'red', :mnemonic=> 's'})
|
759
|
+
field1 = field( [r,c, 30], fname, :bgcolor => "cyan",:block_event => :CHANGE) do |fld|
|
760
|
+
message("You entered #{fld.getvalue}. To quit enter quit and tab out")
|
761
|
+
if fld.getvalue == "quit"
|
762
|
+
logger.info "you typed quit!"
|
763
|
+
throw :close
|
764
|
+
end
|
765
|
+
end
|
766
|
+
#field1.set_label Label.new @form, {:text => fname, :color=>'white',:bgcolor=>'red', :mnemonic=> 's'}
|
767
|
+
field1.set_label( lbl )
|
768
|
+
field1.enter do
|
769
|
+
message "you entered this field"
|
770
|
+
end
|
771
|
+
|
772
|
+
stack :margin_top => 2, :margin => 0 do
|
773
|
+
#label( [8, 30, 60],{:text => "A label", :color=>'white',:bgcolor=>'blue'} )
|
774
|
+
end
|
775
|
+
|
776
|
+
@bluelabel = label( [8, 30, 60],{:text => "B label", :color=>'white',:bgcolor=>'blue'} )
|
777
|
+
|
778
|
+
stack :margin_top => 2, :margin => 0 do
|
779
|
+
toggle :onvalue => " Toggle Down ", :offvalue => " Untoggle ", :mnemonic => 'T', :value => true
|
780
|
+
|
781
|
+
toggle :onvalue => " On ", :offvalue => " Off ", :value => true do |e|
|
782
|
+
alert "You pressed me #{e.state}"
|
783
|
+
end
|
784
|
+
check :text => "Check me!", :onvalue => "Checked", :offvalue => "Unchecked", :value => true do |e|
|
785
|
+
# this works but long and complicated
|
786
|
+
#@bluelabel.text = e.item.getvalue ? e.item.onvalue : e.item.offvalue
|
787
|
+
@bluelabel.text = e.item.text
|
788
|
+
end
|
789
|
+
radio :text => "red", :value => "RED", :color => "red", :group => :colors
|
790
|
+
radio :text => "green", :value => "GREEN", :color => "green", :group => :colors
|
791
|
+
flow do
|
792
|
+
button_row = 17
|
793
|
+
ok_button = button( [button_row,30], "OK", {:mnemonic => 'O'}) do
|
794
|
+
alert("About to dump data into log file!")
|
795
|
+
message "Dumped data to log file"
|
796
|
+
end
|
797
|
+
|
798
|
+
# using ampersand to set mnemonic
|
799
|
+
cancel_button = button( [button_row, 40], "&Cancel" ) do
|
800
|
+
if confirm("Do your really want to quit?")== :YES
|
801
|
+
#throw(:close);
|
802
|
+
quit
|
803
|
+
else
|
804
|
+
message "Quit aborted"
|
805
|
+
end
|
806
|
+
end # cancel
|
807
|
+
button "Don't know"
|
808
|
+
end
|
809
|
+
flow :margin_top => 2 do
|
810
|
+
button "Another"
|
811
|
+
button "Line"
|
812
|
+
end
|
813
|
+
stack :margin_top => 2, :margin => 0 do
|
814
|
+
@pbar = progress :width => 20, :bgcolor => 'white', :color => 'red'
|
815
|
+
@pbar1 = progress :width => 20, :style => :old
|
816
|
+
end
|
817
|
+
end
|
818
|
+
end # stack
|
819
|
+
# lets make another column
|
820
|
+
stack :margin_top => 2, :margin => 70 do
|
821
|
+
l = label "Column 2"
|
822
|
+
f1 = field "afield", :bgcolor => 'white', :color => 'black'
|
823
|
+
list_box "A list", :list => ["Square", "Oval", "Rectangle", "Somethinglarge"], :choose => ["Square"]
|
824
|
+
lb = list_box "Another", :list => ["Square", "Oval", "Rectangle", "Somethinglarge"] do |list|
|
825
|
+
#f1.set_buffer list.text
|
826
|
+
#f1.text list.text
|
827
|
+
f1.text = list.text
|
828
|
+
l.text = list.text.upcase
|
829
|
+
end
|
830
|
+
t = textarea :height => 10 do |e|
|
831
|
+
#@bluelabel.text = e.to_s.tr("\n",' ')
|
832
|
+
@bluelabel.text = e.text.gsub("\n"," ")
|
833
|
+
len = e.source.get_text.length
|
834
|
+
len = len % 20 if len > 20
|
835
|
+
$log.debug " PBAR len of text is #{len}: #{len/20.0} "
|
836
|
+
@pbar.fraction(len/20.0)
|
837
|
+
@pbar1.fraction(len/20.0)
|
838
|
+
i = ((len/20.0)*100).to_i
|
839
|
+
@pbar.text = "completed:#{i}"
|
840
|
+
end
|
841
|
+
t.leave do |c|
|
842
|
+
@bluelabel.text = c.get_text.gsub("\n"," ")
|
843
|
+
end
|
844
|
+
|
845
|
+
end
|
846
|
+
|
847
|
+
# Allow user to get the keys
|
848
|
+
keypress do |key|
|
849
|
+
if key == :C_c
|
850
|
+
message "You tried to cancel"
|
851
|
+
#throw :close
|
852
|
+
quit
|
853
|
+
else
|
854
|
+
#app.message "You pressed #{key}, #{char} "
|
855
|
+
message "You pressed #{key}"
|
856
|
+
end
|
857
|
+
end
|
858
|
+
end
|
859
|
+
end
|