rbcurse 0.1.3 → 1.1.1
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/CHANGELOG +126 -0
- data/Manifest.txt +53 -20
- data/README.markdown +423 -0
- data/Rakefile +3 -1
- data/examples/keytest.rb +177 -0
- data/examples/mpad2.rb +156 -0
- data/examples/newtesttabp.rb +121 -0
- data/examples/rfe.rb +48 -10
- data/examples/rfe_renderer.rb +4 -4
- data/examples/rvimsplit.rb +376 -0
- data/examples/sqlc.rb +97 -106
- data/examples/sqlm.rb +446 -0
- data/examples/test1.rb +4 -4
- data/examples/test2.rb +12 -12
- data/examples/testchars.rb +140 -0
- data/examples/testkeypress.rb +9 -4
- data/examples/testmulticomp.rb +72 -0
- data/examples/testscroller.rb +136 -0
- data/examples/testscrolllb.rb +86 -0
- data/examples/testscrollp.rb +87 -0
- data/examples/testscrollta.rb +80 -0
- data/examples/testscrolltable.rb +166 -0
- data/examples/testsplit.rb +87 -0
- data/examples/testsplit2.rb +123 -0
- data/examples/testsplit3.rb +215 -0
- data/examples/testsplit3_1.rb +244 -0
- data/examples/testsplit3a.rb +215 -0
- data/examples/testsplit3b.rb +237 -0
- data/examples/testsplitta.rb +148 -0
- data/examples/testsplittv.rb +142 -0
- data/examples/testsplittvv.rb +144 -0
- data/examples/testtable.rb +1 -1
- data/examples/testtabp.rb +3 -2
- data/examples/testtestw.rb +69 -0
- data/examples/testtodo.rb +5 -3
- data/examples/testtpane.rb +203 -0
- data/examples/testtpane2.rb +145 -0
- data/examples/testtpanetable.rb +199 -0
- data/examples/viewtodo.rb +5 -3
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/celleditor.rb +2 -2
- data/lib/rbcurse/colormap.rb +5 -5
- data/lib/rbcurse/defaultlistselectionmodel.rb +3 -3
- data/lib/rbcurse/io.rb +663 -0
- data/lib/rbcurse/listeditable.rb +306 -0
- data/lib/rbcurse/listkeys.rb +15 -15
- data/lib/rbcurse/listscrollable.rb +168 -27
- data/lib/rbcurse/mapper.rb +35 -13
- data/lib/rbcurse/rchangeevent.rb +28 -0
- data/lib/rbcurse/rform.rb +845 -0
- data/lib/rbcurse/rlistbox.rb +144 -34
- data/lib/rbcurse/rmessagebox.rb +10 -5
- data/lib/rbcurse/rmulticontainer.rb +325 -0
- data/lib/rbcurse/rmultitextview.rb +306 -0
- data/lib/rbcurse/rscrollform.rb +369 -0
- data/lib/rbcurse/rscrollpane.rb +511 -0
- data/lib/rbcurse/rsplitpane.rb +820 -0
- data/lib/rbcurse/rtabbedpane.rb +737 -109
- data/lib/rbcurse/rtabbedwindow.rb +326 -0
- data/lib/rbcurse/rtable.rb +220 -64
- data/lib/rbcurse/rtextarea.rb +340 -181
- data/lib/rbcurse/rtextview.rb +237 -101
- data/lib/rbcurse/rviewport.rb +203 -0
- data/lib/rbcurse/rwidget.rb +919 -95
- data/lib/rbcurse/scrollable.rb +7 -7
- data/lib/rbcurse/selectable.rb +4 -4
- data/lib/rbcurse/table/tablecellrenderer.rb +3 -0
- data/lib/rbcurse/undomanager.rb +181 -0
- data/lib/rbcurse/vieditable.rb +100 -0
- data/lib/ver/window.rb +471 -21
- metadata +66 -22
- data/README.txt +0 -312
- data/examples/testd.db +0 -0
- data/examples/todocsv.csv +0 -28
data/lib/rbcurse/scrollable.rb
CHANGED
@@ -221,18 +221,18 @@ module Scrollable
|
|
221
221
|
begin
|
222
222
|
pre_key
|
223
223
|
case ch
|
224
|
-
when ?\C-n
|
224
|
+
when ?\C-n.getbyte(0)
|
225
225
|
scroll_forward
|
226
226
|
when 32
|
227
227
|
scroll_forward
|
228
|
-
when ?\C-p
|
228
|
+
when ?\C-p.getbyte(0)
|
229
229
|
scroll_backward
|
230
|
-
when ?0
|
230
|
+
when ?0.getbyte(0)
|
231
231
|
goto_start
|
232
|
-
when ?9
|
232
|
+
when ?9.getbyte(0)
|
233
233
|
goto_end
|
234
|
-
when ?[
|
235
|
-
when ?[
|
234
|
+
when ?[.getbyte(0)
|
235
|
+
when ?[.getbyte(0)
|
236
236
|
when KEY_UP
|
237
237
|
#select_prev_row
|
238
238
|
up
|
@@ -245,7 +245,7 @@ module Scrollable
|
|
245
245
|
if respond_to? :fire
|
246
246
|
fire
|
247
247
|
end
|
248
|
-
when ?A..?Z, ?a..?z
|
248
|
+
when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0)
|
249
249
|
ret = set_selection_for_char ch.chr
|
250
250
|
else
|
251
251
|
return :UNHANDLED #if ret == -1
|
data/lib/rbcurse/selectable.rb
CHANGED
@@ -71,17 +71,17 @@ module Selectable
|
|
71
71
|
def selectable_handle_key ch
|
72
72
|
begin
|
73
73
|
case ch
|
74
|
-
when
|
74
|
+
when ?;.getbyte(0), 32 # x no more selecting since we now jump to row matching char 2008-12-18 13:13
|
75
75
|
return if is_popup and @select_mode == 'single' # not allowing select this way since there will be a difference
|
76
76
|
# between pressing ENTER and space. Enter is trapped by Listbox!
|
77
77
|
do_select
|
78
|
-
when ?'
|
78
|
+
when ?'.getbyte(0)
|
79
79
|
$log.debug "insdie next selection"
|
80
80
|
do_next_selection if @select_mode == 'multiple'
|
81
|
-
when ?"
|
81
|
+
when ?".getbyte(0)
|
82
82
|
$log.debug "insdie prev selection"
|
83
83
|
do_prev_selection if @select_mode == 'multiple'
|
84
|
-
when ?\C-e
|
84
|
+
when ?\C-e.getbyte(0)
|
85
85
|
do_clear_selection if @select_mode == 'multiple'
|
86
86
|
else
|
87
87
|
return :UNHANDLED
|
@@ -77,6 +77,9 @@ module RubyCurses
|
|
77
77
|
padding = 0 if padding < 0
|
78
78
|
_value = " "*padding + _value + " "*padding # so its cleared if we change it midway
|
79
79
|
end
|
80
|
+
# XXX 2009-10-05 23:01 since the len can vary when scrolling
|
81
|
+
# right justification for numbers suffers.
|
82
|
+
# perhaps one should use display_length and then truncate using len
|
80
83
|
graphic.printstring r, c, str % [len, _value], acolor,_attr
|
81
84
|
r += 1
|
82
85
|
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
=begin
|
2
|
+
* Name: UndoManager
|
3
|
+
* Description: Manages undo of text components
|
4
|
+
* Author: rkumar (arunachalesha)
|
5
|
+
|
6
|
+
ISSUES
|
7
|
+
|
8
|
+
This is a very simple, undo facility. This could change in the near future.
|
9
|
+
|
10
|
+
Todo:
|
11
|
+
We need to handle block updates - several undo ops to be done together.
|
12
|
+
|
13
|
+
|
14
|
+
--------
|
15
|
+
* Date: 2010-03-07 19:42
|
16
|
+
* License:
|
17
|
+
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
18
|
+
|
19
|
+
=end
|
20
|
+
|
21
|
+
#
|
22
|
+
#
|
23
|
+
module RubyCurses
|
24
|
+
#
|
25
|
+
# AbstractUndo has the basic workings of the undo redo facility.
|
26
|
+
# It leaves the actual undo and redo to the implementing source object. However,
|
27
|
+
# it does the work of storing edits, and passing the correct edit to the implementor
|
28
|
+
# when the source object calls for an undo or redo operation. It thus manages the edit (undo) queue.
|
29
|
+
#
|
30
|
+
class AbstractUndo
|
31
|
+
# initialize the source object which will issue undo requests
|
32
|
+
def initialize _source
|
33
|
+
source(_source) #if _source
|
34
|
+
@pointer = 0
|
35
|
+
@actions = []
|
36
|
+
$log.debug " INSIDE UNDO CONSTR "
|
37
|
+
end
|
38
|
+
def source(_source)
|
39
|
+
$log.debug " calling source= "
|
40
|
+
raise "Cannot pass a nil source" unless _source
|
41
|
+
@source = _source
|
42
|
+
# currently this is very hardcode again. we need to see this in the light of other objects
|
43
|
+
#@source.bind(:CHANGE){|eve| add_edit(eve) }
|
44
|
+
# a little roundabout but done for getting things up fast
|
45
|
+
@source.undo_handler(self)
|
46
|
+
$log.debug " I am listening to change events on #{@source.name} "
|
47
|
+
end
|
48
|
+
# this is called whenever an undoable edit has happened.
|
49
|
+
# Currently, it is linked above in the bind statement. We've attached this
|
50
|
+
# method as a listener to the source.
|
51
|
+
def add_edit event
|
52
|
+
# this debug is very specific. it should be removed later. We do not know about the object
|
53
|
+
$log.debug " UNDO GOT #{event}: #{event.type}, (#{event.text}), rej: #{@reject_update} "
|
54
|
+
return if @reject_update
|
55
|
+
if @pointer < @actions.length
|
56
|
+
$log.debug " removing some actions since #{@pointer} < #{@actions.length} "
|
57
|
+
@actions.slice!(@pointer..-1)
|
58
|
+
$log.debug " removed actions since #{@pointer} , #{@actions.length} "
|
59
|
+
end
|
60
|
+
@actions << event
|
61
|
+
@pointer = @actions.length
|
62
|
+
end
|
63
|
+
# this has to be bound in source component
|
64
|
+
# typically bind C-_ to undo()
|
65
|
+
# this method figures out the correct undo object to be sent
|
66
|
+
# to the implementor
|
67
|
+
def undo
|
68
|
+
$log.debug " got UNDO call #{@pointer}, sz:#{@actions.size} "
|
69
|
+
return if @pointer == 0
|
70
|
+
@reject_update = true
|
71
|
+
@pointer -=1 #if @pointer > 0
|
72
|
+
@source.repaint_required true
|
73
|
+
@reject_update = false
|
74
|
+
edit = @actions[@pointer]
|
75
|
+
perform_undo edit
|
76
|
+
end
|
77
|
+
# this has to be bound in source
|
78
|
+
# typically bind C-r to redo()
|
79
|
+
# this method figures out the correct redo object to be sent
|
80
|
+
# to the implementor
|
81
|
+
def redo
|
82
|
+
$log.debug "UNDO GOT REDO call #{@pointer}, #{@actions.size} "
|
83
|
+
return if @pointer >= @actions.size
|
84
|
+
@reject_update = true
|
85
|
+
edit = @actions[@pointer]
|
86
|
+
perform_redo edit
|
87
|
+
@source.repaint_required true
|
88
|
+
@pointer +=1 #if @pointer > 0
|
89
|
+
@reject_update = false
|
90
|
+
end
|
91
|
+
def perform_redo edit
|
92
|
+
raise "You must implement this for your undoable component "
|
93
|
+
end
|
94
|
+
def perform_undo edit
|
95
|
+
raise "You must implement this for your undoable component "
|
96
|
+
# to be implemented
|
97
|
+
end
|
98
|
+
#def to_s
|
99
|
+
#inspect
|
100
|
+
#end
|
101
|
+
#def inspect
|
102
|
+
### now that textarea.to_s prints content we shouldn pass it here.
|
103
|
+
##"#{@type.to_s}, #{@source}, ind0:#{@index0}, ind1:#{@index1}, row:#{@row}, text:#{@text}"
|
104
|
+
#"#{@type.to_s}, ind0:#{@index0}, ind1:#{@index1}, row:#{@row}, text:#{@text}"
|
105
|
+
#end
|
106
|
+
end
|
107
|
+
## An implementation of AbstractUndo for textarea.
|
108
|
+
# Very basic.
|
109
|
+
class SimpleUndo < AbstractUndo
|
110
|
+
def initialize _source
|
111
|
+
super
|
112
|
+
end
|
113
|
+
def source(_source)
|
114
|
+
super
|
115
|
+
_source.bind(:CHANGE){|eve| add_edit(eve) }
|
116
|
+
end
|
117
|
+
def perform_undo act
|
118
|
+
row = act.row
|
119
|
+
col = act.index0
|
120
|
+
$log.debug " processing #{act} "
|
121
|
+
case act.type
|
122
|
+
when :INSERT
|
123
|
+
howmany = act.index1 - col
|
124
|
+
@source.list[row].slice!(col,howmany)
|
125
|
+
when :DELETE
|
126
|
+
$log.debug " UNDO processing DELETE #{col}, (#{act.text}) "
|
127
|
+
@source.list[row].insert(col, act.text.chomp)
|
128
|
+
when :DELETE_LINE
|
129
|
+
$log.debug " UNDO inside delete-line #{row} "
|
130
|
+
#@source.list.insert(row, act.text) # insert a blank line, since one was deleted
|
131
|
+
case act.text
|
132
|
+
when Array
|
133
|
+
index = row
|
134
|
+
act.text.each_with_index{|r,i| @source.list.insert index+i, r}
|
135
|
+
when String
|
136
|
+
@source.list.insert row, act.text
|
137
|
+
end
|
138
|
+
when :INSERT_LINE
|
139
|
+
$log.debug " UNDO inside insert-line #{row} "
|
140
|
+
case act.text
|
141
|
+
when Array
|
142
|
+
act.text.size.times { @source.list.delete_at row }
|
143
|
+
when String
|
144
|
+
@source.list.delete_at row
|
145
|
+
end
|
146
|
+
else
|
147
|
+
$log.warn "unhandled change type #{act.type} "
|
148
|
+
end
|
149
|
+
@source.repaint_required true
|
150
|
+
@reject_update = false
|
151
|
+
end
|
152
|
+
# this has to be bound in source
|
153
|
+
def perform_redo act
|
154
|
+
row = act.row
|
155
|
+
col = act.index0
|
156
|
+
$log.debug " REDO processing #{act} "
|
157
|
+
case act.type
|
158
|
+
when :INSERT
|
159
|
+
@source.list[row].insert(col, act.text)
|
160
|
+
when :DELETE
|
161
|
+
row = act.row
|
162
|
+
col = act.index0
|
163
|
+
howmany = act.index1 - col
|
164
|
+
@source.list[row].slice!(col,howmany)
|
165
|
+
when :DELETE_LINE
|
166
|
+
#$log.debug " UNDO redo got deleteline #{row} "
|
167
|
+
@source.list.delete_at row
|
168
|
+
when :INSERT_LINE
|
169
|
+
case act.text
|
170
|
+
when Array
|
171
|
+
index = row
|
172
|
+
act.text.each_with_index{|r,i| @source.list.insert index+i, r}
|
173
|
+
when String
|
174
|
+
@source.list.insert row, act.text
|
175
|
+
end
|
176
|
+
else
|
177
|
+
$log.warn "unhandled change type #{act.type} "
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end # module
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#**************************************************************
|
2
|
+
# Author: rkumar (arunachalesha)
|
3
|
+
# Date: 2010-03-11 22:18
|
4
|
+
# Provides the caller ability to do some edit operations
|
5
|
+
# on list widgets using either keys (vim largely)
|
6
|
+
# or a menu. made originally for textview and multitextview
|
7
|
+
#
|
8
|
+
#**************************************************************
|
9
|
+
#hscrollcols = $multiplier > 0 ? $multiplier : @width/2
|
10
|
+
#def previous_row num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
|
11
|
+
require 'rbcurse/listeditable'
|
12
|
+
module ViEditable
|
13
|
+
include ListEditable
|
14
|
+
|
15
|
+
#def ViEditable.vieditable_init
|
16
|
+
def vieditable_init
|
17
|
+
$log.debug " inside vieditable_init "
|
18
|
+
@editable = true
|
19
|
+
bind_key( ?C, :edit_line)
|
20
|
+
bind_key( ?o, :insert_line)
|
21
|
+
bind_key( ?O) { insert_line(@current_index-1) }
|
22
|
+
bind_key( ?D, :delete_eol)
|
23
|
+
bind_key( [?d, ?$], :delete_eol)
|
24
|
+
bind_key( [?d, ?d] , :delete_line )
|
25
|
+
bind_key( [?d, ?w], :delete_word )
|
26
|
+
bind_key( [?d, ?t], :delete_till )
|
27
|
+
bind_key( [?d, ?f], :delete_forward )
|
28
|
+
bind_key( ?\C-_ ) { @undo_handler.undo if @undo_handler }
|
29
|
+
bind_key( ?u ) { @undo_handler.undo if @undo_handler }
|
30
|
+
bind_key( ?\C-r ) { @undo_handler.redo if @undo_handler }
|
31
|
+
bind_key( ?x, :delete_curr_char )
|
32
|
+
bind_key( ?X, :delete_prev_char )
|
33
|
+
bind_key( [?y, ?y] , :kill_ring_save )
|
34
|
+
bind_key( ?p, :yank ) # paste after this line
|
35
|
+
bind_key( ?P ) { yank(@current_index - 1) } # should be before this line
|
36
|
+
bind_key(?\w, :forward_word)
|
37
|
+
bind_key(?f, :forward_char)
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# edit current or given line
|
43
|
+
def edit_line lineno=@current_index
|
44
|
+
line = @list[lineno]
|
45
|
+
prompt = "Edit: "
|
46
|
+
maxlen = 80
|
47
|
+
config={};
|
48
|
+
config[:default] = line
|
49
|
+
ret, str = rbgetstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
50
|
+
$log.debug " rbgetstr returned #{ret} , #{str} "
|
51
|
+
return if ret != 0
|
52
|
+
@list[lineno].replace(str)
|
53
|
+
@repaint_required = true
|
54
|
+
end
|
55
|
+
##
|
56
|
+
# insert a line
|
57
|
+
def insert_line lineno=@current_index
|
58
|
+
prompt = "Insert: "
|
59
|
+
maxlen = 80
|
60
|
+
#config={};
|
61
|
+
#config[:default] = line
|
62
|
+
#ret, str = rbgetstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
63
|
+
ret, str = input_string prompt
|
64
|
+
#ret, str = rbgetstr(@form.window, @row+@height-1, @col+1, prompt, maxlen, config)
|
65
|
+
$log.debug " rbgetstr returned #{ret} , #{str} "
|
66
|
+
return if ret != 0
|
67
|
+
@list.insert lineno, str
|
68
|
+
@repaint_required = true
|
69
|
+
end
|
70
|
+
##
|
71
|
+
# common method to edit given string
|
72
|
+
# @param [String] string to edit/modify
|
73
|
+
# @param [String] prompt to display before string
|
74
|
+
# @param [int] max length of input
|
75
|
+
# @return [0, -1] return value 0 if okay, -1 if error
|
76
|
+
#
|
77
|
+
def edit_string string, prompt="Edit: ", maxlen=80
|
78
|
+
config={};
|
79
|
+
config[:default] = string
|
80
|
+
ret, str = rbgetstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
81
|
+
#return str if ret == 0
|
82
|
+
#return ""
|
83
|
+
end
|
84
|
+
##
|
85
|
+
# common method to input a blank string
|
86
|
+
# @param [String] prompt to display before string
|
87
|
+
# @param [int] max length of input
|
88
|
+
# @return [0, -1] return value 0 if okay, -1 if error
|
89
|
+
def input_string prompt="Insert: ", maxlen=80
|
90
|
+
ret, str = rbgetstr(@form.window, $error_message_row, $error_message_col, prompt, maxlen, config)
|
91
|
+
#return str if ret == 0
|
92
|
+
#return ""
|
93
|
+
end
|
94
|
+
def edit_chars
|
95
|
+
|
96
|
+
end
|
97
|
+
def edit_word
|
98
|
+
|
99
|
+
end
|
100
|
+
end # module
|
data/lib/ver/window.rb
CHANGED
@@ -1,17 +1,12 @@
|
|
1
1
|
require 'ver/ncurses'
|
2
2
|
module VER
|
3
|
-
|
4
|
-
# * Interface to Ncurses::WINDOW and Ncurses::Panel
|
5
|
-
# * behave IO like: (print puts write read readline)
|
6
|
-
# * hide and show itself
|
7
|
-
|
8
|
-
# There's a very strange bug when i tried subclassing this, as Ncurses seems
|
9
|
-
# to overwrite WINDOW::new, which will not return the Window instance we
|
10
|
-
# want. So we have to wrap instead of subclass.
|
11
|
-
class Window # < Ncurses::WINDOW
|
3
|
+
class Window
|
12
4
|
attr_reader :width, :height, :top, :left
|
13
5
|
attr_accessor :layout
|
14
|
-
attr_reader :panel #
|
6
|
+
attr_reader :panel # reader requires so he can del it in end
|
7
|
+
attr_reader :window_type # window or pad to distinguish 2009-11-02 23:11
|
8
|
+
attr_accessor :name # more for debugging log files. 2010-02-02 19:58
|
9
|
+
attr_accessor :modified # has it been modified and may need a refresh
|
15
10
|
|
16
11
|
def initialize(layout)
|
17
12
|
@visible = true
|
@@ -19,24 +14,48 @@ module VER
|
|
19
14
|
|
20
15
|
@window = Ncurses::WINDOW.new(height, width, top, left)
|
21
16
|
@panel = Ncurses::Panel.new_panel(@window)
|
17
|
+
init_vars
|
22
18
|
## eeks XXX next line will wreak havoc when multiple windows opened like a mb or popup
|
23
|
-
|
19
|
+
#$error_message_row = $status_message_row = Ncurses.LINES-1
|
20
|
+
$error_message_row ||= Ncurses.LINES-1
|
21
|
+
$error_message_col ||= 1
|
22
|
+
|
24
23
|
|
24
|
+
end
|
25
|
+
def init_vars
|
26
|
+
@window_type = :WINDOW
|
25
27
|
Ncurses::keypad(@window, true)
|
26
28
|
@stack = []
|
29
|
+
@name ||="#{self}"
|
30
|
+
@modified = true
|
31
|
+
$catch_alt_digits ||= false # is this where is should put globals ? 2010-03-14 14:00 XXX
|
27
32
|
end
|
33
|
+
##
|
34
|
+
# this is an alternative constructor
|
28
35
|
def self.root_window(layout = { :height => 0, :width => 0, :top => 0, :left => 0 })
|
29
36
|
#VER::start_ncurses
|
30
37
|
@layout = layout
|
31
38
|
@window = Window.new(@layout)
|
39
|
+
@window.name = "Window::ROOTW"
|
32
40
|
@window.wrefresh
|
33
41
|
Ncurses::Panel.update_panels
|
34
42
|
return @window
|
35
43
|
end
|
44
|
+
# 2009-10-13 12:24
|
45
|
+
# not used as yet
|
46
|
+
# this is an alternative constructor
|
47
|
+
# created if you don't want to create a hash first
|
48
|
+
def self.create_window(h=0, w=0, t=0, l=0)
|
49
|
+
layout = { :height => h, :width => w, :top => t, :left => l }
|
50
|
+
@window = Window.new(layout)
|
51
|
+
return @window
|
52
|
+
end
|
36
53
|
|
37
54
|
def resize_with(layout)
|
55
|
+
$log.debug " DARN ! This awready duz a resize!! if h or w or even top or left changed!!! XXX"
|
38
56
|
reset_layout(layout)
|
39
57
|
@window.wresize(height, width)
|
58
|
+
# this is dicey since we often change top and left in pads only for panning !! XXX
|
40
59
|
@window.mvwin(top, left)
|
41
60
|
end
|
42
61
|
|
@@ -130,6 +149,10 @@ module VER
|
|
130
149
|
@window.mvchgat(y, x, max, Ncurses::A_NORMAL, color, nil)
|
131
150
|
end
|
132
151
|
|
152
|
+
def ungetch(ch)
|
153
|
+
Ncurses.ungetch(ch)
|
154
|
+
end
|
155
|
+
|
133
156
|
def getch
|
134
157
|
@window.getch
|
135
158
|
rescue Interrupt => ex
|
@@ -276,6 +299,7 @@ module VER
|
|
276
299
|
# @panel = @window.panel if @window
|
277
300
|
#Ncurses::Panel.del_panel(@panel) if !@panel.nil?
|
278
301
|
#@window.delwin if !@window.nil?
|
302
|
+
$log.debug "win destroy"
|
279
303
|
|
280
304
|
#@panel = @window.panel if @window
|
281
305
|
Ncurses::Panel.del_panel(@panel) if !@panel.nil?
|
@@ -291,10 +315,17 @@ module VER
|
|
291
315
|
# @ param att - ncurses attribute: normal, bold, reverse, blink,
|
292
316
|
# underline
|
293
317
|
def printstring(r,c,string, color, att = Ncurses::A_NORMAL)
|
318
|
+
prv_printstring(r,c,string, color, att )
|
319
|
+
end
|
320
|
+
|
321
|
+
## name changed from printstring to prv_prinstring
|
322
|
+
def prv_printstring(r,c,string, color, att = Ncurses::A_NORMAL)
|
294
323
|
|
295
|
-
|
296
|
-
att = Ncurses::A_NORMAL if att.nil?
|
324
|
+
#$log.debug " #{@name} inside window printstring r #{r} c #{c} #{string} "
|
325
|
+
att = Ncurses::A_NORMAL if att.nil?
|
297
326
|
case att.to_s.downcase
|
327
|
+
when 'normal'
|
328
|
+
att = Ncurses::A_NORMAL
|
298
329
|
when 'underline'
|
299
330
|
att = Ncurses::A_UNDERLINE
|
300
331
|
when 'bold'
|
@@ -311,17 +342,22 @@ module VER
|
|
311
342
|
width = Ncurses.COLS
|
312
343
|
# the next line won't ensure we don't write outside some bounds like table
|
313
344
|
#string = string[0..(width-c)] if c + string.length > width
|
314
|
-
#$log.debug "PRINT
|
345
|
+
#$log.debug "PRINT len:#{string.length}, #{Ncurses.COLS}, #{r}, #{c} w: #{@window} "
|
315
346
|
mvprintw(r, c, "%s", string);
|
316
347
|
attroff(Ncurses.COLOR_PAIR(color) | att)
|
317
348
|
end
|
318
349
|
# added by rk 2008-11-29 19:01
|
350
|
+
# Since these methods write directly to window they are not advised
|
351
|
+
# since clearing previous message we don't know how much to clear.
|
352
|
+
# Best to map error_message to a label.
|
319
353
|
def print_error_message text=$error_message
|
320
354
|
r = $error_message_row || Ncurses.LINES-1
|
321
|
-
|
355
|
+
c = $error_message_col || (Ncurses.COLS-text.length)/2
|
356
|
+
|
357
|
+
$log.debug "got ERROR MESSAGE #{text} row #{r} "
|
322
358
|
clear_error r, $datacolor
|
323
|
-
|
324
|
-
|
359
|
+
printstring r, c, text, color = $promptcolor
|
360
|
+
$error_message_clear_pending = true
|
325
361
|
end
|
326
362
|
# added by rk 2008-11-29 19:01
|
327
363
|
def print_status_message text=$status_message
|
@@ -330,10 +366,19 @@ module VER
|
|
330
366
|
# print it in centre
|
331
367
|
printstring r, (Ncurses.COLS-text.length)/2, text, color = $promptcolor
|
332
368
|
end
|
333
|
-
#
|
369
|
+
# Clear error message printed
|
370
|
+
# I am not only clearing if something was printed. This is since
|
371
|
+
# certain small forms like TabbedForm top form throw an error on printstring.
|
372
|
+
#
|
334
373
|
def clear_error r = $error_message_row, color = $datacolor
|
335
|
-
|
374
|
+
return unless $error_message_clear_pending
|
375
|
+
c = $error_message_col || (Ncurses.COLS-text.length)/2
|
376
|
+
sz = $error_message_size || Ncurses.COLS
|
377
|
+
printstring(r, c, "%-*s" % [sz, " "], color)
|
378
|
+
$error_message_clear_pending = false
|
336
379
|
end
|
380
|
+
##
|
381
|
+
# CAUTION : FOR MESSAGEBOXES ONLY !!!! XXX
|
337
382
|
def print_border_mb row, col, height, width, color, attr
|
338
383
|
mvwaddch row, col, ACS_ULCORNER
|
339
384
|
mvwhline( row, col+1, ACS_HLINE, width-6)
|
@@ -345,15 +390,35 @@ module VER
|
|
345
390
|
mvwaddch row+height-3, col+width-5, Ncurses::ACS_LRCORNER
|
346
391
|
mvwvline( row+1, col+width-5, ACS_VLINE, height-4)
|
347
392
|
end
|
393
|
+
##
|
394
|
+
# prints a border around a widget, CLEARING the area.
|
395
|
+
# If calling with a pad, you would typically use 0,0, h-1, w-1.
|
348
396
|
def print_border row, col, height, width, color, att=Ncurses::A_NORMAL
|
349
397
|
att ||= Ncurses::A_NORMAL
|
350
398
|
|
399
|
+
$log.debug " inside window print_border r #{row} c #{col} h #{height} w #{width} "
|
400
|
+
|
401
|
+
# 2009-11-02 00:45 made att nil for blanking out
|
402
|
+
# FIXME - in tabbedpanes this clears one previous line ??? XXX when using a textarea/view
|
403
|
+
# when using a pad this calls pads printstring which again reduces top and left !!! 2010-01-26 23:53
|
351
404
|
(row+1).upto(row+height-1) do |r|
|
352
|
-
printstring( r, col+1," "*(width-2) ,
|
405
|
+
#printstring( r, col+1," "*(width-2) , $datacolor, nil)
|
406
|
+
prv_printstring( r, col+1," "*(width-2) , $datacolor, nil)
|
353
407
|
end
|
354
|
-
|
408
|
+
prv_print_border_only row, col, height, width, color, att
|
409
|
+
end
|
410
|
+
def print_border_only row, col, height, width, color, att=Ncurses::A_NORMAL
|
411
|
+
prv_print_border_only row, col, height, width, color, att
|
412
|
+
end
|
355
413
|
|
356
414
|
|
415
|
+
## print just the border, no cleanup
|
416
|
+
#+ Earlier, we would clean up. Now in some cases, i'd like
|
417
|
+
#+ to print border over what's been done.
|
418
|
+
# XXX this reduces 1 from width but not height !!! FIXME
|
419
|
+
def prv_print_border_only row, col, height, width, color, att=Ncurses::A_NORMAL
|
420
|
+
att ||= Ncurses::A_NORMAL
|
421
|
+
attron(Ncurses.COLOR_PAIR(color) | att)
|
357
422
|
mvwaddch row, col, ACS_ULCORNER
|
358
423
|
mvwhline( row, col+1, ACS_HLINE, width-2)
|
359
424
|
mvwaddch row, col+width-1, Ncurses::ACS_URCORNER
|
@@ -365,5 +430,390 @@ module VER
|
|
365
430
|
mvwvline( row+1, col+width-1, ACS_VLINE, height-1)
|
366
431
|
attroff(Ncurses.COLOR_PAIR(color) | att)
|
367
432
|
end
|
433
|
+
# added RK 2009-10-08 23:57 for tabbedpanes
|
434
|
+
# THIS IS EXPERIMENTAL -
|
435
|
+
# Acco to most sources, derwin and subwin are not thoroughly tested, avoid usage
|
436
|
+
# subwin moving and resizing not functioning.
|
437
|
+
def derwin(layout)
|
438
|
+
$log.debug " #{self} EXP: returning a subwin in derwin"
|
439
|
+
v = VER::SubWindow.new(self, layout)
|
440
|
+
$log.debug " #{self} EXP: returning a subwin in derwin: #{v} "
|
441
|
+
return v
|
442
|
+
end
|
443
|
+
def _subwin(layout)
|
444
|
+
t = @layout[:top]
|
445
|
+
l = @layout[:left]
|
446
|
+
layout[:top] = layout[:top] + t
|
447
|
+
layout[:left] = layout[:left] + l
|
448
|
+
$log.debug " #{self} EXP: returning a subwin in derwin. Adding #{t} and #{l} "
|
449
|
+
v = VER::SubWindow.new(self, layout)
|
450
|
+
$log.debug " #{self} EXP: returning a subwin in derwin: #{v} "
|
451
|
+
return v
|
452
|
+
end
|
453
|
+
def get_window; @window; end
|
454
|
+
def to_s; @name || self; end
|
455
|
+
# use in place of mvwhline if your widget could be using a pad or window
|
456
|
+
def rb_mvwhline row, col, char, width
|
457
|
+
mvwhline row, col, char, width
|
458
|
+
end
|
459
|
+
# use in place of mvwvline if your widget could be using a pad or window
|
460
|
+
def rb_mvwvline row, col, char, width
|
461
|
+
mvwvline row, col, char, width
|
462
|
+
end
|
463
|
+
# use in place of mvaddch if your widget could be using a pad or window
|
464
|
+
def rb_mvaddch row, col, char
|
465
|
+
mvaddch row, col, char
|
466
|
+
end
|
467
|
+
end
|
468
|
+
##
|
469
|
+
# added RK 2009-10-08 23:57 for tabbedpanes
|
470
|
+
# THIS IS EXPERIMENTAL -
|
471
|
+
# I have not called super in the initializer so any methods you try on subwin
|
472
|
+
# that exist in the superclass which use @window will bomb
|
473
|
+
# @since 0.1.3
|
474
|
+
class SubWindow < VER::Window
|
475
|
+
attr_reader :width, :height, :top, :left
|
476
|
+
attr_accessor :layout
|
477
|
+
attr_reader :panel # XXX reader requires so he can del it in end
|
478
|
+
attr_reader :subwin #
|
479
|
+
attr_reader :parent #
|
480
|
+
|
481
|
+
def initialize(parent, layout)
|
482
|
+
@visible = true
|
483
|
+
reset_layout(layout)
|
484
|
+
|
485
|
+
@parent = parent
|
486
|
+
#@subwin = @parent.get_window().derwin(@height, @width, @top, @left)
|
487
|
+
@subwin = @parent.get_window().subwin(@height, @width, @top, @left)
|
488
|
+
$log.debug "SUBWIN init #{@height} #{@width} #{@top} #{@left} "
|
489
|
+
#$log.debug "SUBWIN init #{@subwin.getbegx} #{@subwin.getbegy} #{@top} #{@left} "
|
490
|
+
@panel = Ncurses::Panel.new_panel(@subwin)
|
491
|
+
|
492
|
+
@window = @subwin # makes more mthods available
|
493
|
+
init_vars
|
494
|
+
|
495
|
+
end
|
496
|
+
# no need really now
|
497
|
+
def reset_layout layout
|
498
|
+
@layout = layout # 2010-02-13 22:23
|
499
|
+
@height = layout[:height]
|
500
|
+
@width = layout[:width]
|
501
|
+
@top = layout[:top]
|
502
|
+
@left = layout[:left]
|
503
|
+
end
|
504
|
+
def _destroy
|
505
|
+
# typically the ensure block should have this
|
506
|
+
# or should window do it for all subwins, or would we want to wait that long ?
|
507
|
+
$log.debug "subwin destroy"
|
508
|
+
|
509
|
+
Ncurses::Panel.del_panel(@panel) if !@panel.nil?
|
510
|
+
@window.delwin if !@window.nil?
|
511
|
+
end
|
368
512
|
end
|
513
|
+
|
514
|
+
##
|
515
|
+
# Pad
|
516
|
+
# This is EXPERIMENTAL
|
517
|
+
# A pad cannot be used interchangeable since some application functions such as wrefresh
|
518
|
+
# are illegal. Cannot expect the application to take care.
|
519
|
+
# Internally we can make it easier. Mostly a pad is used to map to one portion of the screen.
|
520
|
+
# So we allow that to be defined once. Then only start row and col of pad change.
|
521
|
+
# Maybe we should check pad coordinates so no errors
|
522
|
+
# Also check screen coordinates (if we know)
|
523
|
+
# We need padheight and padwidth only to ensure we don't keep recreating.
|
524
|
+
# Howevre, when comp's height increases, then decreases, pad height remains larger
|
525
|
+
# but we keep printing an extra row in copywin. so Pad needs to maintain comp height
|
526
|
+
# and padheight.
|
527
|
+
# @since 0.1.3
|
528
|
+
class Pad < VER::Window
|
529
|
+
# top and left correspond to screen's top and left wich will mostly be fixed
|
530
|
+
attr_accessor :top, :left
|
531
|
+
# start row and col correspond to pad's top and left which will change if scrolling
|
532
|
+
attr_accessor :pminrow, :pmincol
|
533
|
+
# screen's height and width, now it reflects components height and width
|
534
|
+
attr_accessor :sheight, :swidth
|
535
|
+
attr_reader :otherwin
|
536
|
+
# dimensions the pad was created with, used so we don't keep recreating pad, only if increase.
|
537
|
+
attr_reader :padheight, :padwidth
|
538
|
+
#attr_accessor :name # more for debugging log files. 2010-02-02 19:58
|
539
|
+
def initialize(height, width)
|
540
|
+
@visible = true
|
541
|
+
# do we set height and width ?? XXX
|
542
|
+
@window = Ncurses.newpad(height, width)
|
543
|
+
@padheight = height
|
544
|
+
@padwidth = width
|
545
|
+
@height = height
|
546
|
+
@width = width
|
547
|
+
@sheight = height
|
548
|
+
@swidth = width
|
549
|
+
init_vars
|
550
|
+
end
|
551
|
+
def init_vars
|
552
|
+
super
|
553
|
+
@top ||= 0; @left ||= 0
|
554
|
+
@pmincol ||= 0 # pad will print from this col
|
555
|
+
@pminrow ||= 0 # pad will print from this row
|
556
|
+
@window_type = :PAD
|
557
|
+
@name ||="#{self}"
|
558
|
+
$log.debug " PAD constructor #{self} , #{@window} "
|
559
|
+
end
|
560
|
+
#
|
561
|
+
# @param layout is a hash (@see Window.initialize)
|
562
|
+
def self.create_with_layout(layout)
|
563
|
+
@window = Pad.new(layout[:height], layout[:width])
|
564
|
+
@window.reset_layout(layout)
|
565
|
+
return @window
|
566
|
+
end
|
567
|
+
##
|
568
|
+
# increases the pad size, since the widget may have been resized
|
569
|
+
# checks that one of ht or width has been increased
|
570
|
+
# destroys earlier pad and returns new one
|
571
|
+
# Updates sheight and swidth even if reduced so copywin works fine.
|
572
|
+
# @param [Fixnum] height to resize to
|
573
|
+
# @param [Fixnum] width to resize to
|
574
|
+
# @return [Pad]
|
575
|
+
# 2009-10-29 23:18
|
576
|
+
def resize(ht = 0, w = 0)
|
577
|
+
# update sheight and swidth even if reduced, so that pad doesn't overwrite.
|
578
|
+
@sheight = ht if ht > 0
|
579
|
+
@swidth = w if w > 0
|
580
|
+
return if ht < @padheight and w < @padwidth
|
581
|
+
@padheight = ht if ht > @padheight
|
582
|
+
@padwidth = w if w > @padwidth
|
583
|
+
destroy
|
584
|
+
$log.debug " L502 resize, creating newpad with #{@padheight} and #{@padwidth} "
|
585
|
+
@window = Ncurses.newpad(@padheight, @padwidth)
|
586
|
+
$log.debug " L502 resize created #{@window} "
|
587
|
+
return @window
|
588
|
+
end
|
589
|
+
## used if pad and window are same size only
|
590
|
+
# creates a similar sized window
|
591
|
+
# assumes window is backed by this pad
|
592
|
+
# @param object of Window class
|
593
|
+
def self.create_for_window(win)
|
594
|
+
# get coordinates for win
|
595
|
+
@otherwin = win
|
596
|
+
smaxx = win.getmaxx()
|
597
|
+
smaxy = win.getmaxy()
|
598
|
+
top = win.getminx()
|
599
|
+
left = win.getminy()
|
600
|
+
sheight = win.height
|
601
|
+
swidth = win.width
|
602
|
+
# make pad based on size of window
|
603
|
+
window = Pad.create_with_layout(layout = { :height => sheight, :width => swidth, :top => top, :left => sleft })
|
604
|
+
window.sheight = sheight
|
605
|
+
window.swidth = swidth
|
606
|
+
return window
|
607
|
+
|
608
|
+
end
|
609
|
+
# top and left correspond to screen's top and left wich will mostly be fixed.
|
610
|
+
# In cases where the component may float around, as in Splitpanes second component
|
611
|
+
# this would be set using component's row and col.
|
612
|
+
def set_screen_row_col top, left=-1
|
613
|
+
@top = top
|
614
|
+
@left = left unless left < 0
|
615
|
+
end
|
616
|
+
alias :set_screen_pad_left :set_screen_row_col
|
617
|
+
|
618
|
+
## added user setting screens max row and col (e.g splitpanes first component)
|
619
|
+
def set_screen_max_row_col mr, mc
|
620
|
+
$log.debug "#{@name} set_screen_max_row_col #{mr},#{mc}. earlier #{@screen_maxrow}, #{@screen_maxcol} "
|
621
|
+
# added || check on 2010-01-09 18:39 since crashing if mr > sh + top ..
|
622
|
+
# I removed the check, since it results in a blank area on screen since the
|
623
|
+
# widget has not expanded itself. Without the check it will crash on copywin so you
|
624
|
+
# should increase widget size or disallow calling this in this situation.
|
625
|
+
if mr > (@sheight + @top -1 -@pminrow)
|
626
|
+
$log.warn " ->>> ** set_screen_max_row_col #{mr} > #{@sheight} + #{@top} -1 - #{@pminrow} ** "
|
627
|
+
$log.warn " ->>> can result in error in copy_win or in some rows not displaying"
|
628
|
+
return # some situations actually require this ...
|
629
|
+
end unless mr.nil?
|
630
|
+
@screen_maxrow = mr unless mr.nil? # || mr > (@sheight + @top -1 -@pminrow)
|
631
|
+
@screen_maxcol = mc unless mc.nil?
|
632
|
+
end
|
633
|
+
# start row and col correspond to pad's top and left which will change if scrolling
|
634
|
+
# However, if we use this as a backing store for subwindows it could remain the same
|
635
|
+
def set_pad_top_left top, left=-1
|
636
|
+
$log.debug "#{@name} inside set_pad_top_left to #{top} #{left} earlier #{@pminrow}, #{@pmincol}"
|
637
|
+
@pminrow = top unless top < 0
|
638
|
+
@pmincol = left unless left < 0
|
639
|
+
end
|
640
|
+
# return screen max row which will be used for writing to window
|
641
|
+
# XXX what if user sets/overrides sheight
|
642
|
+
def smaxrow
|
643
|
+
#$log.debug " ... niside smaxrow #{@sheight} + #{@top} -1 "
|
644
|
+
#@sheight + @top -1
|
645
|
+
$log.debug "smr: #{@screen_maxrow} ... niside smaxrow #{@sheight} + #{@top} -1 - #{@pminrow}"
|
646
|
+
@screen_maxrow || @sheight + @top -1 -@pminrow
|
647
|
+
end
|
648
|
+
##
|
649
|
+
# return screen max col which will be used for writing to window
|
650
|
+
def smaxcol
|
651
|
+
#$log.debug " ... niside smaxcol #{@swidth} + #{@left} -1 "
|
652
|
+
#@swidth + @left -1
|
653
|
+
# $log.debug " ... niside smaxcol #{@swidth} + #{@left} -1 - #{@pmincol} "
|
654
|
+
@screen_maxcol || @swidth + @left -1 - @pmincol
|
655
|
+
end
|
656
|
+
##
|
657
|
+
# specify the window or subwin that the pad is writing to
|
658
|
+
# 2010-02-20 22:45 - actually since there are pad methods smaxrow used on otherwin
|
659
|
+
# therefor it can only be a Pad !! NOTE
|
660
|
+
def set_backing_window win
|
661
|
+
@otherwin = win
|
662
|
+
# XX should we extract the coordinates and use for printing ??
|
663
|
+
# or for setting maxrow and maxcol
|
664
|
+
end
|
665
|
+
# trying to make things as easy as possible
|
666
|
+
# returns -1 if error in prefresh
|
667
|
+
def wrefresh
|
668
|
+
$log.debug " inside pad's wrefresh #{@window}. minr,minc,top,left,smaxr,c: #{@pminrow}, #{@pmincol}, #{@top} #{@left} #{smaxrow()} #{smaxcol()} self: #{self.name} "
|
669
|
+
|
670
|
+
# caution, prefresh uses maxrow and maxcol not height and width
|
671
|
+
# so we have to add top and less one since we are zero based
|
672
|
+
ret = @window.prefresh(@pminrow, @pmincol, @top, @left, smaxrow(), smaxcol())
|
673
|
+
$log.warn " WREFRESH returns -1 ERROR - width or height must be exceeding " if ret == -1
|
674
|
+
@modified = false
|
675
|
+
return ret
|
676
|
+
end
|
677
|
+
##
|
678
|
+
# copy the window to the pad (assumes we are writing onto win and keeping
|
679
|
+
# pad as backup
|
680
|
+
# also assuming only one win so, window not passed as param
|
681
|
+
# @return return value of copywin which should be 0 (-1 is ERR)
|
682
|
+
def copy_pad_to_win
|
683
|
+
# check that we don't exceed other windows height/maxrow
|
684
|
+
smr = smaxrow()
|
685
|
+
# SHIT, this means the otherwin has to be a Pad, cannot be a window
|
686
|
+
osw = @otherwin.width
|
687
|
+
osh = @otherwin.height
|
688
|
+
osh = @height if osh == 0 # root window has 0
|
689
|
+
osw = @width if osw == 0 # root window has 0
|
690
|
+
osmr = @otherwin.smaxrow() rescue osh # TRYING for windows
|
691
|
+
osmc = @otherwin.smaxcol() rescue osw
|
692
|
+
if smr >= osmr
|
693
|
+
$log.debug " adjusted smr from #{smr} to #{osmr} -1 causing issues in viewfooter"
|
694
|
+
smr = osmr-1 # XXX causing issues in viewport, wont print footer with this
|
695
|
+
end
|
696
|
+
if smr > @sheight + @top -1 -@pminrow # 2010-01-17 13:27
|
697
|
+
smr = @sheight + @top -1 -@pminrow
|
698
|
+
$log.debug " adjusted smr to #{smr} to prevent crash "
|
699
|
+
end
|
700
|
+
smc = smaxcol()
|
701
|
+
$log.debug " SMC original = #{smc} "
|
702
|
+
if smc >= osmc
|
703
|
+
smc = osmc-1
|
704
|
+
smc = @width # XXX ??? THIS WAS WORKING< but throwing error in viewport case
|
705
|
+
smc = [osmc-1, @width].min # yet another hack
|
706
|
+
$log.debug " SMC o-1 #{osmc-1} wdth #{@width}, smc #{smc} "
|
707
|
+
end
|
708
|
+
### XXX commented out since it doesn't let a comp print fully if widget expanded (splitpane)
|
709
|
+
#smc = osw -1 if smc >= osw; # added 2009-11-02 17:01 for tabbedpanes
|
710
|
+
|
711
|
+
# dang, this is coming up a lot. 2010-01-16 20:34
|
712
|
+
# the second scrollpane was one row too large in testsplit3a.rb
|
713
|
+
if smr - @top > @padheight
|
714
|
+
$log.debug " fixing smr to padheight 2010-01-16 20:35 HOPE THIS DOESNT BREAK ANYTHING"
|
715
|
+
smr = @padheight
|
716
|
+
end
|
717
|
+
@pminrow = 0 if @pminrow < 0
|
718
|
+
@pmincol = 0 if @pmincol < 0
|
719
|
+
$log.debug " COPYING #{self.name} to #{@otherwin.name} "
|
720
|
+
$log.debug " calling copy pad #{@pminrow} #{@pmincol}, #{@top} #{@left}, #{smr} #{smc} self #{self.name} "
|
721
|
+
$log.debug " calling copy pad H: #{@height} W: #{@width}, PH #{@padheight} PW #{@padwidth} WIN:#{@window} "
|
722
|
+
# $log.debug " -otherwin target copy pad #{@otherwin.pminrow} #{@otherwin.pmincol}, #{@otherwin.top} #{@otherwin.left}, #{osmr} #{osmc} OTHERWIN:#{@otherwin.name} "
|
723
|
+
ret="-"
|
724
|
+
#if ret == -1
|
725
|
+
#x XXX $log.debug " #{ret} otherwin copy pad #{@otherwin.pminrow} #{@otherwin.pmincol}, #{@otherwin.top} #{@otherwin.left}, #{osmr} #{osmc} "
|
726
|
+
$log.debug " #{ret} otherwin copy pad H: #{osh} W: #{osw}"
|
727
|
+
if @top >= osh
|
728
|
+
$log.debug " #{ret} ERROR top exceeds other ht #{@top} H: #{osh} "
|
729
|
+
end
|
730
|
+
if @left >= osw
|
731
|
+
$log.debug " #{ret} ERROR left exceeds other wt #{@left} W: #{osw} "
|
732
|
+
end
|
733
|
+
if smr >= osh
|
734
|
+
$log.debug " #{ret} ERROR smrow exceeds other ht #{smr} H: #{osh} "
|
735
|
+
smr = osh() -1 # testing 2010-01-31 21:47 , again 2010-02-05 20:22
|
736
|
+
end
|
737
|
+
if smc >= osw
|
738
|
+
$log.debug " #{ret} ERROR smcol exceeds other wt #{smc} W: #{osw} "
|
739
|
+
end
|
740
|
+
if smc - @left > @padwidth
|
741
|
+
$log.debug " #{ret} ERROR smcol - left exceeds padwidth #{smc}- #{@left} PW: #{@padwidth} "
|
742
|
+
end
|
743
|
+
if smr - @top > @padheight
|
744
|
+
$log.debug " #{ret} ERROR smr - top exceeds padheight #{smr}- #{@top} PH: #{@padheight} "
|
745
|
+
end
|
746
|
+
ret = @window.copywin(@otherwin.get_window,@pminrow,@pmincol, @top, @left, smr, smc, 0)
|
747
|
+
$log.debug " copywin ret #{ret} "
|
748
|
+
# 2010-01-11 19:42 one more cause of -1 coming is that padheight (actual height which never
|
749
|
+
# changes unless pad increases) or padwidth is smaller than area being printed. Solution: increase
|
750
|
+
# buffer by increasing widgets w or h. smc - left should not exceed padwidth. smr-top should not
|
751
|
+
# exceed padheight
|
752
|
+
#end
|
753
|
+
@modified = false
|
754
|
+
return ret
|
755
|
+
end
|
756
|
+
def copy_win_to_pad
|
757
|
+
smr = smaxrow()
|
758
|
+
if smr >= @window.smaxrow()
|
759
|
+
smr = @window.smaxrow()-1
|
760
|
+
end
|
761
|
+
$log.debug " copy_win_to_pad #{@otherwin.name}, #{@window.name}, pminr:#{@pminrow} pminc:#{@pmincol} top:#{@top} left:#{@left} smr:#{smr} "
|
762
|
+
ret = @otherwin.copywin(@window.get_window,@pminrow,@pmincol, @top, @left, smr, smaxcol(), 1)
|
763
|
+
@modified = false
|
764
|
+
return ret
|
765
|
+
end
|
766
|
+
##
|
767
|
+
#Used to overwrite the pad onto the screen window
|
768
|
+
# A window should have been specified as window to back (@see set_backing_window) or (@see create_with_window)
|
769
|
+
def overwrite_window
|
770
|
+
return @window.overwrite(@otherwin.get_window)
|
771
|
+
end
|
772
|
+
|
773
|
+
##
|
774
|
+
# convenience method so that pad can use printstring but remove screen's row and col
|
775
|
+
# The absolute row and col will be taken into consideration when printing on screen.
|
776
|
+
#
|
777
|
+
# @param [Fixnum] row row to print on
|
778
|
+
# @param [Fixnum] col column to print on
|
779
|
+
# @param [String] value to print
|
780
|
+
# @param [Fixnum] color - color combination
|
781
|
+
# @param [Fixnum, nil] attrib defaults to NORMAL
|
782
|
+
|
783
|
+
# Pls remove the raise once the program is working, extra line can slow things down
|
784
|
+
# Keep it on when testing.
|
785
|
+
# If the raise is thrown, it means your object could be positioned higher than it should be,
|
786
|
+
# or at some point you have increased top, without increasing the objects row.
|
787
|
+
def printstring(row,col,value,color,attrib=Ncurses::A_NORMAL)
|
788
|
+
#$log.debug " pad printstring #{row} - #{@top} , #{col} - #{@left} "
|
789
|
+
raise "printstring row < top, pls correct code #{row} #{@top}, #{col} #{@left} " if row < @top or col < @left
|
790
|
+
#$log.warn "printstring row < top, pls correct code #{row} #{@top} " if row < @top
|
791
|
+
super(row - @top, col - @left, value, color, attrib)
|
792
|
+
end # printstring
|
793
|
+
# convenience method so that pad can use print_border but remove screen's row and col
|
794
|
+
# Please note that this requires that buffer have latest top and left.
|
795
|
+
def print_border row, col, height, width, color, att=Ncurses::A_NORMAL
|
796
|
+
$log.debug " pad printborder #{row} - #{@top} , #{col} - #{@left}, #{height} , #{width} "
|
797
|
+
raise "print_border: row < top, pls correct code #{row} #{@top}, #{col} #{@left} " if row < @top or col < @left
|
798
|
+
#$log.warn "print_border: row < top, pls correct code #{row} #{@top} " if row < @top
|
799
|
+
super(row - @top, col - @left, height, width, color, att)
|
800
|
+
end
|
801
|
+
def print_border_only row, col, height, width, color, att=Ncurses::A_NORMAL
|
802
|
+
$log.debug " pad printborder_only #{row} - #{@top} , #{col} - #{@left}, #{height} , #{width} "
|
803
|
+
raise "print_border row < top, pls correct code #{row} #{@top}, #{col} #{@left} " if row < @top or col < @left
|
804
|
+
super(row - @top, col - @left, height, width, color, att)
|
805
|
+
end
|
806
|
+
# use in place of mvwhline if your widget could be using a pad or window
|
807
|
+
def rb_mvwhline row, col, char, width
|
808
|
+
super(row-@top, col-@left, char, width)
|
809
|
+
end
|
810
|
+
# use in place of mvwvline if your widget could be using a pad or window
|
811
|
+
def rb_mvwvline row, col, char, width
|
812
|
+
super(row-@top, col-@left, char, width)
|
813
|
+
end
|
814
|
+
# use in place of mvaddch if your widget could be using a pad or window
|
815
|
+
def rb_mvaddch row, col, char
|
816
|
+
super(row-@top, col-@left, char)
|
817
|
+
end
|
818
|
+
end # class Pad
|
369
819
|
end
|