canis 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +45 -0
- data/CHANGES +52 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +24 -0
- data/Rakefile +2 -0
- data/canis.gemspec +25 -0
- data/examples/alpmenu.rb +46 -0
- data/examples/app.sample +19 -0
- data/examples/appemail.rb +191 -0
- data/examples/atree.rb +105 -0
- data/examples/bline.rb +181 -0
- data/examples/common/devel.rb +319 -0
- data/examples/common/file.rb +93 -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 +59 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/table.txt +37 -0
- data/examples/data/tasks.csv +88 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todo.txt +16 -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 +506 -0
- data/examples/dirtree.rb +177 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +212 -0
- data/examples/tasks.rb +179 -0
- data/examples/term2.rb +88 -0
- data/examples/testbuttons.rb +307 -0
- data/examples/testcombo.rb +102 -0
- data/examples/testdb.rb +182 -0
- data/examples/testfields.rb +208 -0
- data/examples/testflowlayout.rb +43 -0
- data/examples/testkeypress.rb +98 -0
- data/examples/testlistbox.rb +187 -0
- data/examples/testlistbox1.rb +199 -0
- data/examples/testmessagebox.rb +144 -0
- data/examples/testprogress.rb +116 -0
- data/examples/testree.rb +107 -0
- data/examples/testsplitlayout.rb +53 -0
- data/examples/testsplitlayout1.rb +49 -0
- data/examples/teststacklayout.rb +48 -0
- data/examples/testwsshortcuts.rb +68 -0
- data/examples/testwsshortcuts2.rb +129 -0
- data/lib/canis.rb +16 -0
- data/lib/canis/core/docs/index.txt +104 -0
- data/lib/canis/core/docs/list.txt +16 -0
- data/lib/canis/core/docs/style_help.yml +34 -0
- data/lib/canis/core/docs/tabbedpane.txt +15 -0
- data/lib/canis/core/docs/table.txt +31 -0
- data/lib/canis/core/docs/textpad.txt +48 -0
- data/lib/canis/core/docs/tree.txt +23 -0
- data/lib/canis/core/include/.DS_Store +0 -0
- data/lib/canis/core/include/action.rb +83 -0
- data/lib/canis/core/include/actionmanager.rb +49 -0
- data/lib/canis/core/include/appmethods.rb +179 -0
- data/lib/canis/core/include/bordertitle.rb +49 -0
- data/lib/canis/core/include/canisparser.rb +100 -0
- data/lib/canis/core/include/colorparser.rb +437 -0
- data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
- data/lib/canis/core/include/io.rb +320 -0
- data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
- data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
- data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
- data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
- data/lib/canis/core/include/listbindings.rb +89 -0
- data/lib/canis/core/include/listeditable.rb +319 -0
- data/lib/canis/core/include/listoperations.rb +61 -0
- data/lib/canis/core/include/listselectionmodel.rb +388 -0
- data/lib/canis/core/include/multibuffer.rb +173 -0
- data/lib/canis/core/include/ractionevent.rb +73 -0
- data/lib/canis/core/include/rchangeevent.rb +27 -0
- data/lib/canis/core/include/rhistory.rb +95 -0
- data/lib/canis/core/include/rinputdataevent.rb +47 -0
- data/lib/canis/core/include/textdocument.rb +111 -0
- data/lib/canis/core/include/vieditable.rb +175 -0
- data/lib/canis/core/include/widgetmenu.rb +66 -0
- data/lib/canis/core/system/colormap.rb +165 -0
- data/lib/canis/core/system/keydefs.rb +32 -0
- data/lib/canis/core/system/ncurses.rb +237 -0
- data/lib/canis/core/system/panel.rb +129 -0
- data/lib/canis/core/system/window.rb +1081 -0
- data/lib/canis/core/util/ansiparser.rb +119 -0
- data/lib/canis/core/util/app.rb +696 -0
- data/lib/canis/core/util/basestack.rb +412 -0
- data/lib/canis/core/util/defaultcolorparser.rb +84 -0
- data/lib/canis/core/util/extras/README +5 -0
- data/lib/canis/core/util/extras/bottomline.rb +1815 -0
- data/lib/canis/core/util/extras/padreader.rb +192 -0
- data/lib/canis/core/util/focusmanager.rb +31 -0
- data/lib/canis/core/util/helpmanager.rb +160 -0
- data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
- data/lib/canis/core/util/promptmenu.rb +235 -0
- data/lib/canis/core/util/rcommandwindow.rb +933 -0
- data/lib/canis/core/util/rdialogs.rb +520 -0
- data/lib/canis/core/util/textutils.rb +74 -0
- data/lib/canis/core/util/viewer.rb +238 -0
- data/lib/canis/core/util/widgetshortcuts.rb +508 -0
- data/lib/canis/core/widgets/applicationheader.rb +103 -0
- data/lib/canis/core/widgets/box.rb +58 -0
- data/lib/canis/core/widgets/divider.rb +310 -0
- data/lib/canis/core/widgets/extras/README.md +12 -0
- data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
- data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
- data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
- data/lib/canis/core/widgets/listbox.rb +326 -0
- data/lib/canis/core/widgets/listfooter.rb +86 -0
- data/lib/canis/core/widgets/rcombo.rb +210 -0
- data/lib/canis/core/widgets/rcontainer.rb +415 -0
- data/lib/canis/core/widgets/rlink.rb +30 -0
- data/lib/canis/core/widgets/rmenu.rb +970 -0
- data/lib/canis/core/widgets/rmenulink.rb +30 -0
- data/lib/canis/core/widgets/rmessagebox.rb +400 -0
- data/lib/canis/core/widgets/rprogress.rb +118 -0
- data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
- data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
- data/lib/canis/core/widgets/rwidget.rb +3634 -0
- data/lib/canis/core/widgets/scrollbar.rb +147 -0
- data/lib/canis/core/widgets/statusline.rb +113 -0
- data/lib/canis/core/widgets/table.rb +1072 -0
- data/lib/canis/core/widgets/tabular.rb +264 -0
- data/lib/canis/core/widgets/textpad.rb +1674 -0
- data/lib/canis/core/widgets/tree.rb +690 -0
- data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
- data/lib/canis/version.rb +3 -0
- metadata +229 -0
@@ -0,0 +1,213 @@
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
2
|
+
# File: abstractlayout.rb
|
3
|
+
# Description: An abstract class for other concrete layouts to subclass
|
4
|
+
# Author: j kepler http://github.com/mare-imbrium/canis/
|
5
|
+
# Date: 2014-05-09 - 17:15
|
6
|
+
# License: MIT
|
7
|
+
# Last update: 2014-05-09 20:38
|
8
|
+
# ----------------------------------------------------------------------------- #
|
9
|
+
# abstractlayout.rb Copyright (C) 2012-2014 j kepler
|
10
|
+
|
11
|
+
|
12
|
+
class AbstractLayout
|
13
|
+
attr_accessor :form
|
14
|
+
# top and left are actually row and col in widgets
|
15
|
+
#
|
16
|
+
attr_accessor :top_margin, :left_margin, :right_margin, :bottom_margin
|
17
|
+
# if width percent is given, then it calculates and overwrites width. Same for height_pc
|
18
|
+
# The _pc values should be between 0 and 1, e.g 0.8 for 80 percent
|
19
|
+
# height and width can be negaive. -1 will stretch the stack to one less than end. 0 will stretch till end.
|
20
|
+
attr_accessor :width, :height, :width_pc, :height_pc
|
21
|
+
# gp between objects
|
22
|
+
attr_accessor :gap
|
23
|
+
attr_accessor :components
|
24
|
+
attr_accessor :ignore_list
|
25
|
+
|
26
|
+
# @param [Form] optional give a form
|
27
|
+
# @param [Hash] optional give settings/attributes which will be set into variables
|
28
|
+
def initialize form, config={}, &block
|
29
|
+
@width = @height = 0
|
30
|
+
@top_margin = @left_margin = @right_margin = @bottom_margin = 0
|
31
|
+
# weightages of each object
|
32
|
+
#@wts = {}
|
33
|
+
# item_config is a hash which contains a hash of attibs for each item.
|
34
|
+
@item_config = Hash.new do |hash, key| hash[key]={}; end
|
35
|
+
|
36
|
+
if form.is_a? Hash
|
37
|
+
@config = form
|
38
|
+
elsif form.is_a? Form
|
39
|
+
@form = form
|
40
|
+
end
|
41
|
+
@gap = 0
|
42
|
+
@ignore_list = ["canis::statusline", "canis::applicationheader"]
|
43
|
+
@config.each_pair { |k,v| instance_variable_set("@#{k}",v) }
|
44
|
+
#@ignore_list = [Canis::StatusLine, Canis::ApplicationHeader]
|
45
|
+
instance_eval &block if block_given?
|
46
|
+
end
|
47
|
+
|
48
|
+
# add one more items for this layout to lay out
|
49
|
+
# If no items are given, this program will take all visible widgets from the form
|
50
|
+
# and stack them, ignoring statusline and applicationheader
|
51
|
+
def push *items
|
52
|
+
@components ||= []
|
53
|
+
@components.push items
|
54
|
+
self
|
55
|
+
end
|
56
|
+
alias :<< :push
|
57
|
+
|
58
|
+
# add a widget giving a hash of attributes to be used later.
|
59
|
+
def add item, config={}
|
60
|
+
@components ||= []
|
61
|
+
@components << item
|
62
|
+
if config
|
63
|
+
@item_config[item] = config
|
64
|
+
end
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def configure_item item, config={}
|
69
|
+
@item_config[item].merge( config )
|
70
|
+
self
|
71
|
+
end
|
72
|
+
# return the config value for a key for an item.
|
73
|
+
# The keys are decided by the layout manager itself, such as :weight.
|
74
|
+
# @param [Widget] item for which some attribute is required
|
75
|
+
# @param [Symbol, String] the key
|
76
|
+
def cget item, key
|
77
|
+
return @item_config[item][key]
|
78
|
+
end
|
79
|
+
|
80
|
+
# set a value for an item and key
|
81
|
+
# This is similar to configure_item which takes multiple pairs ( a hash).
|
82
|
+
# I am seeing which will be more useful.
|
83
|
+
def cset item, key, val
|
84
|
+
@item_config[item][key] = val
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# Add a component, giving a weightage for height
|
90
|
+
# @param [Fixnum, Float] give absolute weight, or fraction of layouts height
|
91
|
+
# if wt is >= 1 then it is absolute height, else if between 0 and 1 ,
|
92
|
+
# it is a percentage.
|
93
|
+
def add_with_weight item, weight
|
94
|
+
@components ||= []
|
95
|
+
@components << item
|
96
|
+
cfg[item][:weight] = weight
|
97
|
+
end
|
98
|
+
|
99
|
+
# remove given item from components list
|
100
|
+
# This could happen if the item has been removed from the form
|
101
|
+
def remove item
|
102
|
+
@components.remove item
|
103
|
+
end
|
104
|
+
|
105
|
+
# clear the list of items the layout has.
|
106
|
+
# Usually, the layout fills this list only once. However, if the list of items has changed
|
107
|
+
# then this can be used to clear the list, so it is fetched again.
|
108
|
+
def clear
|
109
|
+
@components.clear
|
110
|
+
end
|
111
|
+
|
112
|
+
# does some initial common calculations that hopefully should be common across layouters
|
113
|
+
# so that do_layout can be ovveridden while calling this.
|
114
|
+
def _init_layout
|
115
|
+
# when user gives a negative value, we recalc and overwrite so the need to save, for a redraw.
|
116
|
+
@saved_width ||= @width
|
117
|
+
@saved_height ||= @height
|
118
|
+
|
119
|
+
lines = Ncurses.LINES - 1
|
120
|
+
columns = Ncurses.COLS - 1
|
121
|
+
if @height_pc
|
122
|
+
@height = ((lines - @top_margin - @bottom_margin) * @height_pc).floor
|
123
|
+
elsif @saved_height <= 0
|
124
|
+
@height = lines - @saved_height - @top_margin - @bottom_margin
|
125
|
+
end
|
126
|
+
$log.debug " layout height = #{@height} "
|
127
|
+
if @width_pc
|
128
|
+
@width = ((columns - @left_margin - @right_margin) * width_pc).floor
|
129
|
+
elsif @saved_width <= 0
|
130
|
+
# if width was -1 we have overwritten it so now we cannot recalc it. it remains the same
|
131
|
+
@width = columns - @saved_width - @left_margin - @right_margin
|
132
|
+
end
|
133
|
+
$log.debug " layout wid = #{@width} "
|
134
|
+
# if user has not specified, then get all the objects
|
135
|
+
@components ||= @form.widgets.select do |w| w.visible != false && !@ignore_list.include?(w.class.to_s.downcase); end
|
136
|
+
$log.debug " components #{@components.count} "
|
137
|
+
end
|
138
|
+
|
139
|
+
# This program lays out the widgets deciding their row and columm and height and weight.
|
140
|
+
# This program is called once at start of application, and again whenever a RESIZE event happens.
|
141
|
+
def do_layout
|
142
|
+
$log.debug " inside do_layout"
|
143
|
+
_init_layout
|
144
|
+
raise "please implement this in your subclass "
|
145
|
+
c = @left_margin
|
146
|
+
# determine fixed widths and how much is left to share with others,
|
147
|
+
# and how many variable width components there are.
|
148
|
+
ht = 0 # accumulate fixed height
|
149
|
+
fixed_ctr = 0 # how many items have a fixed wt
|
150
|
+
var_ctr = 0
|
151
|
+
var_wt = 0.0
|
152
|
+
@components.each do |e|
|
153
|
+
$log.debug " looping 1 #{e.name} "
|
154
|
+
_tmpwt = @wts[e] || 0
|
155
|
+
# what of field and button placed side by side
|
156
|
+
if e.is_a? Field or e.is_a? Button or e.is_a? Label
|
157
|
+
@wts[e] ||= 1
|
158
|
+
ht += @wts[e] || 1
|
159
|
+
fixed_ctr += 1
|
160
|
+
elsif _tmpwt >= 1
|
161
|
+
ht += @wts[e] || 0
|
162
|
+
fixed_ctr += 1
|
163
|
+
elsif _tmpwt > 0 and _tmpwt <= 1
|
164
|
+
# FIXME how to specify 100 % ???
|
165
|
+
var_ctr += 1
|
166
|
+
var_wt += @wts[e]
|
167
|
+
end
|
168
|
+
end
|
169
|
+
unaccounted = @components.count - (fixed_ctr + var_ctr)
|
170
|
+
$log.debug " unacc #{unaccounted} , fixed #{fixed_ctr} , var : #{var_ctr} , ht #{ht} height #{@height} "
|
171
|
+
balance_ht = @height - ht # use this for those who have specified a %
|
172
|
+
balance_ht1 = balance_ht * (1 - var_wt )
|
173
|
+
average_ht = (balance_ht1 / unaccounted).floor # give this to those who have not specified ht
|
174
|
+
average_ht = (balance_ht1 / unaccounted) # give this to those who have not specified ht
|
175
|
+
$log.debug " #{balance_ht} , #{balance_ht1} , #{average_ht} "
|
176
|
+
# not accounted for gap in heights
|
177
|
+
rem = 0 # remainder to be carried over
|
178
|
+
@components.each do |e|
|
179
|
+
$log.debug " looping 2 #{e.name} #{e.class.to_s.downcase} "
|
180
|
+
next if @ignore_list.include? e.class.to_s.downcase
|
181
|
+
$log.debug " looping 3 #{e.name} "
|
182
|
+
e.row = r
|
183
|
+
e.col = c
|
184
|
+
wt = @wts[e]
|
185
|
+
if wt
|
186
|
+
if wt.is_a? Fixnum
|
187
|
+
e.height = wt
|
188
|
+
elsif wt.is_a? Float
|
189
|
+
e.height = (wt * balance_ht).floor
|
190
|
+
end
|
191
|
+
else
|
192
|
+
# no wt specified, give average of balance wt
|
193
|
+
e.height = average_ht
|
194
|
+
hround = e.height.floor
|
195
|
+
|
196
|
+
rem += e.height - hround
|
197
|
+
e.height = hround
|
198
|
+
# see comment in prev block regarding remaininder
|
199
|
+
if rem >= 1
|
200
|
+
e.height += 1
|
201
|
+
rem = 0
|
202
|
+
end
|
203
|
+
end
|
204
|
+
$log.debug " layout #{e.name} , h: #{e.height} r: #{e.row} , c = #{e.col} "
|
205
|
+
|
206
|
+
e.width = @width
|
207
|
+
r += e.height.floor
|
208
|
+
r += @gap
|
209
|
+
end
|
210
|
+
$log.debug " layout finished "
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
2
|
+
# File: stacklayout.rb
|
3
|
+
# Description:
|
4
|
+
# Author: j kepler http://github.com/mare-imbrium/canis/
|
5
|
+
# Date: 2014-05-08 - 18:33
|
6
|
+
# License: MIT
|
7
|
+
# Last update: 2014-05-09 20:58
|
8
|
+
# ----------------------------------------------------------------------------- #
|
9
|
+
# stacklayout.rb Copyright (C) 2012-2014 j kepler
|
10
|
+
require 'canis/core/include/layouts/abstractlayout'
|
11
|
+
# ----
|
12
|
+
# This does a simple left to right stacking of objects.
|
13
|
+
# if no objects are passed to it, it will take all widgets from the form.
|
14
|
+
#
|
15
|
+
# Individual objects may be configured by setting :weight using +cset+.
|
16
|
+
# layout = FlowLayout.new :height => -1, :top_margin => 1, :bottom_margin => 1, :left_margin => 1
|
17
|
+
# layout.cset(obj, :weight, 15) # fixed width of 15
|
18
|
+
# layout.cset(obj1, :weight, 0.50) # takes 50% of balance area (area not fixed)
|
19
|
+
#
|
20
|
+
class FlowLayout < AbstractLayout
|
21
|
+
|
22
|
+
# @param [Form] optional give a form
|
23
|
+
# @param [Hash] optional give settings/attributes which will be set into variables
|
24
|
+
def initialize arg, config={}, &block
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# This program lays out the widgets deciding their row and columm and height and weight.
|
30
|
+
# This program is called once at start of application, and again whenever a RESIZE event happens.
|
31
|
+
def do_layout
|
32
|
+
_init_layout
|
33
|
+
r = @top_margin
|
34
|
+
c = @left_margin
|
35
|
+
#
|
36
|
+
# determine fixed widths and how much is left to share with others,
|
37
|
+
# and how many variable width components there are.
|
38
|
+
ht = 0 # accumulate fixed height
|
39
|
+
fixed_ctr = 0 # how many items have a fixed wt
|
40
|
+
var_ctr = 0
|
41
|
+
var_wt = 0.0
|
42
|
+
@components.each do |e|
|
43
|
+
$log.debug " looping 1 #{e.name} "
|
44
|
+
_tmpwt = cget(e, :weight) || 0
|
45
|
+
# what of field and button placed side by side
|
46
|
+
if e.is_a? Field or e.is_a? Button or e.is_a? Label
|
47
|
+
# what to do here ?
|
48
|
+
@wts[e] ||= 1
|
49
|
+
ht += @wts[e] || 1
|
50
|
+
fixed_ctr += 1
|
51
|
+
elsif _tmpwt >= 1
|
52
|
+
ht += _tmpwt || 0
|
53
|
+
fixed_ctr += 1
|
54
|
+
elsif _tmpwt > 0 and _tmpwt <= 1
|
55
|
+
# FIXME how to specify 100 % ???
|
56
|
+
var_ctr += 1
|
57
|
+
var_wt += _tmpwt
|
58
|
+
end
|
59
|
+
end
|
60
|
+
unaccounted = @components.count - (fixed_ctr + var_ctr)
|
61
|
+
$log.debug " unacc #{unaccounted} , fixed #{fixed_ctr} , var : #{var_ctr} , ht #{ht} height #{@height} "
|
62
|
+
balance_ht = @width - ht # use this for those who have specified a %
|
63
|
+
balance_ht1 = balance_ht * (1 - var_wt )
|
64
|
+
average_ht = (balance_ht1 / unaccounted).floor # give this to those who have not specified ht
|
65
|
+
average_ht = (balance_ht1 / unaccounted) # give this to those who have not specified ht
|
66
|
+
$log.debug " #{balance_ht} , #{balance_ht1} , #{average_ht} "
|
67
|
+
# not accounted for gap in heights
|
68
|
+
rem = 0 # remainder to be carried over
|
69
|
+
@components.each do |e|
|
70
|
+
$log.debug " looping 2 #{e.name} #{e.class.to_s.downcase} "
|
71
|
+
next if @ignore_list.include? e.class.to_s.downcase
|
72
|
+
$log.debug " looping 3 #{e.name} "
|
73
|
+
e.row = r
|
74
|
+
e.col = c
|
75
|
+
wt = cget(e, :weight)
|
76
|
+
if wt
|
77
|
+
if wt.is_a? Fixnum
|
78
|
+
e.width = wt
|
79
|
+
elsif wt.is_a? Float
|
80
|
+
e.width = (wt * balance_ht).floor
|
81
|
+
end
|
82
|
+
else
|
83
|
+
# no wt specified, give average of balance wt
|
84
|
+
e.width = average_ht
|
85
|
+
hround = e.width.floor
|
86
|
+
|
87
|
+
rem += e.width - hround
|
88
|
+
e.width = hround
|
89
|
+
# see comment in prev block regarding remaininder
|
90
|
+
if rem >= 1
|
91
|
+
e.width += 1
|
92
|
+
rem = 0
|
93
|
+
end
|
94
|
+
end
|
95
|
+
$log.debug " layout #{e.name} , w: #{e.width} r: #{e.row} , c = #{e.col} "
|
96
|
+
|
97
|
+
e.height = @height
|
98
|
+
c += e.width.floor
|
99
|
+
c += @gap
|
100
|
+
end
|
101
|
+
$log.debug " layout finished "
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
2
|
+
# File: stacklayout.rb
|
3
|
+
# Description:
|
4
|
+
# Author: j kepler http://github.com/mare-imbrium/canis/
|
5
|
+
# Date: 2014-05-08 - 18:33
|
6
|
+
# License: MIT
|
7
|
+
# Last update: 2014-05-09 19:58
|
8
|
+
# ----------------------------------------------------------------------------- #
|
9
|
+
# stacklayout.rb Copyright (C) 2012-2014 j kepler
|
10
|
+
require 'canis/core/include/layouts/abstractlayout'
|
11
|
+
# ----
|
12
|
+
# This does a simple stacking of objects. Or all objects.
|
13
|
+
# Some simple layout managers may not require objects to be passed to
|
14
|
+
# it, others that are complex may require the same.
|
15
|
+
class StackLayout < AbstractLayout
|
16
|
+
|
17
|
+
# @param [Form] optional give a form
|
18
|
+
# @param [Hash] optional give settings/attributes which will be set into variables
|
19
|
+
def initialize arg, config={}, &block
|
20
|
+
@wts = {}
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# in case user does not wish to add objects, but wishes to specify the weightage on one,
|
26
|
+
# send in the widget and its weightage.
|
27
|
+
#
|
28
|
+
# @param [Widget] widget whose weightage is to be specified
|
29
|
+
# @param [Float, Fixnum] weightage for the given widget (@see add_with_weight)
|
30
|
+
def weightage item, wt
|
31
|
+
@wts[item] = wt
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# This program lays out the widgets deciding their row and columm and height and weight.
|
36
|
+
# This program is called once at start of application, and again whenever a RESIZE event happens.
|
37
|
+
def do_layout
|
38
|
+
_init_layout
|
39
|
+
r = @top_margin
|
40
|
+
c = @left_margin
|
41
|
+
#
|
42
|
+
# determine fixed widths and how much is left to share with others,
|
43
|
+
# and how many variable width components there are.
|
44
|
+
ht = 0 # accumulate fixed height
|
45
|
+
fixed_ctr = 0 # how many items have a fixed wt
|
46
|
+
var_ctr = 0
|
47
|
+
var_wt = 0.0
|
48
|
+
@components.each do |e|
|
49
|
+
$log.debug " looping 1 #{e.name} "
|
50
|
+
_tmpwt = @wts[e] || 0
|
51
|
+
# what of field and button placed side by side
|
52
|
+
if e.is_a? Field or e.is_a? Button or e.is_a? Label
|
53
|
+
@wts[e] ||= 1
|
54
|
+
ht += @wts[e] || 1
|
55
|
+
fixed_ctr += 1
|
56
|
+
elsif _tmpwt >= 1
|
57
|
+
ht += @wts[e] || 0
|
58
|
+
fixed_ctr += 1
|
59
|
+
elsif _tmpwt > 0 and _tmpwt <= 1
|
60
|
+
# FIXME how to specify 100 % ???
|
61
|
+
var_ctr += 1
|
62
|
+
var_wt += @wts[e]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
unaccounted = @components.count - (fixed_ctr + var_ctr)
|
66
|
+
$log.debug " unacc #{unaccounted} , fixed #{fixed_ctr} , var : #{var_ctr} , ht #{ht} height #{@height} "
|
67
|
+
balance_ht = @height - ht # use this for those who have specified a %
|
68
|
+
balance_ht1 = balance_ht * (1 - var_wt )
|
69
|
+
average_ht = (balance_ht1 / unaccounted).floor # give this to those who have not specified ht
|
70
|
+
average_ht = (balance_ht1 / unaccounted) # give this to those who have not specified ht
|
71
|
+
$log.debug " #{balance_ht} , #{balance_ht1} , #{average_ht} "
|
72
|
+
# not accounted for gap in heights
|
73
|
+
rem = 0 # remainder to be carried over
|
74
|
+
@components.each do |e|
|
75
|
+
$log.debug " looping 2 #{e.name} #{e.class.to_s.downcase} "
|
76
|
+
next if @ignore_list.include? e.class.to_s.downcase
|
77
|
+
$log.debug " looping 3 #{e.name} "
|
78
|
+
e.row = r
|
79
|
+
e.col = c
|
80
|
+
wt = @wts[e]
|
81
|
+
if wt
|
82
|
+
if wt.is_a? Fixnum
|
83
|
+
e.height = wt
|
84
|
+
elsif wt.is_a? Float
|
85
|
+
e.height = (wt * balance_ht).floor
|
86
|
+
end
|
87
|
+
else
|
88
|
+
# no wt specified, give average of balance wt
|
89
|
+
e.height = average_ht
|
90
|
+
hround = e.height.floor
|
91
|
+
|
92
|
+
rem += e.height - hround
|
93
|
+
e.height = hround
|
94
|
+
# see comment in prev block regarding remaininder
|
95
|
+
if rem >= 1
|
96
|
+
e.height += 1
|
97
|
+
rem = 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
$log.debug " layout #{e.name} , h: #{e.height} r: #{e.row} , c = #{e.col} "
|
101
|
+
|
102
|
+
e.width = @width
|
103
|
+
r += e.height.floor
|
104
|
+
r += @gap
|
105
|
+
end
|
106
|
+
$log.debug " layout finished "
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
2
|
+
# File: listbindings.rb
|
3
|
+
# Description: bindings for multi-row widgets such as listbox, table,
|
4
|
+
# Author: jkepler http://github.com/mare-imbrium/canis/
|
5
|
+
# Date: 2011-12-11 - 12:58
|
6
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
7
|
+
# Last update: 2014-06-03 14:10
|
8
|
+
# ----------------------------------------------------------------------------- #
|
9
|
+
#
|
10
|
+
module Canis
|
11
|
+
#
|
12
|
+
# bindings for multi-row widgets such as listbox, table,
|
13
|
+
#
|
14
|
+
module ListBindings
|
15
|
+
extend self
|
16
|
+
def bindings
|
17
|
+
$log.debug "YYYY: INSIDE LISTBINDING FOR #{self.class} "
|
18
|
+
bind_key(Ncurses::KEY_LEFT, 'cursor backward'){ cursor_backward } if respond_to? :cursor_backward
|
19
|
+
bind_key(Ncurses::KEY_RIGHT, 'cursor_forward'){ cursor_forward } if respond_to? :cursor_forward
|
20
|
+
# very irritating when user pressed up arrow, commented off 2012-01-4 can be made optional
|
21
|
+
bind_key(Ncurses::KEY_UP, 'previous row'){ ret = up; } #get_window.ungetch(KEY_BTAB) if ret == :NO_PREVIOUS_ROW }
|
22
|
+
# the next was irritating if user wanted to add a row ! 2011-10-10
|
23
|
+
#bind_key(Ncurses::KEY_DOWN){ ret = down ; get_window.ungetch(KEY_TAB) if ret == :NO_NEXT_ROW }
|
24
|
+
bind_key(Ncurses::KEY_DOWN, 'next row'){ ret = down ; }
|
25
|
+
bind_key(279, 'goto_start'){ goto_start }
|
26
|
+
bind_key(277, 'goto end'){ goto_end }
|
27
|
+
bind_key(338, 'scroll forward'){ scroll_forward() }
|
28
|
+
bind_key(339, 'scroll backward'){ scroll_backward() }
|
29
|
+
|
30
|
+
# this allows us to set on a component basis, or global basis
|
31
|
+
# Motivation was mainly for textarea which needs emacs keys
|
32
|
+
kmap = $key_map_type || :both
|
33
|
+
if kmap == :emacs || kmap == :both
|
34
|
+
bind_key(?\C-v, 'scroll forward'){ scroll_forward }
|
35
|
+
# clashes with M-v for toggle one key selection, i guess you can set it as you like
|
36
|
+
bind_key(?\M-v, 'scroll backward'){ scroll_backward }
|
37
|
+
bind_key(?\C-s, 'ask search'){ ask_search() }
|
38
|
+
bind_key(?\C-n, 'next row'){ down() }
|
39
|
+
bind_key(?\C-p, 'previous row'){ down() }
|
40
|
+
bind_key(?\M->, 'goto bottom'){ goto_end() }
|
41
|
+
bind_key(?\M-<, 'goto top'){ goto_start() }
|
42
|
+
bind_key([?\C-x, ?>], :scroll_right)
|
43
|
+
bind_key([?\C-x, ?<], :scroll_left)
|
44
|
+
end
|
45
|
+
if kmap == :vim || kmap == :both
|
46
|
+
# some of these will not have effect in textarea such as j k, gg and G, search
|
47
|
+
bind_key(?j, 'next row'){ down() }
|
48
|
+
bind_key(?k, 'previous row'){ up() }
|
49
|
+
bind_key(?w, 'forward_word'){ forward_word }
|
50
|
+
bind_key(?b, 'backward_word'){ backward_word }
|
51
|
+
bind_key(?W, 'forward WORD'){ forward_regex :WORD }
|
52
|
+
bind_key(?B, 'backward WORD'){ backward_regex :WORD }
|
53
|
+
bind_key(?\C-d, 'scroll forward'){ scroll_forward() }
|
54
|
+
bind_key(32, 'scroll forward'){ scroll_forward() } unless $row_selector == 32
|
55
|
+
bind_key(0, 'scroll backward'){ scroll_backward() } unless $range_selector == 0
|
56
|
+
bind_key(?\C-b, 'scroll backward'){ scroll_backward() }
|
57
|
+
bind_key(?\C-e, "Scroll Window Down"){ scroll_window_down }
|
58
|
+
bind_key(?\C-y, "Scroll Window Up"){ scroll_window_up }
|
59
|
+
bind_key([?g,?g], 'goto start'){ goto_start } # mapping double keys like vim
|
60
|
+
bind_key(?G, 'goto end'){ goto_end() }
|
61
|
+
|
62
|
+
# textpad has removed this since it messes with bookmarks which are on single-quote
|
63
|
+
bind_key([?',?'], 'goto last position'){ goto_last_position } # vim , goto last row position (not column)
|
64
|
+
bind_key(?L, :bottom_of_window)
|
65
|
+
bind_key(?M, :middle_of_window)
|
66
|
+
bind_key(?H, :top_of_window)
|
67
|
+
|
68
|
+
bind_key(?/, :ask_search)
|
69
|
+
bind_key(?n, :find_more)
|
70
|
+
bind_key(?h, 'cursor backward'){ cursor_backward } if respond_to? :cursor_backward
|
71
|
+
bind_key(?l, 'cursor forward'){ cursor_forward } if respond_to? :cursor_forward
|
72
|
+
bind_key(?$, :cursor_eol)
|
73
|
+
end
|
74
|
+
bind_key(?\C-a, 'start of line'){ cursor_bol } if respond_to? :cursor_bol
|
75
|
+
bind_key(?\C-e, 'end of line'){ cursor_eol } if respond_to? :cursor_eol
|
76
|
+
bind_key(?\M-l, :scroll_right)
|
77
|
+
bind_key(?\M-h, :scroll_left)
|
78
|
+
bind_key(KEY_ENTER, :fire_action_event)
|
79
|
+
|
80
|
+
# save as and edit_external are only in tv and textarea
|
81
|
+
# save_as can be given to list's also and tables
|
82
|
+
# put them someplace so the code can be shared.
|
83
|
+
bind_key([?\C-x, ?\C-s], :saveas)
|
84
|
+
bind_key([?\C-x, ?e], :edit_external)
|
85
|
+
|
86
|
+
end # def
|
87
|
+
end
|
88
|
+
end
|
89
|
+
include Canis::ListBindings
|