rbcurse 1.4.0 → 1.4.1.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/NOTES +68 -0
  2. data/README.markdown +73 -330
  3. data/TODO2.txt +2 -2
  4. data/VERSION +1 -1
  5. data/examples/abasiclist.rb +8 -2
  6. data/examples/alpmenu.rb +1 -1
  7. data/examples/app.rb +1 -24
  8. data/examples/appdirtree.rb +1 -1
  9. data/examples/appemail.rb +8 -14
  10. data/examples/appemaillb.rb +2 -2
  11. data/examples/appgcompose.rb +7 -5
  12. data/examples/common/file.rb +40 -0
  13. data/examples/{rmail.rb → common/rmail.rb} +0 -0
  14. data/examples/data/README.markdown +9 -0
  15. data/examples/data/brew.txt +38 -0
  16. data/examples/data/color.2 +37 -0
  17. data/examples/data/gemlist.txt +60 -0
  18. data/examples/data/lotr.txt +12 -0
  19. data/examples/data/ports.txt +136 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/{todocsv.csv → data/todocsv.csv} +0 -0
  22. data/examples/data/unix1.txt +21 -0
  23. data/examples/data/unix2.txt +11 -0
  24. data/examples/dbdemo.rb +49 -14
  25. data/examples/{appgmail.rb → deprecated/appgmail.rb} +1 -1
  26. data/examples/{splitp.rb → deprecated/splitp.rb} +0 -0
  27. data/examples/{testscrolllb.rb → deprecated/testscrolllb.rb} +0 -0
  28. data/examples/{testscrollp.rb → deprecated/testscrollp.rb} +0 -0
  29. data/examples/{testscrollta.rb → deprecated/testscrollta.rb} +0 -0
  30. data/examples/{testscrolltable.rb → deprecated/testscrolltable.rb} +0 -0
  31. data/examples/{testsplit.rb → deprecated/testsplit.rb} +0 -0
  32. data/examples/{testsplit2.rb → deprecated/testsplit2.rb} +0 -0
  33. data/examples/{testsplit3.rb → deprecated/testsplit3.rb} +0 -0
  34. data/examples/{testsplit3_1.rb → deprecated/testsplit3_1.rb} +0 -0
  35. data/examples/{testsplit3a.rb → deprecated/testsplit3a.rb} +0 -0
  36. data/examples/{testsplit3b.rb → deprecated/testsplit3b.rb} +0 -0
  37. data/examples/{testsplitta.rb → deprecated/testsplitta.rb} +0 -0
  38. data/examples/{testsplittv.rb → deprecated/testsplittv.rb} +0 -0
  39. data/examples/{testsplittvv.rb → deprecated/testsplittvv.rb} +0 -0
  40. data/examples/{testtpane.rb → deprecated/testtpane.rb} +0 -0
  41. data/examples/{testtpane2.rb → deprecated/testtpane2.rb} +0 -0
  42. data/examples/{testtpanetable.rb → deprecated/testtpanetable.rb} +0 -0
  43. data/examples/dirtree.rb +17 -7
  44. data/examples/experimental/resultsetdemo.rb +280 -0
  45. data/examples/experimental/testmform.rb +35 -0
  46. data/examples/{testscroller.rb → experimental/testscroller.rb} +1 -19
  47. data/examples/experimental/teststackflow.rb +111 -0
  48. data/examples/menu1.rb +1 -0
  49. data/examples/multispl.rb +4 -4
  50. data/examples/newmessagebox.rb +130 -0
  51. data/examples/newtabbedwindow.rb +100 -0
  52. data/examples/newtesttabp.rb +0 -3
  53. data/examples/qdfilechooser.rb +0 -3
  54. data/examples/rfe.rb +134 -18
  55. data/examples/rfe_renderer.rb +48 -2
  56. data/examples/sqlc.rb +2 -1
  57. data/examples/sqlm.rb +0 -2
  58. data/examples/table1.rb +1 -7
  59. data/examples/term2.rb +4 -1
  60. data/examples/test1.rb +0 -5
  61. data/examples/test2.rb +42 -31
  62. data/examples/testapp2.rb +8 -1
  63. data/examples/testchars.rb +0 -4
  64. data/examples/testcombo.rb +5 -9
  65. data/examples/testkeypress.rb +0 -3
  66. data/examples/testmenu.rb +0 -4
  67. data/examples/testmulticomp.rb +3 -5
  68. data/examples/testmulticontainer.rb +94 -0
  69. data/examples/testtable.rb +0 -5
  70. data/examples/testtabp.rb +16 -18
  71. data/examples/testtodo.rb +1 -5
  72. data/examples/testwsshortcuts.rb +64 -0
  73. data/examples/testwsshortcuts2.rb +126 -0
  74. data/examples/viewtodo.rb +1 -4
  75. data/lib/rbcurse.rb +1 -1
  76. data/lib/rbcurse/app.rb +92 -69
  77. data/lib/rbcurse/applicationheader.rb +46 -6
  78. data/lib/rbcurse/celleditor.rb +1 -9
  79. data/lib/rbcurse/comboboxcellrenderer.rb +0 -4
  80. data/lib/rbcurse/common/ansiparser.rb +117 -0
  81. data/{examples → lib/rbcurse/common}/appmethods.rb +25 -0
  82. data/lib/rbcurse/common/basestack.rb +407 -0
  83. data/lib/rbcurse/common/bordertitle.rb +41 -0
  84. data/lib/rbcurse/common/chunk.rb +177 -0
  85. data/lib/rbcurse/common/colorparser.rb +71 -0
  86. data/lib/rbcurse/common/keydefs.rb +30 -0
  87. data/lib/rbcurse/common/widgetshortcuts.rb +302 -0
  88. data/lib/rbcurse/deprecated/README.markdown +12 -0
  89. data/lib/rbcurse/{rscrollpane.rb → deprecated/rscrollpane.rb} +0 -0
  90. data/lib/rbcurse/{rsplitpane.rb → deprecated/rsplitpane.rb} +0 -0
  91. data/lib/rbcurse/{rsplitpane2.rb → deprecated/rsplitpane2.rb} +0 -0
  92. data/lib/rbcurse/{rviewport.rb → deprecated/rviewport.rb} +0 -0
  93. data/lib/rbcurse/experimental/README.markdown +14 -0
  94. data/lib/rbcurse/experimental/resultsettextview.rb +585 -0
  95. data/lib/rbcurse/experimental/stackflow.rb +478 -0
  96. data/lib/rbcurse/extras/bottomline.rb +85 -16
  97. data/lib/rbcurse/extras/box.rb +58 -0
  98. data/lib/rbcurse/extras/directorylist.rb +1 -1
  99. data/lib/rbcurse/extras/horizlist.rb +203 -0
  100. data/lib/rbcurse/extras/listselectable.rb +8 -0
  101. data/lib/rbcurse/extras/multiform.rb +330 -0
  102. data/lib/rbcurse/extras/multilinelabel.rb +142 -0
  103. data/lib/rbcurse/extras/newmessagebox.rb +328 -0
  104. data/lib/rbcurse/extras/newtabbedpane.rb +612 -0
  105. data/lib/rbcurse/extras/newtabbedwindow.rb +68 -0
  106. data/lib/rbcurse/extras/padreader.rb +189 -0
  107. data/lib/rbcurse/extras/rcomboedit.rb +256 -0
  108. data/lib/rbcurse/extras/resultsetbrowser.rb +281 -0
  109. data/lib/rbcurse/extras/statusline.rb +44 -6
  110. data/lib/rbcurse/extras/tabularwidget.rb +141 -104
  111. data/lib/rbcurse/extras/textpad.rb +516 -0
  112. data/lib/rbcurse/extras/viewer.rb +2 -0
  113. data/lib/rbcurse/io.rb +120 -3
  114. data/lib/rbcurse/listcellrenderer.rb +2 -1
  115. data/lib/rbcurse/listkeys.rb +1 -1
  116. data/lib/rbcurse/listscrollable.rb +72 -7
  117. data/lib/rbcurse/rbasiclistbox.rb +64 -12
  118. data/lib/rbcurse/rchangeevent.rb +0 -1
  119. data/lib/rbcurse/rcombo.rb +54 -59
  120. data/lib/rbcurse/rcommandwindow.rb +46 -10
  121. data/lib/rbcurse/rcontainer.rb +415 -0
  122. data/lib/rbcurse/rdialogs.rb +242 -165
  123. data/lib/rbcurse/rinputdataevent.rb +0 -1
  124. data/lib/rbcurse/rlistbox.rb +19 -9
  125. data/lib/rbcurse/rmessagebox.rb +1 -5
  126. data/lib/rbcurse/rmulticontainer.rb +64 -61
  127. data/lib/rbcurse/rmultitextview.rb +0 -2
  128. data/lib/rbcurse/rpopupmenu.rb +0 -2
  129. data/lib/rbcurse/rscrollform.rb +61 -12
  130. data/lib/rbcurse/rtabbedpane.rb +89 -73
  131. data/lib/rbcurse/rtabbedwindow.rb +53 -211
  132. data/lib/rbcurse/rtable.rb +0 -2
  133. data/lib/rbcurse/rtextarea.rb +14 -14
  134. data/lib/rbcurse/rtextview.rb +165 -50
  135. data/lib/rbcurse/rvimsplit.rb +15 -12
  136. data/lib/rbcurse/rwidget.rb +404 -150
  137. data/lib/rbcurse/table/tablecellrenderer.rb +1 -4
  138. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -3
  139. data/lib/ver/ncurses.rb +1 -9
  140. data/lib/ver/rpad.rb +375 -0
  141. data/lib/ver/window.rb +262 -440
  142. metadata +73 -31
