canis 0.0.4
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.
- 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
|