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,194 @@
|
|
|
1
|
+
require 'canis/core/widgets/rwidget'
|
|
2
|
+
#include Ncurses # FFI 2011-09-8
|
|
3
|
+
include Canis
|
|
4
|
+
module Canis
|
|
5
|
+
#
|
|
6
|
+
# This paints labels for various keys at the bottom of the screen, in 2 rows.
|
|
7
|
+
# This is based on alpines last 2 rows. Modes are supported so that the
|
|
8
|
+
# labels change as you enter a widget.
|
|
9
|
+
# For an example, see dbdemo.rb or rfe.rb
|
|
10
|
+
# NOTE: applications using 'App' use a shortcut "dock" to create this.
|
|
11
|
+
#
|
|
12
|
+
# The most minimal keylabel to print one label in first row, and none in second is:
|
|
13
|
+
# [["F1", "Help"], nil]
|
|
14
|
+
# To print 2 labels, one over the other:
|
|
15
|
+
# [["F1", "Help"], ["F10", "Quit"]]
|
|
16
|
+
#
|
|
17
|
+
class KeyLabelPrinter < Widget
|
|
18
|
+
attr_reader :key_labels
|
|
19
|
+
# the current mode (labels are based on mode, changing the mode, changes the labels
|
|
20
|
+
# displayed)
|
|
21
|
+
dsl_property :mode
|
|
22
|
+
# set the color of the labels, overriding the defaults
|
|
23
|
+
dsl_accessor :footer_color_pair
|
|
24
|
+
# set the color of the mnemonic, overriding the defaults
|
|
25
|
+
dsl_accessor :footer_mnemonic_color_pair
|
|
26
|
+
#attr_accessor :row_relative # lets only advertise this when we've tested it out
|
|
27
|
+
|
|
28
|
+
def initialize form, key_labels, config={}, &block
|
|
29
|
+
|
|
30
|
+
@name = "dock"
|
|
31
|
+
case key_labels
|
|
32
|
+
when Hash
|
|
33
|
+
raise "KeyLabelPrinter: KeyLabels cannot be a hash, Array of key labels required. Perhaps you did not pass labels"
|
|
34
|
+
when Array
|
|
35
|
+
else
|
|
36
|
+
raise "KeyLabelPrinter: Array of key labels required. Perhaps you did not pass labels"
|
|
37
|
+
end
|
|
38
|
+
super form, config, &block
|
|
39
|
+
@mode ||= :normal
|
|
40
|
+
#@key_labels = key_labels
|
|
41
|
+
@key_hash = {}
|
|
42
|
+
@key_hash[@mode] = key_labels
|
|
43
|
+
@editable = false
|
|
44
|
+
@focusable = false
|
|
45
|
+
unless @row
|
|
46
|
+
@row_relative = -2
|
|
47
|
+
@row = Ncurses.LINES + @row_relative
|
|
48
|
+
end
|
|
49
|
+
@col ||= 0
|
|
50
|
+
# if negativ row passed we store as relative to bottom, so we can maintain that.
|
|
51
|
+
if @row < 0
|
|
52
|
+
@row_relative = @row
|
|
53
|
+
@row = Ncurses.LINES - @row
|
|
54
|
+
else
|
|
55
|
+
@row_relative = (Ncurses.LINES - @row) * -1
|
|
56
|
+
end
|
|
57
|
+
@cols ||= Ncurses.COLS-1
|
|
58
|
+
@repaint_required = true
|
|
59
|
+
@footer_color_pair ||= $bottomcolor
|
|
60
|
+
@footer_mnemonic_color_pair ||= $reversecolor #2
|
|
61
|
+
end
|
|
62
|
+
def key_labels mode=@mode
|
|
63
|
+
@key_hash[mode]
|
|
64
|
+
end
|
|
65
|
+
# returns the keys as printed. these may or may not help
|
|
66
|
+
# in validation depedign on what you passed as zeroth index
|
|
67
|
+
def get_current_keys
|
|
68
|
+
a = []
|
|
69
|
+
@key_hash[@mode].each do |arr|
|
|
70
|
+
a << arr[0] unless arr.nil?
|
|
71
|
+
end
|
|
72
|
+
return a
|
|
73
|
+
end
|
|
74
|
+
def getvalue
|
|
75
|
+
@key_hash
|
|
76
|
+
end
|
|
77
|
+
def set_key_labels _key_labels, mode=:normal
|
|
78
|
+
@key_hash[mode] = _key_labels
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# XXX need to move wrapping etc up and done once.
|
|
83
|
+
def repaint
|
|
84
|
+
return unless @repaint_required
|
|
85
|
+
r,c = rowcol
|
|
86
|
+
# this should only happen if there's a change in window
|
|
87
|
+
if @row_relative
|
|
88
|
+
@row = Ncurses.LINES+@row_relative
|
|
89
|
+
end
|
|
90
|
+
arr = key_labels()
|
|
91
|
+
print_key_labels(arr, mode=@mode)
|
|
92
|
+
@repaint_required = false
|
|
93
|
+
end
|
|
94
|
+
# ?? does not use mode, i think key_labels is unused. a hash is now used 2011-10-11 XXX FIXME
|
|
95
|
+
# WARNING, i have not tested this after changing it.
|
|
96
|
+
def append_key_label key, label, mode=@mode
|
|
97
|
+
#@key_labels << [key, label] if !@key_labels.include? [key, label]
|
|
98
|
+
@key_hash[mode] << [key, label] if !@key_hash[mode].include? [key, label]
|
|
99
|
+
@repaint_required = true
|
|
100
|
+
end
|
|
101
|
+
def print_key_labels(arr = key_labels(), mode=@mode)
|
|
102
|
+
#return if !@show_key_labels # XXX
|
|
103
|
+
@win ||= @form.window
|
|
104
|
+
#$log.debug "XXX: PKL #{arr.length}, #{arr}"
|
|
105
|
+
@padding = @cols / (arr.length/2)
|
|
106
|
+
posx = 0
|
|
107
|
+
even = []
|
|
108
|
+
odd = []
|
|
109
|
+
arr.each_index { |i|
|
|
110
|
+
if i % 2 == 0
|
|
111
|
+
#arr[i+1] = ['',''] if arr[i+1].nil?
|
|
112
|
+
nextarr = arr[i+1] || ['', '']
|
|
113
|
+
keyw = [arr[i][0].length, nextarr[0].length].max
|
|
114
|
+
labelw = [arr[i][1].length, nextarr[1].length].max
|
|
115
|
+
|
|
116
|
+
even << [ sprintf("%*s", keyw, arr[i][0]), sprintf("%-*s", labelw, arr[i][1]) ]
|
|
117
|
+
odd << [ sprintf("%*s", keyw, nextarr[0]), sprintf("%-*s", labelw, nextarr[1]) ]
|
|
118
|
+
#$log.debug("loop even: #{even.inspect}")
|
|
119
|
+
else
|
|
120
|
+
end
|
|
121
|
+
}
|
|
122
|
+
#$log.debug("even: #{even.inspect}")
|
|
123
|
+
#$log.debug("odd : #{odd.inspect}")
|
|
124
|
+
#posy = @barrow-1
|
|
125
|
+
posy = @row
|
|
126
|
+
print_key_labels_row(posy, posx, even)
|
|
127
|
+
posy = @row+1
|
|
128
|
+
print_key_labels_row(posy, posx, odd)
|
|
129
|
+
# uncommented next line after ffi-ncurses else not showing till key press FFI 2011-09-17
|
|
130
|
+
@win.wrefresh # needed else secod row not shown after askchoice XXX
|
|
131
|
+
end
|
|
132
|
+
def print_key_labels_row(posy, posx, arr)
|
|
133
|
+
# FIXME: this logic of padding needs to take into account
|
|
134
|
+
# width of window
|
|
135
|
+
padding = 8
|
|
136
|
+
padding = 4 if arr.length > 5
|
|
137
|
+
padding = 2 if arr.length > 7
|
|
138
|
+
padding = 0 if arr.length > 9
|
|
139
|
+
#padding = @padding # XXX 2008-11-13 23:01
|
|
140
|
+
my_form_win = @win
|
|
141
|
+
@win.printstring(posy,0, "%-*s" % [@cols," "], @footer_color_pair, @attr)
|
|
142
|
+
arr.each do |kl|
|
|
143
|
+
key = kl[0]
|
|
144
|
+
lab = kl[1]
|
|
145
|
+
if key !="" # don't print that white blank space for fillers
|
|
146
|
+
color_pair= @footer_mnemonic_color_pair # $reversecolor #2
|
|
147
|
+
x = posx + (key.length - key.strip.length)
|
|
148
|
+
my_form_win.attron(Ncurses.COLOR_PAIR(color_pair))
|
|
149
|
+
my_form_win.mvprintw(posy, x, "%s" % kl[0].strip );
|
|
150
|
+
my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair))
|
|
151
|
+
end
|
|
152
|
+
color_pair=@footer_color_pair
|
|
153
|
+
posx = posx + kl[0].length
|
|
154
|
+
my_form_win.attron(Ncurses.COLOR_PAIR(color_pair))
|
|
155
|
+
|
|
156
|
+
#lab = sprintf(" %s %*s" , kl[1], padding, " ");
|
|
157
|
+
lab = sprintf(" %s %s" , kl[1], " "*padding);
|
|
158
|
+
my_form_win.mvprintw(posy, posx, lab)
|
|
159
|
+
my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair))
|
|
160
|
+
posx = posx + lab.length
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
##
|
|
164
|
+
# updates existing label with a new one.
|
|
165
|
+
# @return true if updated, else false
|
|
166
|
+
# @example update "C-x", "C-x", "Disable"
|
|
167
|
+
def update_application_key_label(display_code, new_display_code, text)
|
|
168
|
+
@repaint_required = true
|
|
169
|
+
labels = key_labels()
|
|
170
|
+
raise "labels are nil !!!" unless labels
|
|
171
|
+
labels.each_index do |ix|
|
|
172
|
+
lab = labels[ix]
|
|
173
|
+
next if lab.nil?
|
|
174
|
+
if lab[0] == display_code
|
|
175
|
+
labels[ix] = [new_display_code , text]
|
|
176
|
+
$log.debug("updated #{labels[ix]}")
|
|
177
|
+
return true
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
return false
|
|
181
|
+
end
|
|
182
|
+
alias :update :update_application_key_label
|
|
183
|
+
##
|
|
184
|
+
# inserts an application label at given index
|
|
185
|
+
# to add the key, use create_datakeys to add bindings
|
|
186
|
+
# remember to call restore_application_key_labels after updating/inserting
|
|
187
|
+
def insert_application_key_label(index, display_code, text)
|
|
188
|
+
@repaint_required = true
|
|
189
|
+
labels = key_labels()
|
|
190
|
+
labels.insert(index, [display_code , text] )
|
|
191
|
+
end
|
|
192
|
+
# ADD HERE KEYLABEL
|
|
193
|
+
end
|
|
194
|
+
end
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# ----------------------------------------------------------------------------- #
|
|
3
|
+
# File: listbox.rb
|
|
4
|
+
# Description: A list box based on textpad
|
|
5
|
+
# Author: jkepler http://github.com/mare-imbrium/canis/
|
|
6
|
+
# Date: 2014-04-06 - 19:37
|
|
7
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
|
8
|
+
# Last update: 2014-07-07 00:36
|
|
9
|
+
# ----------------------------------------------------------------------------- #
|
|
10
|
+
# listbox.rb Copyright (C) 2012-2014 kepler
|
|
11
|
+
|
|
12
|
+
require 'canis'
|
|
13
|
+
require 'forwardable'
|
|
14
|
+
require 'canis/core/include/listselectionmodel'
|
|
15
|
+
##
|
|
16
|
+
# A listbox based on textpad.
|
|
17
|
+
# Contains a scrollable array of Strings. The list is selectable too.
|
|
18
|
+
# In place editing is not provided, however editing in a separate box
|
|
19
|
+
# has been implemented in various examples.
|
|
20
|
+
# Essentially, the listbox only adds selection to the textpad.
|
|
21
|
+
# TODO
|
|
22
|
+
# ----
|
|
23
|
+
# [ ] focussed_color - this could be part of textpad too. row under cursor
|
|
24
|
+
# [ ] rlist has menu actions that can use prompt menu or popup ?
|
|
25
|
+
# [ ] nothing has been done about show_selector -- consider whether to knock off
|
|
26
|
+
#
|
|
27
|
+
#
|
|
28
|
+
# CHANGES
|
|
29
|
+
# -------
|
|
30
|
+
# - removed Array operations to Textpad, some renaming 2014-04-10 - 20:50
|
|
31
|
+
#
|
|
32
|
+
#
|
|
33
|
+
module Canis
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# A scrollable, selectable array of strings.
|
|
37
|
+
# Delegates display to ListRenderer
|
|
38
|
+
# Delegates selection to Defaultlistselection (/include/listselectionmodel.rb)
|
|
39
|
+
# Due to extending Defaultlistselection, methods are not visible here.
|
|
40
|
+
# Selection methods are (the first three are what programmers will use the most):
|
|
41
|
+
#
|
|
42
|
+
# - `selected_values` : returns values selecteda (multiple selection)
|
|
43
|
+
# - `selected_value` : returns value of row selected (single selection)
|
|
44
|
+
# - `selected_rows` : same as selected_indices, indices of selected items
|
|
45
|
+
#
|
|
46
|
+
# - `toggle_row_selection` : toggles current row, called by key $row_selector
|
|
47
|
+
# - `select` : select given or current row
|
|
48
|
+
# - `unselect` : unselects given or current row
|
|
49
|
+
# - `is_row_selected?` : determine if given row is selected
|
|
50
|
+
# - `is_selection_empty?` : has anything been selected
|
|
51
|
+
# - `clear_selection` : clear selection
|
|
52
|
+
# - `select_all` : select all rows
|
|
53
|
+
#
|
|
54
|
+
# Listbox also fires a ListSelectionEvent whose type can be:
|
|
55
|
+
#
|
|
56
|
+
# - :INSERT , a row or rows added to selection
|
|
57
|
+
# - :DELETE , a row or rows removed from selection
|
|
58
|
+
# - :CLEAR , all selection cleared
|
|
59
|
+
#
|
|
60
|
+
# == Examples
|
|
61
|
+
#
|
|
62
|
+
# mylist = %w[john tim matz shougo _why sean aaron]
|
|
63
|
+
# l = Listbox.new @form, :row => 5, :col => 4, :height => 10, :width => 20, :list => mylist
|
|
64
|
+
#
|
|
65
|
+
# Inside a Flow:
|
|
66
|
+
#
|
|
67
|
+
# lb = listbox :list => mylist, :title => 'Contacts', :width_pc => 50, :selection_mode => :single
|
|
68
|
+
#
|
|
69
|
+
class Listbox < TextPad
|
|
70
|
+
|
|
71
|
+
extend Forwardable
|
|
72
|
+
|
|
73
|
+
# boolean, should a selector character be shown on the left of data for selected rows.
|
|
74
|
+
dsl_property :show_selector
|
|
75
|
+
# should textpads content_cols also add left_margin ? XXX
|
|
76
|
+
# how much space to leave on left, currently 0, was used with selector character once
|
|
77
|
+
dsl_property :left_margin
|
|
78
|
+
|
|
79
|
+
# justify text to :left :right or :center (renderer to take care of this).
|
|
80
|
+
dsl_accessor :justify
|
|
81
|
+
|
|
82
|
+
# should focussed line be shown in a different way, currently BOLD, default true
|
|
83
|
+
dsl_accessor :should_show_focus
|
|
84
|
+
|
|
85
|
+
def initialize form = nil, config={}, &block
|
|
86
|
+
|
|
87
|
+
@left_margin = 0
|
|
88
|
+
@should_show_focus = true
|
|
89
|
+
|
|
90
|
+
register_events([:LEAVE_ROW, :LIST_SELECTION_EVENT])
|
|
91
|
+
self.extend DefaultListSelection
|
|
92
|
+
super
|
|
93
|
+
# textpad takes care of enter_row and press
|
|
94
|
+
#@_events.push(*[:LEAVE_ROW, :LIST_SELECTION_EVENT])
|
|
95
|
+
bind_key(?f, 'next row starting with char'){ set_selection_for_char(nil) }
|
|
96
|
+
|
|
97
|
+
# if user has not specified a selection model, install default
|
|
98
|
+
unless @selection_mode == :none
|
|
99
|
+
unless @list_selection_model
|
|
100
|
+
create_default_selection_model
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
# if user has not specified a renderer, install default
|
|
104
|
+
unless @renderer
|
|
105
|
+
create_default_renderer
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
# create a default renderer since user has not specified
|
|
109
|
+
# Widgets inheriting this with a differernt rendering such as tree
|
|
110
|
+
# can overrider this.
|
|
111
|
+
def create_default_renderer
|
|
112
|
+
r = ListRenderer.new self
|
|
113
|
+
renderer(r)
|
|
114
|
+
end
|
|
115
|
+
def renderer *val
|
|
116
|
+
if val.empty?
|
|
117
|
+
return @renderer
|
|
118
|
+
end
|
|
119
|
+
@renderer = val[0]
|
|
120
|
+
end
|
|
121
|
+
# create a default selection model
|
|
122
|
+
# Widgets inheriting this may override this
|
|
123
|
+
def create_default_selection_model
|
|
124
|
+
list_selection_model(Canis::DefaultListSelectionModel.new self)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# http://www.opensource.apple.com/source/gcc/gcc-5483/libjava/javax/swing/table/DefaultTableColumnModel.java
|
|
129
|
+
#
|
|
130
|
+
# clear the list completely of data, including selections
|
|
131
|
+
def clear
|
|
132
|
+
@selected_indices.clear
|
|
133
|
+
super
|
|
134
|
+
end
|
|
135
|
+
alias :remove_all :clear
|
|
136
|
+
|
|
137
|
+
# This is called whenever user leaves a row
|
|
138
|
+
# Fires handler for leave_row
|
|
139
|
+
def on_leave_row arow
|
|
140
|
+
# leave this out, since we are not painting on exit of widget 2014-07-02 - 17:51
|
|
141
|
+
#if @should_show_focus
|
|
142
|
+
#fire_row_changed arow
|
|
143
|
+
#end
|
|
144
|
+
fire_handler :LEAVE_ROW, self
|
|
145
|
+
end
|
|
146
|
+
# This is called whenever user enters a row
|
|
147
|
+
def on_enter_row arow
|
|
148
|
+
super
|
|
149
|
+
# TODO check if user wants focus to be showed
|
|
150
|
+
## this results in the row being entered and left being evaluated and repainted
|
|
151
|
+
# which means that the focussed row can be bolded. The renderer's +render+ method will be triggered
|
|
152
|
+
if @should_show_focus
|
|
153
|
+
fire_row_changed @oldindex
|
|
154
|
+
fire_row_changed arow
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
#def on_leave
|
|
158
|
+
#super
|
|
159
|
+
#on_leave_row @current_index if @current_index
|
|
160
|
+
#end
|
|
161
|
+
# get a char ensure it is a char or number
|
|
162
|
+
# In this state, it could accept control and other chars.
|
|
163
|
+
private
|
|
164
|
+
def _ask_a_char
|
|
165
|
+
ch = @graphic.getch
|
|
166
|
+
#message "achar is #{ch}"
|
|
167
|
+
if ch < 26 || ch > 255
|
|
168
|
+
@graphic.ungetch ch
|
|
169
|
+
return :UNHANDLED
|
|
170
|
+
end
|
|
171
|
+
return ch.chr
|
|
172
|
+
end
|
|
173
|
+
public
|
|
174
|
+
# sets the selection to the next row starting with char
|
|
175
|
+
# Trying to return unhandled is having no effect right now. if only we could pop it into a
|
|
176
|
+
# stack or unget it.
|
|
177
|
+
def set_selection_for_char char=nil
|
|
178
|
+
char = _ask_a_char unless char
|
|
179
|
+
return :UNHANDLED if char == :UNHANDLED
|
|
180
|
+
#alert "got #{char}"
|
|
181
|
+
@oldrow = @current_index
|
|
182
|
+
@last_regex = /^#{char}/i
|
|
183
|
+
ix = next_regex @last_regex
|
|
184
|
+
return unless ix
|
|
185
|
+
@current_index = ix[0]
|
|
186
|
+
#alert "curr ind #{@current_index} "
|
|
187
|
+
@search_found_ix = @current_index
|
|
188
|
+
@curpos = ix[1]
|
|
189
|
+
ensure_visible
|
|
190
|
+
return @current_index
|
|
191
|
+
end
|
|
192
|
+
# Find the next row that contains given string
|
|
193
|
+
# @return row and col offset of match, or nil
|
|
194
|
+
# @param String to find
|
|
195
|
+
def next_regex str
|
|
196
|
+
first = nil
|
|
197
|
+
## content can be string or Chunkline, so we had to write <tt>index</tt> for this.
|
|
198
|
+
## =~ does not give an error, but it does not work.
|
|
199
|
+
@list.each_with_index do |line, ix|
|
|
200
|
+
col = line =~ /#{str}/
|
|
201
|
+
if col
|
|
202
|
+
first ||= [ ix, col ]
|
|
203
|
+
if ix > @current_index
|
|
204
|
+
return [ix, col]
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
return first
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
end # class listbox
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
## Takes care of rendering the list.
|
|
215
|
+
# In the case of a List we take care of selected indices.
|
|
216
|
+
# Also, focussed row is shown in bold, although we can make that optional and configurable
|
|
217
|
+
# A user wanting a different rendering of listboxes may either extend this class
|
|
218
|
+
# or completely replace it and set it as the renderer.
|
|
219
|
+
class ListRenderer < AbstractTextPadRenderer
|
|
220
|
+
# text to be placed in the left margin. This requires that a left margin be set in the source
|
|
221
|
+
# object.
|
|
222
|
+
attr_accessor :left_margin_text
|
|
223
|
+
attr_accessor :row_focussed_attr
|
|
224
|
+
|
|
225
|
+
def initialize source
|
|
226
|
+
@source = source
|
|
227
|
+
# internal width based on both borders - earlier internal_width which we need
|
|
228
|
+
@int_w = 3
|
|
229
|
+
# 3 leaves a blank black in popuplists as in testlistbox.rb F4
|
|
230
|
+
# setting it as 2 means that in some cases, the next line first character
|
|
231
|
+
# gets overwritten with traversal
|
|
232
|
+
#@int_w = 2
|
|
233
|
+
end
|
|
234
|
+
# This is called prior to render_all, and may not be called when a single row is rendered
|
|
235
|
+
# as in fire_row_changed
|
|
236
|
+
def pre_render
|
|
237
|
+
super
|
|
238
|
+
@selected_indices = @source.selected_indices
|
|
239
|
+
@left_margin = @source.left_margin
|
|
240
|
+
@bg = @source.bgcolor
|
|
241
|
+
@fg = @source.color
|
|
242
|
+
@attr = NORMAL
|
|
243
|
+
@row_focussed_attr ||= $row_focussed_attr
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
#
|
|
247
|
+
# @param pad for calling print methods on
|
|
248
|
+
# @param lineno the line number on the pad to print on
|
|
249
|
+
# @param text data to print
|
|
250
|
+
#--
|
|
251
|
+
# NOTE: in some cases like testlistbox.rb if a line is updated then the newly printed
|
|
252
|
+
# value may not overwrite the entire line, addstr seems to only write the text no more
|
|
253
|
+
# Fixed with +clear_row+
|
|
254
|
+
#++
|
|
255
|
+
def render pad, lineno, text
|
|
256
|
+
sele = false
|
|
257
|
+
=begin
|
|
258
|
+
bg = @source.bgcolor
|
|
259
|
+
fg = @source.color
|
|
260
|
+
att = NORMAL
|
|
261
|
+
cp = get_color($datacolor, fg, bg)
|
|
262
|
+
=end
|
|
263
|
+
bg = @bg || @source.bgcolor
|
|
264
|
+
fg = @fg || @source.color
|
|
265
|
+
att = @attr || NORMAL
|
|
266
|
+
cp = get_color($datacolor, fg, bg)
|
|
267
|
+
|
|
268
|
+
if @selected_indices.include? lineno
|
|
269
|
+
# print selected row in reverse
|
|
270
|
+
sele = true
|
|
271
|
+
fg = @source.selected_color || fg
|
|
272
|
+
bg = @source.selected_bgcolor || bg
|
|
273
|
+
att = @source.selected_attr || REVERSE
|
|
274
|
+
cp = get_color($datacolor, fg, bg)
|
|
275
|
+
elsif lineno == @source.current_index
|
|
276
|
+
# print focussed row in different attrib
|
|
277
|
+
if @source.should_show_focus
|
|
278
|
+
# bold was supposed to be if the object loses focus, but although render is called
|
|
279
|
+
# however, padrefresh is not happening since we do not paint on exiting a widget
|
|
280
|
+
att = BOLD
|
|
281
|
+
if @source.focussed
|
|
282
|
+
att = @row_focussed_attr
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
# take current index into account as BOLD
|
|
286
|
+
# and oldindex as normal
|
|
287
|
+
end
|
|
288
|
+
FFI::NCurses.wattron(pad,FFI::NCurses.COLOR_PAIR(cp) | att)
|
|
289
|
+
FFI::NCurses.mvwaddstr(pad, lineno, 0, @left_margin_text) if @left_margin_text
|
|
290
|
+
FFI::NCurses.mvwaddstr(pad, lineno, @left_margin, text)
|
|
291
|
+
FFI::NCurses.wattroff(pad,FFI::NCurses.COLOR_PAIR(cp) | att)
|
|
292
|
+
|
|
293
|
+
# the above only sets the attrib under the text not the whole line, we
|
|
294
|
+
# need the whole line to be REVERSE
|
|
295
|
+
# Strangely in testlistbox1 unselecting removes the entire lines REVERSE
|
|
296
|
+
# but in testlistbox.rb the previous selected lines REV only partially goes
|
|
297
|
+
# so we have to make the entire line in current attrib
|
|
298
|
+
sele = true
|
|
299
|
+
if sele
|
|
300
|
+
FFI::NCurses.mvwchgat(pad, y=lineno, x=@left_margin, @source.width - @left_margin - @int_w, att, cp, nil)
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
# clear row before writing so previous contents are erased and don't show through
|
|
304
|
+
# I could do this everytime i write but trying to make it faster
|
|
305
|
+
# and only call this if +fire_row_changed+ is called.
|
|
306
|
+
# NOTE: in clear_row one is supposed to clear to the width of the pad, not window
|
|
307
|
+
# otherwise on scrolling you might get black bg if you have some other color bg.
|
|
308
|
+
# This is mostly important if you have a bgcolor that is different from the terminal
|
|
309
|
+
# bgcolor.
|
|
310
|
+
# @param - pad
|
|
311
|
+
# @param - line number (index of row to clear)
|
|
312
|
+
def _clear_row pad, lineno
|
|
313
|
+
raise "unused"
|
|
314
|
+
@color_pair ||= get_color($datacolor, @source.color, @source.bgcolor)
|
|
315
|
+
cp = @color_pair
|
|
316
|
+
att = NORMAL
|
|
317
|
+
@_clearstring ||= " " * (@source.width - @left_margin - @int_w)
|
|
318
|
+
# with int_w = 3 we get that one space in popuplist
|
|
319
|
+
# added attr on 2014-05-02 - 00:16 otherwise a list inside a white bg messagebox shows
|
|
320
|
+
# empty rows in black bg.
|
|
321
|
+
FFI::NCurses.wattron(pad,FFI::NCurses.COLOR_PAIR(cp) | att)
|
|
322
|
+
FFI::NCurses.mvwaddstr(pad,lineno, @left_margin, @_clearstring)
|
|
323
|
+
FFI::NCurses.wattroff(pad,FFI::NCurses.COLOR_PAIR(cp) | att)
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
end # module
|