@@ -0,0 +1,41 @@
1
+ # I am moving the common title and border printing stuff into
2
+ # a separate module.
3
+ module BorderTitle
4
+ dsl_accessor :suppress_borders #to_print_borders
5
+ dsl_accessor :border_attrib, :border_color
6
+ dsl_accessor :title #set this on top
7
+ dsl_accessor :title_attrib #bold, reverse, normal
8
+ dsl_accessor :border_attrib, :border_color #
9
+
10
+ def bordertitle_init
11
+ @row_offset = @col_offset = 0 if @suppress_borders
12
+ @internal_width = 1 if @suppress_borders
13
+ end
14
+ # why the dash does it reduce height by one.
15
+ def print_borders
16
+ raise ArgumentError, "Graphic not set" unless @graphic
17
+ width = @width
18
+ height = @height-1
19
+ window = @graphic
20
+ startcol = @col
21
+ startrow = @row
22
+ @color_pair = get_color($datacolor)
23
+ bordercolor = @border_color || @color_pair
24
+ borderatt = @border_attrib || Ncurses::A_NORMAL
25
+ window.print_border startrow, startcol, height, width, bordercolor, borderatt
26
+ print_title
27
+ end
28
+ def print_title
29
+ return unless @title
30
+ raise "#{self} needs width" unless @width
31
+ @color_pair ||= get_color($datacolor) # should we not use this ??? XXX
32
+ #$log.debug " print_title #{@row}, #{@col}, #{@width} "
33
+ # check title.length and truncate if exceeds width
34
+ _title = @title
35
+ if @title.length > @width - 2
36
+ _title = @title[0..@width-2]
37
+ end
38
+ @graphic.printstring( @row, @col+(@width-_title.length)/2, _title, @color_pair, @title_attrib) unless @title.nil?
39
+ end
40
+
41
+ end
@@ -0,0 +1,177 @@
1
+ # ------------------------------------------------------------ #
2
+ # File: chunk.rb
3
+ # Description:
4
+ # Author: rkumar http://github.com/rkumar/rbcurse/
5
+ # Date: 07.11.11 - 12:31
6
+ # Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
7
+ # Last update: use ,,L
8
+ # ------------------------------------------------------------ #
9
+ #
10
+
11
+ module Chunks
12
+ extend self
13
+ class Chunk
14
+
15
+ # color_pair of associated text
16
+ # text to print
17
+ # attribute of associated text
18
+ #attr_accessor :color, :text, :attrib
19
+ attr_reader :chunk
20
+
21
+ def initialize color, text, attrib
22
+ @chunk = [ color, text, attrib ]
23
+ #@color = color
24
+ #@text = text
25
+ #@attrib = attrib
26
+ end
27
+ def color
28
+ @chunk[0]
29
+ end
30
+ def text
31
+ @chunk[1]
32
+ end
33
+ def attrib
34
+ @chunk[2]
35
+ end
36
+ end
37
+
38
+ # consists of an array of chunks and corresponds to a line
39
+ # to be printed.
40
+ class ChunkLine
41
+
42
+ # an array of chunks
43
+ attr_reader :chunks
44
+
45
+ def initialize arr=nil
46
+ @chunks = arr.nil? ? Array.new : arr
47
+ end
48
+ def <<(chunk)
49
+ raise ArgumentError, "Chunk object expected. Received #{chunk.class} " unless chunk.is_a? Chunk
50
+ @chunks << chunk
51
+ end
52
+ alias :add :<<
53
+ def each &block
54
+ @chunks.each &block
55
+ end
56
+
57
+ # returns length of text in chunks
58
+ def row_length
59
+ result = 0
60
+ @chunks.each { |e| result += e.text.length }
61
+ return result
62
+ end
63
+ alias :length :row_length
64
+ alias :size :row_length
65
+
66
+ # return a Chunkline containing only the text for the range requested
67
+ def substring start, size
68
+ end
69
+ end
70
+ class ColorParser
71
+ def initialize cp
72
+ color_parser cp
73
+ @color_pair = $datacolor
74
+ @attrib = FFI::NCurses::A_NORMAL
75
+ @color_array = [:white]
76
+ @bgcolor_array = [:black]
77
+ @attrib_array = [@attrib]
78
+ @color_pair_array = [@color_pair]
79
+ @color = :white
80
+ @bgcolor = :black
81
+ end
82
+ #
83
+ # Takes a formatted string and converts the parsed parts to chunks.
84
+ #
85
+ # @param [String] takes the entire line or string and breaks into an array of chunks
86
+ # @yield chunk if block
87
+ # @return [ChunkLine] # [Array] array of chunks
88
+ # @since 1.4.1 2011-11-3 experimental, can change
89
+ public
90
+ def convert_to_chunk s, colorp=$datacolor, att=FFI::NCurses::A_NORMAL
91
+ #require 'rbcurse/common/chunk'
92
+
93
+ @color_parser ||= get_default_color_parser()
94
+ ## defaults
95
+ color_pair = @color_pair
96
+ attrib = @attrib
97
+ #res = []
98
+ res = ChunkLine.new
99
+ color = @color
100
+ bgcolor = @bgcolor
101
+ # stack the values, so when user issues "/end" we can pop earlier ones
102
+
103
+ @color_parser.parse_format(s) do |p|
104
+ case p
105
+ when Array
106
+ ## got color / attrib info, this starts a new span
107
+
108
+ #color, bgcolor, attrib = *p
109
+ lc, lb, la = *p
110
+ if la
111
+ @attrib = get_attrib la
112
+ end
113
+ if lc || lb
114
+ @color = lc ? lc : @color_array.last
115
+ @bgcolor = lb ? lb : @bgcolor_array.last
116
+ @color_array << @color
117
+ @bgcolor_array << @bgcolor
118
+ @color_pair = get_color($datacolor, @color, @bgcolor)
119
+ end
120
+ @color_pair_array << @color_pair
121
+ @attrib_array << @attrib
122
+ #$log.debug "XXX: CHUNK start #{color_pair} , #{attrib} :: c:#{lc} b:#{lb} "
123
+ #$log.debug "XXX: CHUNK start arr #{@color_pair_array} :: #{@attrib_array} "
124
+
125
+ when :endcolor
126
+
127
+ # end the current (last) span
128
+ @color_pair_array.pop
129
+ @color_pair = @color_pair_array.last
130
+ @attrib_array.pop
131
+ @attrib = @attrib_array.last
132
+ #$log.debug "XXX: CHUNK end #{color_pair} , #{attrib} "
133
+ #$log.debug "XXX: CHUNK end arr #{@color_pair_array} :: #{@attrib_array} "
134
+ when :reset # ansi has this
135
+ # end all previous colors
136
+ @color_pair = $datacolor # @color_pair_array.first
137
+ @color_pair_array = [@color_pair]
138
+ @attrib = FFI::NCurses::A_NORMAL #@attrib_array.first
139
+ @attrib_array = [@attrib]
140
+ @bgcolor_array = [@bgcolor_array.first]
141
+ @color_array = [@color_array.first]
142
+
143
+ when String
144
+
145
+ ## create the chunk
146
+ $log.debug "XXX: CHUNK using on #{p} : #{@color_pair} , #{@attrib} "
147
+
148
+ #chunk = [color_pair, p, attrib]
149
+ chunk = Chunk.new @color_pair, p, @attrib
150
+ if block_given?
151
+ yield chunk
152
+ else
153
+ res << chunk
154
+ end
155
+ end
156
+ end # parse
157
+ return res unless block_given?
158
+ end
159
+ def get_default_color_parser
160
+ require 'rbcurse/common/colorparser'
161
+ @color_parser || DefaultColorParser.new
162
+ end
163
+ # supply with a color parser, if you supplied formatted text
164
+ public
165
+ def color_parser f
166
+ $log.debug "XXX: color_parser setting in CP to #{f} "
167
+ if f == :tmux
168
+ @color_parser = get_default_color_parser()
169
+ elsif f == :ansi
170
+ require 'rbcurse/common/ansiparser'
171
+ @color_parser = AnsiParser.new
172
+ else
173
+ @color_parser = f
174
+ end
175
+ end
176
+ end # class
177
+ end
@@ -0,0 +1,71 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: colorparser.rb
3
+ # Description: Default parse for our tmux format
4
+ # The aim is to be able to specify parsers so different kinds
5
+ # of formatting or documents can be used, such as ANSI formatted
6
+ # manpages.
7
+ # Author: rkumar http://github.com/rkumar/rbcurse/
8
+ # Date: 07.11.11 - 13:17
9
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
10
+ # Last update: use ,,L
11
+ # ----------------------------------------------------------------------------- #
12
+ # == TODO
13
+ # - perhaps we can compile the regexp once and reuse
14
+ #
15
+
16
+ class DefaultColorParser
17
+
18
+ # NOTE: Experimental and minimal
19
+ # parses the formatted string and yields either an array of color, bgcolor and attrib
20
+ # or the text. This will be called by convert_to_chunk.
21
+ #
22
+ # Currently, assumes colors and attributes are correct. No error checking or fancy stuff.
23
+ # s="#[fg=green]hello there#[fg=yellow, bg=black, dim]"
24
+ # @since 1.4.1 2011-11-3 experimental, can change
25
+ # @return [nil] knows nothign about output format.
26
+
27
+ def parse_format s # yields attribs or text
28
+ ## set default colors
29
+ color = :white
30
+ bgcolor = :black
31
+ attrib = FFI::NCurses::A_NORMAL
32
+ text = ""
33
+
34
+ ## split #[...]
35
+ a = s.split /(#\[[^\]]*\])/
36
+ a.each { |e|
37
+ ## process color or attrib portion
38
+ if e[0,2] == "#[" && e[-1] == "]"
39
+ # now resetting 1:20 PM November 3, 2011 , earlier we were carrying over
40
+ color, bgcolor, attrib = nil, nil, nil
41
+ catch(:done) do
42
+ e = e[2..-2]
43
+ ## first split on commas to separate fg, bg and attr
44
+ atts = e.split /\s*,\s*/
45
+ atts.each { |att|
46
+ ## next split on =
47
+ part = att.split /\s*=\s*/
48
+ case part[0]
49
+ when "fg"
50
+ color = part[1]
51
+ when "bg"
52
+ bgcolor = part[1]
53
+ when "/end", "end"
54
+ yield :endcolor if block_given?
55
+ #next
56
+ throw :done
57
+ else
58
+ # attrib
59
+ attrib = part[0]
60
+ end
61
+ }
62
+ yield [color,bgcolor,attrib] if block_given?
63
+ end # catch
64
+ else
65
+ text = e
66
+ yield text if block_given?
67
+ end
68
+ }
69
+ end
70
+
71
+ end
@@ -0,0 +1,30 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: keydefs.rb
3
+ # Description: Some common keys used in app. Earlier part of rwidget.rb
4
+ # Author: rkumar http://github.com/rkumar/rbcurse/
5
+ # Date: 08.11.11 - 14:57
6
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
7
+ # Last update: 08.11.11 - 14:57
8
+ # ----------------------------------------------------------------------------- #
9
+ #
10
+
11
+ # some common definition that we use throughout app. Do not add more, only what is common.
12
+ # I should not have added Sh-F9 and C-left since they are rare, but only to show they exist.
13
+ #
14
+ KEY_TAB = 9
15
+ KEY_F1 = FFI::NCurses::KEY_F1
16
+ KEY_F10 = FFI::NCurses::KEY_F10
17
+ KEY_ENTER = 10 # FFI::NCurses::KEY_ENTER gives 343
18
+ KEY_BTAB = 353 # nc gives same
19
+ KEY_RETURN = 13 # Nc gives 343 for KEY_ENTER
20
+ KEY_DELETE = 330
21
+ KEY_BACKSPACE = KEY_BSPACE = 127 # Nc gives 263 for BACKSPACE
22
+ KEY_CC = 3 # C-c
23
+ KEY_LEFT = FFI::NCurses::KEY_LEFT
24
+ KEY_RIGHT = FFI::NCurses::KEY_RIGHT
25
+ KEY_UP = FFI::NCurses::KEY_UP
26
+ KEY_DOWN = FFI::NCurses::KEY_DOWN
27
+ C_LEFT = 18168
28
+ C_RIGHT = 18167
29
+ S_F9 = 17949126
30
+ META_KEY = 128
@@ -0,0 +1,302 @@
1
+ # ------------------------------------------------------------ #
2
+ # File: widgetshortcuts.rb
3
+ # Description: A common module for shortcuts to create widgets
4
+ # Also, stacks and flows objects
5
+ # Author: rkumar http://github.com/rkumar/rbcurse/
6
+ # Date: 05.11.11 - 15:13
7
+ # Last update: 06.11.11 - 10:57
8
+ # == TODO
9
+ # add multirow comps like textview and textarea, list
10
+ # add blocks that make sense like in app
11
+ # - what if user does not want form attached - app uses useform ot
12
+ # to check for this, if current_object don't add form
13
+ #
14
+ # - usage of _position inside means these shortcuts cannot be reused
15
+ # with other positioning systems, we'll be cut-pasting forever
16
+ #
17
+ # == CHANGES
18
+ # ------------------------------------------------------------ #
19
+ #
20
+
21
+ # what is the real purpose of the shortcuts, is it to avoid putting nil
22
+ # for form there if not required.
23
+ # Or is it positioning, such as in a stack. or just a method ?
24
+ module RubyCurses
25
+ module WidgetShortcuts
26
+ class Ws
27
+ attr_reader :config
28
+ def initialize config={}
29
+ @config = config
30
+ end
31
+ def [](sym)
32
+ @config[sym]
33
+ end
34
+ def []=(sym, val)
35
+ @config[sym] = val
36
+ end
37
+ end
38
+ class WsStack < Ws; end
39
+ class WsFlow < Ws; end
40
+ def widget_shortcuts_init
41
+ @_ws_app_row = @_ws_app_col = 0
42
+ @_ws_active = []
43
+ @_ws_components = []
44
+ @variables = {}
45
+ end
46
+ def field config={}, &block
47
+ w = Field.new nil, config #, &block
48
+ _position w
49
+ if block
50
+ w.bind(:CHANGED, &block)
51
+ end
52
+ return w
53
+ end
54
+ def label config={}, &block
55
+ w = Label.new nil, config, &block
56
+ _position w
57
+ end
58
+ def blank
59
+ label :text => ""
60
+ end
61
+ def line config={}
62
+ #horizontal line TODO
63
+ #row = config[:row] || @app_row
64
+ #width = config[:width] || 20
65
+ #_position config
66
+ #col = config[:col] || 1
67
+ #@color_pair = config[:color_pair] || $datacolor
68
+ #@attrib = config[:attrib] || Ncurses::A_NORMAL
69
+ #@window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)
70
+ #@window.mvwhline( row, col, FFI::NCurses::ACS_HLINE, width)
71
+ #@window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)
72
+ end
73
+ def check config={}, &block
74
+ w = CheckBox.new nil, config #, &block
75
+ _position w
76
+ if block
77
+ w.bind(:PRESS, &block)
78
+ end
79
+ return w
80
+ end
81
+ def button config={}, &block
82
+ w = Button.new nil, config #, &block
83
+ _position w
84
+ if block
85
+ w.bind(:PRESS, &block)
86
+ end
87
+ return w
88
+ end
89
+ def radio config={}, &block
90
+ a = config[:group]
91
+ # should we not check for a nil
92
+ if @variables.has_key? a
93
+ v = @variables[a]
94
+ else
95
+ v = Variable.new
96
+ @variables[a] = v
97
+ end
98
+ config[:variable] = v
99
+ config.delete(:group)
100
+ w = RadioButton.new nil, config #, &block
101
+ _position w
102
+ if block
103
+ w.bind(:PRESS, &block)
104
+ end
105
+ return w
106
+ end
107
+ # editable text area
108
+ def textarea config={}, &block
109
+ require 'rbcurse/rtextarea'
110
+ # TODO confirm events many more
111
+ events = [ :CHANGE, :LEAVE, :ENTER ]
112
+ block_event = events[0]
113
+ #_process_args args, config, block_event, events
114
+ #config[:width] = config[:display_length] unless config.has_key? :width
115
+ # if no width given, expand to flows width
116
+ #config[:width] ||= @stack.last.width if @stack.last
117
+ useform = nil
118
+ #useform = @form if @current_object.empty?
119
+ w = TextArea.new useform, config
120
+ w.width = :expand unless w.width
121
+ w.height ||= 8 # TODO
122
+ _position(w)
123
+ # need to expand to stack's width or flows itemwidth if given
124
+ if block
125
+ w.bind(block_event, &block)
126
+ end
127
+ return w
128
+ end
129
+ def textview config={}, &block
130
+ require 'rbcurse/rtextview'
131
+ events = [ :LEAVE, :ENTER ]
132
+ block_event = events[0]
133
+ #_process_args args, config, block_event, events
134
+ #config[:width] = config[:display_length] unless config.has_key? :width
135
+ # if no width given, expand to flows width
136
+ #config[:width] ||= @stack.last.width if @stack.last
137
+ useform = nil
138
+ #useform = @form if @current_object.empty?
139
+ w = TextView.new useform, config
140
+ w.width = :expand unless w.width
141
+ w.height ||= 8 # TODO
142
+ _position(w)
143
+ # need to expand to stack's width or flows itemwidth if given
144
+ if block
145
+ w.bind(block_event, &block)
146
+ end
147
+ return w
148
+ end
149
+ def _position w
150
+ cur = @_ws_active.last
151
+ # this is outside any stack or flow, so we do the minimal
152
+ # user should specify row and col
153
+ unless cur
154
+ w.row ||= 0
155
+ w.col ||= 0
156
+ $log.debug "XXX: LABEL #{w.row} , #{w.col} "
157
+ w.set_form @form if @form # temporary,, only set if not inside an object FIXME
158
+ if w.width == :expand
159
+ w.width = FFI::NCurses.COLS-0 # or take windows width since this could be in a message box
160
+ end
161
+ if w.height == :expand
162
+ # take from current row, and not zero FIXME
163
+ w.height = FFI::NCurses.LINES-0 # or take windows width since this could be in a message box
164
+ end
165
+ return
166
+ end
167
+ r = cur[:row] || 0
168
+ c = cur[:col] || 0
169
+ w.row = r
170
+ w.col = c
171
+ if cur.is_a? WsStack
172
+ r += w.height || 1
173
+ cur[:row] = r
174
+ else
175
+ wid = cur[:item_width] || w.width || 10
176
+ c += wid + 1
177
+ cur[:col] = c
178
+ end
179
+ if w.width == :expand
180
+ w.width = cur[:width] or raise "Width not known for stack"
181
+ end
182
+ if w.height == :expand
183
+ w.height = cur[:height] or raise "height not known for flow"
184
+ end
185
+ w.color ||= cur[:color]
186
+ w.bgcolor ||= cur[:bgcolor]
187
+ w.set_form @form if @form # temporary
188
+ @_ws_components << w
189
+ cur[:components] << w
190
+ end
191
+ # make it as simple as possible, don't try to be intelligent or
192
+ # clever, put as much on the user
193
+ def stack config={}, &block
194
+ s = WsStack.new config
195
+ _configure s
196
+ @_ws_active << s
197
+ yield_or_eval &block if block_given?
198
+ @_ws_active.pop
199
+
200
+ # ---- stack is finished now
201
+ last = @_ws_active.last
202
+ if last
203
+ case last
204
+ when WsStack
205
+ when WsFlow
206
+ last[:col] += last[:item_width] || 0
207
+ # this tries to set height of outer flow based on highest row
208
+ # printed, however that does not account for height of object,
209
+ # so user should give a height to the flow.
210
+ last[:height] = s[:row] if s[:row] > (last[:height]||0)
211
+ $log.debug "XXX: STACK setting col to #{s[:col]} "
212
+ end
213
+ end
214
+
215
+ end
216
+ #
217
+ # item_width - width to use per item
218
+ # but the item width may apply to stacks inside not to items
219
+ def flow config={}, &block
220
+ s = WsFlow.new config
221
+ _configure s
222
+ @_ws_active << s
223
+ yield_or_eval &block if block_given?
224
+ @_ws_active.pop
225
+ last = @_ws_active.last
226
+ if last
227
+ case last
228
+ when WsStack
229
+ if s[:height]
230
+ last[:row] += s[:height]
231
+ else
232
+ #last[:row] += last[:highest_row]
233
+ last[:row] += 1
234
+ end
235
+ when WsFlow
236
+ last[:col] += last[:item_width] || 0
237
+ end
238
+ end
239
+ end
240
+ # flow and stack could have a border option
241
+ def box config={}, &block
242
+ require 'rbcurse/extras/box'
243
+ # take current stacks row and col
244
+ # advance row by one and col by one
245
+ # at end note row and advance by one
246
+ # draw a box around using these coordinates. width should be
247
+ # provided unless we have item width or something.
248
+ last = @_ws_active.last
249
+ if last
250
+ r = last[:row]
251
+ c = last[:col]
252
+ config[:row] = r
253
+ config[:col] = c
254
+ last[:row] += config[:margin_top] || 1
255
+ last[:col] += config[:margin_left] || 1
256
+ _box = Box.new @form, config # needs to be created first or will overwrite area after others painted
257
+ yield_or_eval &block if block_given?
258
+ h = config[:height] || last[:height] || (last[:row] - r)
259
+ h = 2 if h < 2
260
+ w = config[:width] || last[:width] || 15 # tmp
261
+ case last
262
+ when WsFlow
263
+ w = last[:col]
264
+ when WsStack
265
+ #h += 1
266
+ end
267
+ config[:row] = r
268
+ config[:col] = c
269
+ config[:height] = h
270
+ config[:width] = w
271
+ _box.row r
272
+ _box.col c
273
+ _box.height h
274
+ _box.width w
275
+ last[:row] += 1
276
+ last[:col] += 1 # ??? XXX if flow we need to increment properly or not ?
277
+ end
278
+ end
279
+ def _configure s
280
+ s[:row] ||= 0
281
+ s[:col] ||= 0
282
+ s[:row] += (s[:margin_top] || 0)
283
+ s[:col] += (s[:margin_left] || 0)
284
+ s[:width] = FFI::NCurses.COLS if s[:width] == :expand
285
+ last = @_ws_active.last
286
+ if last
287
+ if last.is_a? WsStack
288
+ s[:row] += (last[:row] || 0)
289
+ s[:col] += (last[:col] || 0)
290
+ else
291
+ s[:row] += (last[:row] || 0)
292
+ s[:col] += (last[:col] || 0) # we are updating with item_width as each st finishes
293
+ s[:width] ||= last[:item_width] #
294
+ end
295
+ end
296
+ s[:components] = []
297
+ end
298
+
299
+
300
+
301
+ end
302
+ end