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,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
|