rbcurse 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Makefile +21 -0
- data/Manifest.txt +6 -0
- data/README.markdown +6 -4
- data/TODO +372 -0
- data/TODO2.txt +121 -0
- data/VERSION +1 -1
- data/examples/README.txt +67 -0
- data/examples/abasiclist.rb +33 -0
- data/examples/alpmenu.rb +42 -0
- data/examples/app.rb +859 -0
- data/examples/app.sample +17 -0
- data/examples/appdirtree.rb +74 -0
- data/examples/appemail.rb +191 -0
- data/examples/appemaillb.rb +308 -0
- data/examples/appgcompose.rb +315 -0
- data/examples/atree.rb +64 -0
- data/examples/common/file.rb +40 -0
- data/examples/common/rmail.rb +257 -0
- data/examples/data.txt +683 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +60 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +495 -0
- data/examples/deprecated/appgmail.rb +952 -0
- data/examples/deprecated/splitp.rb +56 -0
- data/examples/deprecated/testscrolllb.rb +86 -0
- data/examples/deprecated/testscrollp.rb +88 -0
- data/examples/deprecated/testscrollta.rb +80 -0
- data/examples/deprecated/testscrolltable.rb +165 -0
- data/examples/deprecated/testsplit.rb +87 -0
- data/examples/deprecated/testsplit2.rb +123 -0
- data/examples/deprecated/testsplit3.rb +215 -0
- data/examples/deprecated/testsplit3_1.rb +244 -0
- data/examples/deprecated/testsplit3a.rb +215 -0
- data/examples/deprecated/testsplit3b.rb +237 -0
- data/examples/deprecated/testsplitta.rb +148 -0
- data/examples/deprecated/testsplittv.rb +142 -0
- data/examples/deprecated/testsplittvv.rb +144 -0
- data/examples/deprecated/testtpane.rb +215 -0
- data/examples/deprecated/testtpane2.rb +145 -0
- data/examples/deprecated/testtpanetable.rb +203 -0
- data/examples/dirtree.rb +88 -0
- data/examples/experimental/resultsetdemo.rb +280 -0
- data/examples/experimental/testmform.rb +35 -0
- data/examples/experimental/testscroller.rb +117 -0
- data/examples/experimental/teststackflow.rb +111 -0
- data/examples/menu1.rb +112 -0
- data/examples/multispl.rb +86 -0
- data/examples/newmessagebox.rb +131 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +121 -0
- data/examples/qdfilechooser.rb +68 -0
- data/examples/rfe.rb +1239 -0
- data/examples/rfe_renderer.rb +121 -0
- data/examples/sqlc.rb +454 -0
- data/examples/sqlm.rb +437 -0
- data/examples/sqlt.rb +408 -0
- data/examples/status.txt +68 -0
- data/examples/table1.rb +24 -0
- data/examples/term2.rb +84 -0
- data/examples/test1.rb +239 -0
- data/examples/test2.rb +674 -0
- data/examples/testapp.rb +44 -0
- data/examples/testapp2.rb +58 -0
- data/examples/testchars.rb +137 -0
- data/examples/testcombo.rb +91 -0
- data/examples/testkeypress.rb +66 -0
- data/examples/testlistbox.rb +113 -0
- data/examples/testmenu.rb +101 -0
- data/examples/testmulticomp.rb +70 -0
- data/examples/testmulticontainer.rb +94 -0
- data/examples/testmultispl.rb +199 -0
- data/examples/testree.rb +106 -0
- data/examples/testtable.rb +264 -0
- data/examples/testtabp.rb +107 -0
- data/examples/testtodo.rb +584 -0
- data/examples/testvimsplit.rb +112 -0
- data/examples/testwsshortcuts.rb +64 -0
- data/examples/testwsshortcuts2.rb +126 -0
- data/examples/todo.db +0 -0
- data/examples/todo.yml +191 -0
- data/examples/viewtodo.rb +574 -0
- data/lib/rbcurse/deprecated/README.markdown +12 -0
- data/lib/rbcurse/deprecated/rpad.rb +375 -0
- data/lib/rbcurse/deprecated/rscrollpane.rb +512 -0
- data/lib/rbcurse/deprecated/rsplitpane.rb +894 -0
- data/lib/rbcurse/deprecated/rsplitpane2.rb +1009 -0
- data/lib/rbcurse/deprecated/rviewport.rb +204 -0
- data/lib/rbcurse/deprecated/widgets/mapper.rb +130 -0
- data/lib/rbcurse/deprecated/widgets/rmessagebox.rb +348 -0
- data/lib/rbcurse/deprecated/widgets/rtabbedpane.rb +1158 -0
- data/lib/rbcurse/deprecated/widgets/rtabbedwindow.rb +167 -0
- data/lib/rbcurse/deprecated/widgets/scrollable.rb +301 -0
- data/lib/rbcurse/deprecated/widgets/stdscrwindow.rb +309 -0
- data/lib/ver/keyboard2.rb +170 -0
- data/test/test_rbcurse.rb +0 -0
- metadata +131 -9
@@ -0,0 +1,12 @@
|
|
1
|
+
== Short Story
|
2
|
+
|
3
|
+
If you are new here, don't touch anything in this directory.
|
4
|
+
|
5
|
+
== Long Story
|
6
|
+
|
7
|
+
This directory contains stuff that was once used, but has since been rewritten in a simpler form.
|
8
|
+
Thus, I've replaced this with the simpler form. This still exists for anyone who was using it.
|
9
|
+
|
10
|
+
Some old stuff was either rather ambitiously rewritten or written awfully like MessageBox. I've got a more sensible version up now. Stuff here will *NOT* be maintained by me anylonger.
|
11
|
+
|
12
|
+
There's also stuff here that will *NOT* work any longer such as SplitPanes and ScrollPanes. Support for them has been removed from the core (Form, widget and window) since it was complicating the core too much.
|
@@ -0,0 +1,375 @@
|
|
1
|
+
require 'ver/window'
|
2
|
+
|
3
|
+
# This contains pad and subwin.
|
4
|
+
#
|
5
|
+
# 1. IMHO, subwins and derwins are not very stable. Avoid using them. I've tinkered
|
6
|
+
# with them quite a bit and given them up.
|
7
|
+
# 2. Pads are quite okay, I tried something too complex, and copywin often can give
|
8
|
+
# errors, or seg faults. So i've steered away from the Pad class. I may try a simpler
|
9
|
+
# less clever pad approach to textview sometime again.
|
10
|
+
|
11
|
+
module VER
|
12
|
+
##
|
13
|
+
# Pad
|
14
|
+
# This is EXPERIMENTAL
|
15
|
+
# A pad cannot be used interchangeable since some application functions such as wrefresh
|
16
|
+
# are illegal. Cannot expect the application to take care.
|
17
|
+
# Internally we can make it easier. Mostly a pad is used to map to one portion of the screen.
|
18
|
+
# So we allow that to be defined once. Then only start row and col of pad change.
|
19
|
+
# Maybe we should check pad coordinates so no errors
|
20
|
+
# Also check screen coordinates (if we know)
|
21
|
+
# We need padheight and padwidth only to ensure we don't keep recreating.
|
22
|
+
# Howevre, when comp's height increases, then decreases, pad height remains larger
|
23
|
+
# but we keep printing an extra row in copywin. so Pad needs to maintain comp height
|
24
|
+
# and padheight.
|
25
|
+
# @since 0.1.3
|
26
|
+
# NOTE used only by TabbedPane. If we rewrite without using it in 1.3.1 then scrap.
|
27
|
+
# 2011-11-8 Now the new simpler TabbedPane does not use pads.
|
28
|
+
# The aim o this class was to act as a replacement for window, making it seamless
|
29
|
+
# to use a pad instead
|
30
|
+
class Pad < VER::Window
|
31
|
+
# top and left correspond to screen's top and left wich will mostly be fixed
|
32
|
+
attr_accessor :top, :left
|
33
|
+
# start row and col correspond to pad's top and left which will change if scrolling
|
34
|
+
attr_accessor :pminrow, :pmincol
|
35
|
+
# screen's height and width, now it reflects components height and width
|
36
|
+
attr_accessor :sheight, :swidth
|
37
|
+
attr_reader :otherwin
|
38
|
+
# dimensions the pad was created with, used so we don't keep recreating pad, only if increase.
|
39
|
+
attr_reader :padheight, :padwidth
|
40
|
+
#attr_accessor :name # more for debugging log files. 2010-02-02 19:58
|
41
|
+
def initialize(height, width)
|
42
|
+
@visible = true
|
43
|
+
# do we set height and width ?? XXX
|
44
|
+
@window = Ncurses.newpad(height, width)
|
45
|
+
@padheight = height
|
46
|
+
@padwidth = width
|
47
|
+
@height = height
|
48
|
+
@width = width
|
49
|
+
@sheight = height
|
50
|
+
@swidth = width
|
51
|
+
init_vars
|
52
|
+
end
|
53
|
+
def init_vars
|
54
|
+
super
|
55
|
+
@top ||= 0; @left ||= 0
|
56
|
+
@pmincol ||= 0 # pad will print from this col
|
57
|
+
@pminrow ||= 0 # pad will print from this row
|
58
|
+
@window_type = :PAD
|
59
|
+
@name ||="#{self}"
|
60
|
+
$log.debug " PAD constructor #{self} , #{@window} "
|
61
|
+
end
|
62
|
+
#
|
63
|
+
# @param layout is a hash (@see Window.initialize)
|
64
|
+
def self.create_with_layout(layout)
|
65
|
+
@window = Pad.new(layout[:height], layout[:width])
|
66
|
+
@window.reset_layout(layout)
|
67
|
+
return @window
|
68
|
+
end
|
69
|
+
##
|
70
|
+
# increases the pad size, since the widget may have been resized
|
71
|
+
# checks that one of ht or width has been increased
|
72
|
+
# destroys earlier pad and returns new one
|
73
|
+
# Updates sheight and swidth even if reduced so copywin works fine.
|
74
|
+
# @param [Fixnum] height to resize to
|
75
|
+
# @param [Fixnum] width to resize to
|
76
|
+
# @return [Pad]
|
77
|
+
# 2009-10-29 23:18
|
78
|
+
def resize(ht = 0, w = 0)
|
79
|
+
# update sheight and swidth even if reduced, so that pad doesn't overwrite.
|
80
|
+
@sheight = ht if ht > 0
|
81
|
+
@swidth = w if w > 0
|
82
|
+
return if ht < @padheight and w < @padwidth
|
83
|
+
@padheight = ht if ht > @padheight
|
84
|
+
@padwidth = w if w > @padwidth
|
85
|
+
destroy
|
86
|
+
$log.debug " L502 resize, creating newpad with #{@padheight} and #{@padwidth} "
|
87
|
+
@window = Ncurses.newpad(@padheight, @padwidth)
|
88
|
+
$log.debug " L502 resize created #{@window} "
|
89
|
+
return @window
|
90
|
+
end
|
91
|
+
## used if pad and window are same size only
|
92
|
+
# creates a similar sized window
|
93
|
+
# assumes window is backed by this pad
|
94
|
+
# @param object of Window class
|
95
|
+
def self.create_for_window(win)
|
96
|
+
# get coordinates for win
|
97
|
+
@otherwin = win
|
98
|
+
smaxx = win.getmaxx()
|
99
|
+
smaxy = win.getmaxy()
|
100
|
+
top = win.getminx()
|
101
|
+
left = win.getminy()
|
102
|
+
sheight = win.height
|
103
|
+
swidth = win.width
|
104
|
+
# make pad based on size of window
|
105
|
+
window = Pad.create_with_layout(layout = { :height => sheight, :width => swidth, :top => top, :left => sleft })
|
106
|
+
window.sheight = sheight
|
107
|
+
window.swidth = swidth
|
108
|
+
return window
|
109
|
+
|
110
|
+
end
|
111
|
+
# top and left correspond to screen's top and left wich will mostly be fixed.
|
112
|
+
# In cases where the component may float around, as in Splitpanes second component
|
113
|
+
# this would be set using component's row and col.
|
114
|
+
def set_screen_row_col top, left=-1
|
115
|
+
@top = top
|
116
|
+
@left = left unless left < 0
|
117
|
+
end
|
118
|
+
alias :set_screen_pad_left :set_screen_row_col
|
119
|
+
|
120
|
+
## added user setting screens max row and col (e.g splitpanes first component)
|
121
|
+
def set_screen_max_row_col mr, mc
|
122
|
+
$log.debug "#{@name} set_screen_max_row_col #{mr},#{mc}. earlier #{@screen_maxrow}, #{@screen_maxcol} "
|
123
|
+
# added || check on 2010-01-09 18:39 since crashing if mr > sh + top ..
|
124
|
+
# I removed the check, since it results in a blank area on screen since the
|
125
|
+
# widget has not expanded itself. Without the check it will crash on copywin so you
|
126
|
+
# should increase widget size or disallow calling this in this situation.
|
127
|
+
if mr > (@sheight + @top -1 -@pminrow)
|
128
|
+
$log.warn " ->>> ** set_screen_max_row_col #{mr} > #{@sheight} + #{@top} -1 - #{@pminrow} ** "
|
129
|
+
$log.warn " ->>> can result in error in copy_win or in some rows not displaying"
|
130
|
+
return # some situations actually require this ...
|
131
|
+
end unless mr.nil?
|
132
|
+
@screen_maxrow = mr unless mr.nil? # || mr > (@sheight + @top -1 -@pminrow)
|
133
|
+
@screen_maxcol = mc unless mc.nil?
|
134
|
+
end
|
135
|
+
# start row and col correspond to pad's top and left which will change if scrolling
|
136
|
+
# However, if we use this as a backing store for subwindows it could remain the same
|
137
|
+
def set_pad_top_left top, left=-1
|
138
|
+
$log.debug "#{@name} inside set_pad_top_left to #{top} #{left} earlier #{@pminrow}, #{@pmincol}"
|
139
|
+
@pminrow = top unless top < 0
|
140
|
+
@pmincol = left unless left < 0
|
141
|
+
end
|
142
|
+
# return screen max row which will be used for writing to window
|
143
|
+
# XXX what if user sets/overrides sheight
|
144
|
+
def smaxrow
|
145
|
+
#$log.debug " ... niside smaxrow #{@sheight} + #{@top} -1 "
|
146
|
+
#@sheight + @top -1
|
147
|
+
$log.debug "smr: #{@screen_maxrow} ... niside smaxrow #{@sheight} + #{@top} -1 - #{@pminrow}"
|
148
|
+
@screen_maxrow || @sheight + @top -1 -@pminrow
|
149
|
+
end
|
150
|
+
##
|
151
|
+
# return screen max col which will be used for writing to window
|
152
|
+
def smaxcol
|
153
|
+
#$log.debug " ... niside smaxcol #{@swidth} + #{@left} -1 "
|
154
|
+
#@swidth + @left -1
|
155
|
+
# $log.debug " ... niside smaxcol #{@swidth} + #{@left} -1 - #{@pmincol} "
|
156
|
+
@screen_maxcol || @swidth + @left -1 - @pmincol
|
157
|
+
end
|
158
|
+
##
|
159
|
+
# specify the window or subwin that the pad is writing to
|
160
|
+
# 2010-02-20 22:45 - actually since there are pad methods smaxrow used on otherwin
|
161
|
+
# therefor it can only be a Pad !! NOTE
|
162
|
+
def set_backing_window win
|
163
|
+
@otherwin = win
|
164
|
+
# XX should we extract the coordinates and use for printing ??
|
165
|
+
# or for setting maxrow and maxcol
|
166
|
+
end
|
167
|
+
# trying to make things as easy as possible
|
168
|
+
# returns -1 if error in prefresh
|
169
|
+
def wrefresh
|
170
|
+
$log.debug " inside pad's wrefresh #{@window}. minr,minc,top,left,smaxr,c: #{@pminrow}, #{@pmincol}, #{@top} #{@left} #{smaxrow()} #{smaxcol()} self: #{self.name} "
|
171
|
+
|
172
|
+
# caution, prefresh uses maxrow and maxcol not height and width
|
173
|
+
# so we have to add top and less one since we are zero based
|
174
|
+
ret = @window.prefresh(@pminrow, @pmincol, @top, @left, smaxrow(), smaxcol())
|
175
|
+
$log.warn " WREFRESH returns -1 ERROR - width or height must be exceeding " if ret == -1
|
176
|
+
@modified = false
|
177
|
+
return ret
|
178
|
+
end
|
179
|
+
##
|
180
|
+
# copy the window to the pad (assumes we are writing onto win and keeping
|
181
|
+
# pad as backup
|
182
|
+
# also assuming only one win so, window not passed as param
|
183
|
+
# @return return value of copywin which should be 0 (-1 is ERR)
|
184
|
+
def copy_pad_to_win
|
185
|
+
$log.warn " DEPRECATED copy_pad_to_win" # CLEANUP
|
186
|
+
raise "DEPREC copy_pad_to_win deprecated. Will be removed. Let me know if it is needed"
|
187
|
+
# check that we don't exceed other windows height/maxrow
|
188
|
+
smr = smaxrow()
|
189
|
+
# SHIT, this means the otherwin has to be a Pad, cannot be a window
|
190
|
+
osw = @otherwin.width
|
191
|
+
osh = @otherwin.height
|
192
|
+
osh = @height if osh == 0 # root window has 0
|
193
|
+
osw = @width if osw == 0 # root window has 0
|
194
|
+
osmr = @otherwin.smaxrow() rescue osh # TRYING for windows
|
195
|
+
osmc = @otherwin.smaxcol() rescue osw
|
196
|
+
if smr >= osmr
|
197
|
+
$log.debug " adjusted smr from #{smr} to #{osmr} -1 causing issues in viewfooter"
|
198
|
+
smr = osmr-1 # XXX causing issues in viewport, wont print footer with this
|
199
|
+
end
|
200
|
+
if smr > @sheight + @top -1 -@pminrow # 2010-01-17 13:27
|
201
|
+
smr = @sheight + @top -1 -@pminrow
|
202
|
+
$log.debug " adjusted smr to #{smr} to prevent crash "
|
203
|
+
end
|
204
|
+
smc = smaxcol()
|
205
|
+
$log.debug " SMC original = #{smc} "
|
206
|
+
if smc >= osmc
|
207
|
+
smc = osmc-1
|
208
|
+
smc = @width # XXX ??? THIS WAS WORKING< but throwing error in viewport case
|
209
|
+
smc = [osmc-1, @width].min # yet another hack
|
210
|
+
$log.debug " SMC o-1 #{osmc-1} wdth #{@width}, smc #{smc} "
|
211
|
+
end
|
212
|
+
### XXX commented out since it doesn't let a comp print fully if widget expanded (splitpane)
|
213
|
+
#smc = osw -1 if smc >= osw; # added 2009-11-02 17:01 for tabbedpanes
|
214
|
+
|
215
|
+
# dang, this is coming up a lot. 2010-01-16 20:34
|
216
|
+
# the second scrollpane was one row too large in testsplit3a.rb
|
217
|
+
if smr - @top > @padheight
|
218
|
+
$log.debug " fixing smr to padheight 2010-01-16 20:35 HOPE THIS DOESNT BREAK ANYTHING"
|
219
|
+
smr = @padheight
|
220
|
+
end
|
221
|
+
@pminrow = 0 if @pminrow < 0
|
222
|
+
@pmincol = 0 if @pmincol < 0
|
223
|
+
$log.debug " COPYING #{self.name} to #{@otherwin.name} "
|
224
|
+
$log.debug " calling copy pad #{@pminrow} #{@pmincol}, #{@top} #{@left}, #{smr} #{smc} self #{self.name} "
|
225
|
+
$log.debug " calling copy pad H: #{@height} W: #{@width}, PH #{@padheight} PW #{@padwidth} WIN:#{@window} "
|
226
|
+
# $log.debug " -otherwin target copy pad #{@otherwin.pminrow} #{@otherwin.pmincol}, #{@otherwin.top} #{@otherwin.left}, #{osmr} #{osmc} OTHERWIN:#{@otherwin.name} "
|
227
|
+
ret="-"
|
228
|
+
#if ret == -1
|
229
|
+
#x XXX $log.debug " #{ret} otherwin copy pad #{@otherwin.pminrow} #{@otherwin.pmincol}, #{@otherwin.top} #{@otherwin.left}, #{osmr} #{osmc} "
|
230
|
+
$log.debug " #{ret} otherwin copy pad H: #{osh} W: #{osw}"
|
231
|
+
if @top >= osh
|
232
|
+
$log.debug " #{ret} ERROR top exceeds other ht #{@top} H: #{osh} "
|
233
|
+
end
|
234
|
+
if @left >= osw
|
235
|
+
$log.debug " #{ret} ERROR left exceeds other wt #{@left} W: #{osw} "
|
236
|
+
end
|
237
|
+
if smr >= osh
|
238
|
+
$log.debug " #{ret} ERROR smrow exceeds other ht #{smr} H: #{osh} "
|
239
|
+
smr = osh() -1 # testing 2010-01-31 21:47 , again 2010-02-05 20:22
|
240
|
+
end
|
241
|
+
if smc >= osw
|
242
|
+
$log.debug " #{ret} ERROR smcol exceeds other wt #{smc} W: #{osw} "
|
243
|
+
end
|
244
|
+
if smc - @left > @padwidth
|
245
|
+
$log.debug " #{ret} ERROR smcol - left exceeds padwidth #{smc}- #{@left} PW: #{@padwidth} "
|
246
|
+
end
|
247
|
+
if smr - @top > @padheight
|
248
|
+
$log.debug " #{ret} ERROR smr - top exceeds padheight #{smr}- #{@top} PH: #{@padheight} "
|
249
|
+
end
|
250
|
+
ret = @window.copywin(@otherwin.get_window,@pminrow,@pmincol, @top, @left, smr, smc, 0)
|
251
|
+
$log.debug " copywin ret #{ret} "
|
252
|
+
# 2010-01-11 19:42 one more cause of -1 coming is that padheight (actual height which never
|
253
|
+
# changes unless pad increases) or padwidth is smaller than area being printed. Solution: increase
|
254
|
+
# buffer by increasing widgets w or h. smc - left should not exceed padwidth. smr-top should not
|
255
|
+
# exceed padheight
|
256
|
+
#end
|
257
|
+
@modified = false
|
258
|
+
return ret
|
259
|
+
end
|
260
|
+
# @deprecated
|
261
|
+
def copy_win_to_pad
|
262
|
+
$log.warn " DEPRECATED copy_win_to_pad" # CLEANUP 2011-09-29
|
263
|
+
raise "DEPREC copy_win_to_pad deprecated. Will be removed. Let me know if it is needed"
|
264
|
+
smr = smaxrow()
|
265
|
+
if smr >= @window.smaxrow()
|
266
|
+
smr = @window.smaxrow()-1
|
267
|
+
end
|
268
|
+
$log.debug " copy_win_to_pad #{@otherwin.name}, #{@window.name}, pminr:#{@pminrow} pminc:#{@pmincol} top:#{@top} left:#{@left} smr:#{smr} "
|
269
|
+
ret = @otherwin.copywin(@window.get_window,@pminrow,@pmincol, @top, @left, smr, smaxcol(), 1)
|
270
|
+
@modified = false
|
271
|
+
return ret
|
272
|
+
end
|
273
|
+
##
|
274
|
+
#Used to overwrite the pad onto the screen window
|
275
|
+
# A window should have been specified as window to back (@see set_backing_window) or (@see create_with_window)
|
276
|
+
def overwrite_window
|
277
|
+
return @window.overwrite(@otherwin.get_window)
|
278
|
+
end
|
279
|
+
|
280
|
+
##
|
281
|
+
# convenience method so that pad can use printstring but remove screen's row and col
|
282
|
+
# The absolute row and col will be taken into consideration when printing on screen.
|
283
|
+
#
|
284
|
+
# @param [Fixnum] row row to print on
|
285
|
+
# @param [Fixnum] col column to print on
|
286
|
+
# @param [String] value to print
|
287
|
+
# @param [Fixnum] color - color combination
|
288
|
+
# @param [Fixnum, nil] attrib defaults to NORMAL
|
289
|
+
|
290
|
+
# Pls remove the raise once the program is working, extra line can slow things down
|
291
|
+
# Keep it on when testing.
|
292
|
+
# If the raise is thrown, it means your object could be positioned higher than it should be,
|
293
|
+
# or at some point you have increased top, without increasing the objects row.
|
294
|
+
def printstring(row,col,value,color,attrib=Ncurses::A_NORMAL)
|
295
|
+
#$log.debug " pad printstring #{row} - #{@top} , #{col} - #{@left} "
|
296
|
+
raise "printstring row < top, pls correct code #{row} #{@top}, #{col} #{@left} " if row < @top or col < @left
|
297
|
+
#$log.warn "printstring row < top, pls correct code #{row} #{@top} " if row < @top
|
298
|
+
super(row - @top, col - @left, value, color, attrib)
|
299
|
+
end # printstring
|
300
|
+
# convenience method so that pad can use print_border but remove screen's row and col
|
301
|
+
# Please note that this requires that buffer have latest top and left.
|
302
|
+
def print_border row, col, height, width, color, att=Ncurses::A_NORMAL
|
303
|
+
$log.debug " pad printborder #{row} - #{@top} , #{col} - #{@left}, #{height} , #{width} "
|
304
|
+
raise "print_border: row < top, pls correct code #{row} #{@top}, #{col} #{@left} " if row < @top or col < @left
|
305
|
+
#$log.warn "print_border: row < top, pls correct code #{row} #{@top} " if row < @top
|
306
|
+
super(row - @top, col - @left, height, width, color, att)
|
307
|
+
end
|
308
|
+
def print_border_only row, col, height, width, color, att=Ncurses::A_NORMAL
|
309
|
+
$log.debug " pad printborder_only #{row} - #{@top} , #{col} - #{@left}, #{height} , #{width} "
|
310
|
+
raise "print_border row < top, pls correct code #{row} #{@top}, #{col} #{@left} " if row < @top or col < @left
|
311
|
+
super(row - @top, col - @left, height, width, color, att)
|
312
|
+
end
|
313
|
+
# use in place of mvwhline if your widget could be using a pad or window
|
314
|
+
def rb_mvwhline row, col, char, width
|
315
|
+
super(row-@top, col-@left, char, width)
|
316
|
+
end
|
317
|
+
# use in place of mvwvline if your widget could be using a pad or window
|
318
|
+
def rb_mvwvline row, col, char, width
|
319
|
+
super(row-@top, col-@left, char, width)
|
320
|
+
end
|
321
|
+
# use in place of mvaddch if your widget could be using a pad or window
|
322
|
+
def rb_mvaddch row, col, char
|
323
|
+
super(row-@top, col-@left, char)
|
324
|
+
end
|
325
|
+
end # class Pad
|
326
|
+
#-------------------------------- deprecated stuff ------------------ #
|
327
|
+
##
|
328
|
+
# added RK 2009-10-08 23:57 for tabbedpanes
|
329
|
+
# THIS IS EXPERIMENTAL -
|
330
|
+
# I have not called super in the initializer so any methods you try on subwin
|
331
|
+
# that exist in the superclass which use @window will bomb
|
332
|
+
# @since 0.1.3 REMOVE UNUSED.
|
333
|
+
# @deprecated
|
334
|
+
class SubWindow < VER::Window
|
335
|
+
attr_reader :width, :height, :top, :left
|
336
|
+
attr_accessor :layout
|
337
|
+
attr_reader :panel # XXX reader requires so he can del it in end
|
338
|
+
attr_reader :subwin #
|
339
|
+
attr_reader :parent #
|
340
|
+
|
341
|
+
def initialize(parent, layout)
|
342
|
+
@visible = true
|
343
|
+
reset_layout(layout)
|
344
|
+
|
345
|
+
@parent = parent
|
346
|
+
#@subwin = @parent.get_window().derwin(@height, @width, @top, @left)
|
347
|
+
@subwin = @parent.get_window().subwin(@height, @width, @top, @left)
|
348
|
+
$log.debug "SUBWIN init #{@height} #{@width} #{@top} #{@left} "
|
349
|
+
#$log.debug "SUBWIN init #{@subwin.getbegx} #{@subwin.getbegy} #{@top} #{@left} "
|
350
|
+
@panel = Ncurses::Panel.new_panel(@subwin)
|
351
|
+
|
352
|
+
@window = @subwin # makes more mthods available
|
353
|
+
init_vars
|
354
|
+
|
355
|
+
end
|
356
|
+
# no need really now
|
357
|
+
def reset_layout layout
|
358
|
+
@layout = layout # 2010-02-13 22:23
|
359
|
+
@height = layout[:height]
|
360
|
+
@width = layout[:width]
|
361
|
+
@top = layout[:top]
|
362
|
+
@left = layout[:left]
|
363
|
+
end
|
364
|
+
def _destroy
|
365
|
+
# typically the ensure block should have this
|
366
|
+
# or should window do it for all subwins, or would we want to wait that long ?
|
367
|
+
$log.debug "subwin destroy"
|
368
|
+
|
369
|
+
Ncurses::Panel.del_panel(panel.pointer) if !panel.nil? # FFI
|
370
|
+
#@window.delwin(@window) if !@window.nil? # added FFI 2011-09-7
|
371
|
+
delwin if !@window.nil? # added FFI 2011-09-7
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
end
|
@@ -0,0 +1,512 @@
|
|
1
|
+
=begin
|
2
|
+
* Name: Scrollpane
|
3
|
+
* Description: a scrollable widget allowing user to scroll and view
|
4
|
+
parts of underlying object that typically are larger than screen area.
|
5
|
+
Mainly, contains a viewport, scrollbars and manages viewport through usage
|
6
|
+
of scrollbars.
|
7
|
+
Also contains viewport for row and columns.
|
8
|
+
* Author: rkumar
|
9
|
+
Todo section:
|
10
|
+
- add events, property changed etc at least for scrolling - DONE
|
11
|
+
SCrollpane normall should listen in to changes in viewport, however Scro calls those very methods
|
12
|
+
and what's more, other classes would listen to SCR and not to VP.
|
13
|
+
- scrollbars to be classes - shall we avoid over-engineering, and KISS
|
14
|
+
- if scrollpane reduced it should also resize, as example inside splitpane.
|
15
|
+
* file created 2009-10-27 19:20
|
16
|
+
* Added a call to child's set_form_col from set_form_row
|
17
|
+
Major changes 2010-02-11 19:51 to simplify version RFED16
|
18
|
+
* Still need to clean up this and viewport. make as light as possible
|
19
|
+
* If scrolling, no repainting should happen. Scrollpane could get the buffer
|
20
|
+
and scroll itself. Or ensure that inner object does not rework...
|
21
|
+
|
22
|
+
Pass handle_key to child, also repaint refer child.
|
23
|
+
Avoid passing to viewport as this would slow down alot.
|
24
|
+
|
25
|
+
NOTE: if a caller is interested in knowing what scrolling has happened, pls bind to :STATE_CHANGE, you will receive the viewport object. If you find this cumbersome, and wish to know only about scrolling, we can put in a scrolling event and inform of row or col scrolling. Or we can fire a property change with row or col increment.
|
26
|
+
|
27
|
+
|
28
|
+
--------
|
29
|
+
* License:
|
30
|
+
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
31
|
+
|
32
|
+
=end
|
33
|
+
#require 'rubygems'
|
34
|
+
#require 'ncurses'
|
35
|
+
require 'logger'
|
36
|
+
require 'rbcurse'
|
37
|
+
require 'rbcurse/rviewport'
|
38
|
+
|
39
|
+
#include Ncurses # FFI 2011-09-8
|
40
|
+
include RubyCurses
|
41
|
+
module RubyCurses
|
42
|
+
extend self
|
43
|
+
|
44
|
+
##
|
45
|
+
# A scrollable box throgh which one can see portions of underlying object
|
46
|
+
# such as textarea, table or a form, usually the underlying data is larger
|
47
|
+
# than what can be displayed.
|
48
|
+
|
49
|
+
class ScrollPane < Widget
|
50
|
+
# viewport
|
51
|
+
# row_viewport
|
52
|
+
# column_viewport
|
53
|
+
# horizontal scrollbar 0-NONE, 1=ALWAYS, 2=AS_NEEDED
|
54
|
+
# vertical scrollbar 0-NONE, 1=ALWAYS, 2=AS_NEEDED
|
55
|
+
attr_accessor :cascade_changes # should changes in size go down to child, default false
|
56
|
+
|
57
|
+
def initialize form, config={}, &block
|
58
|
+
@focusable = true
|
59
|
+
@editable = false
|
60
|
+
#@left_margin = 1
|
61
|
+
@row = 0
|
62
|
+
@col = 0
|
63
|
+
super
|
64
|
+
@row_offset = @col_offset = 1
|
65
|
+
init_vars
|
66
|
+
@_events.push :STATE_CHANGE
|
67
|
+
# $log.debug " SCROLLPANE recvs form #{form.name}, #{form.window.name} " unless form.nil?
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
##
|
72
|
+
# set child component being used in viewport
|
73
|
+
# @see set_viewport_view
|
74
|
+
def child ch
|
75
|
+
if ch != nil
|
76
|
+
@child = ch # added 2010-02-11 15:28 we might do away with viewport, setting panned to child
|
77
|
+
@child.rows_panned = @child.cols_panned = 0
|
78
|
+
|
79
|
+
ch.parent_component = self # added 2010-01-13 12:55 so offsets can go down ?
|
80
|
+
|
81
|
+
@child.should_create_buffer = true
|
82
|
+
@form.add_rows += 2 # related to scr_top XXX What if form not set. i cannot keep accumulating
|
83
|
+
update_child
|
84
|
+
# -3 since we start row +1 to get indented by 1, also we use
|
85
|
+
# height -1 in scrollpane, so we need -2 to indent, and one more
|
86
|
+
# for row
|
87
|
+
set_viewport_view(ch)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
##
|
91
|
+
# update of child's coordinates, needs to be called whenever it
|
92
|
+
# changes, so i need to call it before calling child's update
|
93
|
+
# FIXME - this is become 2 calls, make it one - becoming expensive
|
94
|
+
# if called often
|
95
|
+
def update_child
|
96
|
+
scr_top = 3 # for Pad, if Pad passed as in SplitPane
|
97
|
+
scr_left = 1 # for Pad, if Pad passed as in SplitPane
|
98
|
+
if @form.window.window_type == :WINDOW
|
99
|
+
scr_top = @row + 1
|
100
|
+
scr_left = @col + 1
|
101
|
+
@child.row(@row+@row_offset)
|
102
|
+
@child.col(@col+@col_offset)
|
103
|
+
else
|
104
|
+
# PAD case
|
105
|
+
@child.row(scr_top)
|
106
|
+
@child.col(scr_left)
|
107
|
+
end
|
108
|
+
@child.set_buffering(:target_window => @target_window || @form.window, :form => @form, :bottom => @height-3, :right => @width-3 )
|
109
|
+
@child.set_buffering(:screen_top => scr_top, :screen_left => scr_left)
|
110
|
+
# lets set the childs ext offsets
|
111
|
+
$log.debug "SCRP #{name} adding (to #{@child.name}) ext_row_off: #{@child.ext_row_offset} += #{@ext_row_offset} +#{@row_offset} "
|
112
|
+
$log.debug "SCRP adding ext_col_off: #{@child.ext_col_offset} += #{@ext_col_offset} +#{@col_offset} "
|
113
|
+
## 2010-02-09 18:58 i think we should not put col_offset since the col
|
114
|
+
## of child would take care of that. same for row_offset. XXX
|
115
|
+
@child.ext_col_offset += @ext_col_offset + @col + @col_offset - @screen_left # 2010-02-09 19:14
|
116
|
+
# added row and col setting to child RFED16 2010-02-17 00:22 as
|
117
|
+
# in splitpane. seems we are not using ext_offsets now ? texta
|
118
|
+
# and TV are not. and i've commented off from widget
|
119
|
+
|
120
|
+
$log.debug " #{@child.ext_row_offset} += #{@ext_row_offset} + #{@row} -#{@screen_top} "
|
121
|
+
@child.ext_row_offset += @ext_row_offset + @row + @row_offset - @screen_top
|
122
|
+
# adding this since child's ht should not be less. or we have a
|
123
|
+
# copywin failure
|
124
|
+
@child.height ||= @height
|
125
|
+
@child.width ||= @width
|
126
|
+
if @child.height < @height
|
127
|
+
@child.height = @height
|
128
|
+
end
|
129
|
+
if @child.width < @width
|
130
|
+
@child.width = @width
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
def init_vars
|
135
|
+
#@curpos = @pcol = @toprow = @current_index = 0
|
136
|
+
@hsb_policy = :AS_NEEDED
|
137
|
+
@vsb_policy = :AS_NEEDED
|
138
|
+
@repaint_required = true
|
139
|
+
@repaint_border = true
|
140
|
+
@row_outofbounds=0
|
141
|
+
@col_outofbounds=0
|
142
|
+
@border_width = 2
|
143
|
+
@screen_top = 0
|
144
|
+
@screen_left = 0
|
145
|
+
end
|
146
|
+
# set the component to be viewed
|
147
|
+
def set_viewport_view ch
|
148
|
+
@viewport = Viewport.new nil
|
149
|
+
@viewport.set_view ch
|
150
|
+
## this -2 should depend on whether we are putting border/scrollbars or not.
|
151
|
+
# -1 added on 2010-02-16 23:35 since we are red 1, and bw
|
152
|
+
@viewport.set_view_size(@height-@border_width-0, @width-@border_width-0) # XXX make it one less
|
153
|
+
@viewport.cascade_changes = @cascade_changes # added 2010-02-04 18:19
|
154
|
+
@viewport.bind(:STATE_CHANGE) { |e| view_state_changed(e) }
|
155
|
+
@viewport.bind(:PROPERTY_CHANGE) { |e| view_property_changed(e) }
|
156
|
+
end
|
157
|
+
# return underlying viewport
|
158
|
+
# in order to run some of its methods
|
159
|
+
def get_viewport
|
160
|
+
return @viewport
|
161
|
+
end
|
162
|
+
# Directly set the viewport.
|
163
|
+
# Usually it is best to use set_viewport_view instead
|
164
|
+
def set_viewport vp
|
165
|
+
old = @viewport
|
166
|
+
@viewport = vp
|
167
|
+
fire_property_change "viewport", old, @viewport
|
168
|
+
end
|
169
|
+
# sets the component to be used as a rowheader TODO
|
170
|
+
def set_rowheader_view ch
|
171
|
+
old = @rowheader
|
172
|
+
@rowheader = Viewport.new
|
173
|
+
@rowheader.set_view ch
|
174
|
+
fire_property_change "row_header", old, @rowheader
|
175
|
+
end
|
176
|
+
# sets the component to be used as a column header TODO
|
177
|
+
def set_columnheader_view ch
|
178
|
+
old = @columnheader
|
179
|
+
@columnheader = Viewport.new
|
180
|
+
@columnheader.set_view ch
|
181
|
+
fire_property_change "column_header", old, @columnheader
|
182
|
+
end
|
183
|
+
def set_view_size h,w
|
184
|
+
# calling the property shoudl uniformally trigger fire_property_change
|
185
|
+
@viewport.set_view_size h,w
|
186
|
+
#height(h)
|
187
|
+
#width(w)
|
188
|
+
#fire_handler :PROPERTY_CHANGE, self # XXX should it be an event STATE_CHANGED with details
|
189
|
+
end
|
190
|
+
## seems i wrote this only so i could set repaint_required to true
|
191
|
+
# However, now that VP calls state changed, that will happen XXX
|
192
|
+
def set_view_position r,c
|
193
|
+
ret = @viewport.set_view_position r,c
|
194
|
+
if ret
|
195
|
+
@repaint_required = true if ret
|
196
|
+
# fire_property_change("view_position",
|
197
|
+
end
|
198
|
+
return ret
|
199
|
+
end
|
200
|
+
# this method is registered with Viewport for changes
|
201
|
+
def view_state_changed ev
|
202
|
+
fire_handler :STATE_CHANGE, ev #???
|
203
|
+
@repaint_required = true
|
204
|
+
end
|
205
|
+
# this method is registered with Viewport for changes to properties
|
206
|
+
def view_property_changed ev
|
207
|
+
fire_handler :PROPERTY_CHANGE, ev #???
|
208
|
+
@repaint_required = true
|
209
|
+
end
|
210
|
+
# @return [true, false] false if r,c not changed
|
211
|
+
def increment_view_row num
|
212
|
+
#x r = @viewport.row() #- @viewport.top_margin
|
213
|
+
#x c = @viewport.col() #- @viewport.left_margin
|
214
|
+
r, c = @viewport.get_pad_top_left()
|
215
|
+
$log.debug " SCR inc viewport currently : r #{r} c #{c} "
|
216
|
+
r += num
|
217
|
+
ret = set_view_position r, c
|
218
|
+
v_scroll_bar if ret
|
219
|
+
return ret
|
220
|
+
end
|
221
|
+
# @return [true, false] false if r,c not changed
|
222
|
+
def increment_view_col num
|
223
|
+
r, c = @viewport.get_pad_top_left()
|
224
|
+
#r = @viewport.row() #- @viewport.top_margin
|
225
|
+
#c = @viewport.col() #- @viewport.left_margin
|
226
|
+
c += num
|
227
|
+
ret = set_view_position r, c
|
228
|
+
h_scroll_bar if ret
|
229
|
+
return ret
|
230
|
+
end
|
231
|
+
def repaint # scrollpane
|
232
|
+
# viewports child should repaint onto pad
|
233
|
+
# viewport then clips
|
234
|
+
# this calls viewports refresh from its refresh
|
235
|
+
return unless @repaint_required
|
236
|
+
if @viewport
|
237
|
+
update_child
|
238
|
+
$log.debug "SCRP #{@name} calling viewport repaint"
|
239
|
+
#@viewport.repaint_all true # 2010-01-16 23:09
|
240
|
+
@viewport.repaint_required true # changed 2010-01-19 19:34
|
241
|
+
@viewport.repaint # child's repaint should do it on its pad
|
242
|
+
$log.debug " #{@name} SCRP scrollpane repaint #{@graphic.name} "
|
243
|
+
end
|
244
|
+
# TODO this only if major change
|
245
|
+
if @repaint_border && @repaint_all # added 2010-01-16 20:15
|
246
|
+
#@graphic.wclear
|
247
|
+
$log.debug " #{@name} repaint all scroll: r #{@row} c #{@col} h #{@height}-1 w #{@width} "
|
248
|
+
bordercolor = @border_color || $datacolor
|
249
|
+
borderatt = @border_attrib || Ncurses::A_NORMAL
|
250
|
+
# NOTE - should be width-1 print_b reduces one from width, but
|
251
|
+
# not height !
|
252
|
+
|
253
|
+
@graphic.print_border_only(@row, @col, @height-1, @width, bordercolor, borderatt)
|
254
|
+
h_scroll_bar
|
255
|
+
v_scroll_bar
|
256
|
+
#x XXX @viewport.repaint_all(true) unless @viewport.nil? # brought here 2010-01-19 19:34
|
257
|
+
#@repaint_border = false # commented off on 2010-01-16 20:15 so repaint_all can have effect
|
258
|
+
end
|
259
|
+
return if @viewport == nil
|
260
|
+
$log.debug "SCRP #{@name} calling viewport to SCRP b2s #{@graphic.name} "
|
261
|
+
paint
|
262
|
+
end
|
263
|
+
def getvalue
|
264
|
+
# TODO
|
265
|
+
end
|
266
|
+
## handle keys for scrollpane.
|
267
|
+
# First hands key to child object
|
268
|
+
# If unused, checks to see if it has anything mapped.
|
269
|
+
# If not consumed, returns :UNHANDLED, else 0.
|
270
|
+
def handle_key ch
|
271
|
+
# if this gets key it should just hand it to child
|
272
|
+
return :UNHANDLED if @viewport.nil? # added 2010-02-02 12:44
|
273
|
+
if @viewport != nil
|
274
|
+
$log.debug " calling child handle_key #{ch} "
|
275
|
+
ret = @viewport.handle_key ch
|
276
|
+
# XXX ret returns 0under normal circumstance, so will next line work ?
|
277
|
+
# what i mean is if ret == 0
|
278
|
+
|
279
|
+
@repaint_required = true if ret == 0 # added 2009-12-27 22:21 BUFFERED
|
280
|
+
$log.debug " ... child ret #{ret}"
|
281
|
+
|
282
|
+
|
283
|
+
## Here's the only option scrollpane has of checking whether the child has
|
284
|
+
##+ exceeded boundary BUFFERED 2009-12-29 23:12
|
285
|
+
# TEMPORARILY COMMENTED WHILE TESTING SCROLL UP AND DOWN XXX
|
286
|
+
#fr = @form.row
|
287
|
+
#fc = @form.col
|
288
|
+
#if fr >= @row + @height -2
|
289
|
+
#@form.setrowcol @row + @height -2, fc
|
290
|
+
#elsif fr < @row
|
291
|
+
#@form.setrowcol @row, fc
|
292
|
+
#end
|
293
|
+
#if fc >= @col + @width -1
|
294
|
+
#@form.setrowcol fr, @col + @width -1
|
295
|
+
#end
|
296
|
+
##
|
297
|
+
|
298
|
+
return ret if ret != :UNHANDLED
|
299
|
+
end
|
300
|
+
ret = 0 # default return value
|
301
|
+
ks = keycode_tos(ch)
|
302
|
+
$log.debug " scrollpane gets KEY #{ch}, ks #{ks} "
|
303
|
+
case ch
|
304
|
+
when ?\M-n.getbyte(0)
|
305
|
+
## scroll down one row (unless multiplier set)
|
306
|
+
ret = down
|
307
|
+
when ?\M-p.getbyte(0)
|
308
|
+
## scroll up one row (unless multiplier set)
|
309
|
+
ret = up
|
310
|
+
#when ?0.getbyte(0), ?\C-[.getbyte(0)
|
311
|
+
#goto_start #start of buffer # cursor_start
|
312
|
+
#when ?\C-].getbyte(0)
|
313
|
+
#goto_end # end / bottom cursor_end # TODO
|
314
|
+
when ?\M-\<.getbyte(0)
|
315
|
+
@height.times { up ; }
|
316
|
+
when ?\M-\>.getbyte(0)
|
317
|
+
@height.times { down ; }
|
318
|
+
when KEY_DOWN
|
319
|
+
ret = down
|
320
|
+
#check_curpos
|
321
|
+
when ?\M-h.getbyte(0)
|
322
|
+
## scroll left one position
|
323
|
+
repeatm {
|
324
|
+
ret = cursor_backward
|
325
|
+
@child.cols_panned = @child.cols_panned+1 if ret
|
326
|
+
@form.setrowcol @form.row, @form.col+1+@col_outofbounds if ret
|
327
|
+
}
|
328
|
+
when ?\M-l.getbyte(0)
|
329
|
+
## scroll right one position
|
330
|
+
repeatm {
|
331
|
+
ret = cursor_forward
|
332
|
+
@child.cols_panned = @child.cols_panned-1 if ret
|
333
|
+
@form.setrowcol @form.row, @form.col-1+@col_outofbounds if ret
|
334
|
+
}
|
335
|
+
when KEY_BACKSPACE, KEY_BSPACE
|
336
|
+
ret = cursor_backward
|
337
|
+
#when ?\C-u.getbyte(0)
|
338
|
+
## multiplier. Series is 4 16 64
|
339
|
+
#@multiplier = (@multiplier == 0 ? 4 : @multiplier *= 4)
|
340
|
+
#return 0
|
341
|
+
when ?\C-c.getbyte(0)
|
342
|
+
$multiplier = 0
|
343
|
+
return 0
|
344
|
+
else
|
345
|
+
return :UNHANDLED
|
346
|
+
end
|
347
|
+
ret = :UNHANDLED if !ret
|
348
|
+
$multiplier = 0
|
349
|
+
return ret # 0 2010-02-04 18:47 returning ret else repaint is happening when UNHANDLED
|
350
|
+
end
|
351
|
+
# private
|
352
|
+
def _down
|
353
|
+
increment_view_row(1)
|
354
|
+
end
|
355
|
+
# private
|
356
|
+
def _up
|
357
|
+
increment_view_row(-1)
|
358
|
+
end
|
359
|
+
def cursor_forward
|
360
|
+
increment_view_col(1)
|
361
|
+
end
|
362
|
+
def cursor_backward
|
363
|
+
increment_view_col(-1)
|
364
|
+
end
|
365
|
+
def down
|
366
|
+
## scroll down one row (currently one only)
|
367
|
+
$log.debug " MULT DOWN #{$multiplier} "
|
368
|
+
repeatm {
|
369
|
+
ret = _down
|
370
|
+
return unless ret # 2010-02-04 18:29
|
371
|
+
## we've scrolled down, but we need to keep the cursor where
|
372
|
+
##+ editing actually is. Isn't this too specific to textarea ?
|
373
|
+
$log.debug " SCRP setting row to #{@form.row-1} upon scrolling down "
|
374
|
+
## only move up the cursor if its within bounds
|
375
|
+
# if @form.row > @row
|
376
|
+
@child.rows_panned = @child.rows_panned-1 if ret
|
377
|
+
@form.setrowcol @form.row-1+@row_outofbounds, @form.col if ret
|
378
|
+
}
|
379
|
+
end
|
380
|
+
def up
|
381
|
+
## scroll up one row (currently one only)
|
382
|
+
repeatm {
|
383
|
+
ret = _up
|
384
|
+
return unless ret # 2010-02-04 18:29
|
385
|
+
$log.debug " SCRP setting row to #{@form.row+1} upon scrolling up R:#{@row} H:#{@height} "
|
386
|
+
# if @form.row < @row + @height
|
387
|
+
@child.rows_panned = @child.rows_panned+1 if ret
|
388
|
+
@form.setrowcol @form.row+1+@row_outofbounds, @form.col if ret
|
389
|
+
}
|
390
|
+
end
|
391
|
+
def on_enter
|
392
|
+
#super 2010-01-02 18:53 leading to a stack overflow XXX ???
|
393
|
+
set_form_row
|
394
|
+
end
|
395
|
+
# this is called once externally, on on_enter
|
396
|
+
#+ after that its called internally only, which in this case is never
|
397
|
+
def set_form_row
|
398
|
+
#@form.row = @row + 1 unless @form.nil?
|
399
|
+
if @viewport != nil
|
400
|
+
#$log.debug " calling scrollpane set_form_row"
|
401
|
+
ret = @viewport.child.set_form_row # added 2009-12-27 23:23 BUFFERED
|
402
|
+
ret = @viewport.child.set_form_col # added 2010-01-16 21:09
|
403
|
+
end
|
404
|
+
$log.debug " FORM SCRP #{@form.name} "
|
405
|
+
$log.debug "SCRP set_form_row #{@form.row} #{@form.col} "
|
406
|
+
end
|
407
|
+
## added 2010-02-09 10:17
|
408
|
+
# Sometimes some parent objects may just call this.
|
409
|
+
# Would be better if they only called row and row called both ??? or is that less reliable
|
410
|
+
# In any case we have to combine this someday!!
|
411
|
+
def set_form_col
|
412
|
+
#@form.row = @row + 1 unless @form.nil?
|
413
|
+
if @viewport != nil
|
414
|
+
#$log.debug " calling scrollpane set_form_row"
|
415
|
+
ret = @viewport.child.set_form_col # added 2010-01-16 21:09
|
416
|
+
end
|
417
|
+
$log.debug " FORM SCRP #{@form.name} "
|
418
|
+
$log.debug "SCRP set_form_col #{@form.row} #{@form.col} "
|
419
|
+
end
|
420
|
+
|
421
|
+
## this is called once only, on select_field by form.
|
422
|
+
##+ after that not at all.
|
423
|
+
def rowcol
|
424
|
+
r1 = @row #+@row_offset
|
425
|
+
c1 = @col #+@col_offset
|
426
|
+
return r1, c1 if @viewport.nil? # added 2010-02-02 12:41
|
427
|
+
|
428
|
+
r,c = @viewport.child.rowcol # added 2009-12-28 15:23 BUFFERED
|
429
|
+
$log.debug "SCRP rowcol: #{r1} + #{r} , #{c1} + #{c} "
|
430
|
+
return r1+r, c1+c
|
431
|
+
end
|
432
|
+
|
433
|
+
def paint
|
434
|
+
@repaint_required = false
|
435
|
+
@repaint_all = false
|
436
|
+
end
|
437
|
+
def h_scroll_bar
|
438
|
+
return if @viewport.nil?
|
439
|
+
sz = (@viewport.width*1.00/@viewport.child().width)*@viewport.width
|
440
|
+
#$log.debug " h_scroll_bar sz #{sz}, #{@viewport.width} #{@viewport.child().width}"
|
441
|
+
sz = sz.ceil
|
442
|
+
return if sz < 1
|
443
|
+
start = 1
|
444
|
+
start = ((@viewport.col*1.00+@viewport.width)/@viewport.child().width)*@viewport.width
|
445
|
+
start -= sz
|
446
|
+
start = start.ceil
|
447
|
+
# # the problem with next 2 lines is that attributes of border could be overwritten
|
448
|
+
# draw horiz line
|
449
|
+
r = @row #+ @ext_row_offset # 2010-02-11 11:57 RFED16
|
450
|
+
c = @col #+ @ext_col_offset # 2010-02-11 11:57 RFED16
|
451
|
+
$log.debug " h_scroll_bar start #{start}, r #{r} c #{c} h:#{@height} "
|
452
|
+
@graphic.rb_mvwhline(r+@height-1, c+1, FFI::NCurses::ACS_HLINE, @width-2)
|
453
|
+
# draw scroll bar
|
454
|
+
#sz.times{ |i| @graphic.mvaddch(r+@height-1, c+start+1+i, FFI::NCurses::ACS_CKBOARD) }
|
455
|
+
sz.times{ |i| @graphic.rb_mvaddch(r+@height-1, c+start+1+i, FFI::NCurses::ACS_CKBOARD) }
|
456
|
+
end
|
457
|
+
def v_scroll_bar
|
458
|
+
return if @viewport.nil?
|
459
|
+
sz = (@viewport.height*1.00/@viewport.child().height)*@viewport.height
|
460
|
+
#$log.debug " v_scroll_bar sz #{sz}, #{@viewport.width} #{@viewport.child().width}"
|
461
|
+
sz = sz.ceil
|
462
|
+
return if sz < 1
|
463
|
+
start = 1
|
464
|
+
start = ((@viewport.row*1.00+@viewport.height)/@viewport.child().height)*@viewport.height
|
465
|
+
start -= sz
|
466
|
+
r = @row #+ @ext_row_offset # 2010-02-11 11:57 RFED16
|
467
|
+
c = @col #+ @ext_col_offset # 2010-02-11 11:57 RFED16
|
468
|
+
$log.debug " v_scroll_bar start #{start}, col:#{@col} w:#{@width}, r #{r}+1 c #{c}+w-1 "
|
469
|
+
start = start.ceil
|
470
|
+
# # the problem with next 2 lines is that attributes of border could be overwritten
|
471
|
+
# draw verti line
|
472
|
+
# this is needed to erase previous bar when shrinking
|
473
|
+
#@graphic.mvwvline(r+1,c+@width-1, FFI::NCurses::ACS_VLINE, @height-2)
|
474
|
+
@graphic.rb_mvwvline(r+1,c+@width-1, FFI::NCurses::ACS_VLINE, @height-2)
|
475
|
+
# draw scroll bar
|
476
|
+
#sz.times{ |i| @graphic.mvaddch(r+start+1+i, c+@width-1, FFI::NCurses::ACS_CKBOARD) }
|
477
|
+
sz.times{ |i| @graphic.rb_mvaddch(r+start+1+i, c+@width-1, FFI::NCurses::ACS_CKBOARD) }
|
478
|
+
end
|
479
|
+
# set height
|
480
|
+
# a container must pass down changes in size to it's children
|
481
|
+
# 2010-02-04 18:06 - i am not sure about this. When viewport is set then it passes down
|
482
|
+
# changes to child which user did not intend. Maybe in splitpane it is okay but other cases?
|
483
|
+
# Perhaps its okay if scrollpane gets larger than child, not otherwise.
|
484
|
+
# added 2010-01-16 23:55
|
485
|
+
def height(*val)
|
486
|
+
return @height if val.empty?
|
487
|
+
oldvalue = @height || 0
|
488
|
+
super
|
489
|
+
@height = val[0]
|
490
|
+
return if @viewport == nil
|
491
|
+
delta = @height - oldvalue
|
492
|
+
return if delta == 0
|
493
|
+
@repaint_required = true
|
494
|
+
@viewport.height += delta
|
495
|
+
end
|
496
|
+
# set width
|
497
|
+
# a container must pass down changes in size to it's children
|
498
|
+
# added 2010-01-16 23:55
|
499
|
+
def width(*val)
|
500
|
+
return @width if val.empty?
|
501
|
+
oldvalue = @width || 0
|
502
|
+
super
|
503
|
+
@width = val[0]
|
504
|
+
return if @viewport == nil
|
505
|
+
delta = @width - oldvalue
|
506
|
+
return if delta == 0
|
507
|
+
@repaint_required = true
|
508
|
+
@viewport.width += delta
|
509
|
+
end
|
510
|
+
|
511
|
+
end # class ScrollPane
|
512
|
+
end # module
|