rbcurse-core 0.0.2 → 0.0.3
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 +8 -0
- data/VERSION +1 -1
- data/examples/abasiclist.rb +1 -0
- data/lib/rbcurse/core/include/action.rb +45 -5
- data/lib/rbcurse/core/include/actionmanager.rb +49 -0
- data/lib/rbcurse/core/include/appmethods.rb +7 -1
- data/lib/rbcurse/core/include/io.rb +27 -8
- data/lib/rbcurse/core/include/listbindings.rb +2 -1
- data/lib/rbcurse/core/include/listscrollable.rb +17 -5
- data/lib/rbcurse/core/include/rhistory.rb +24 -8
- data/lib/rbcurse/core/include/widgetmenu.rb +66 -0
- data/lib/rbcurse/core/system/ncurses.rb +17 -3
- data/lib/rbcurse/core/system/window.rb +18 -5
- data/lib/rbcurse/core/util/app.rb +1 -1
- data/lib/rbcurse/core/util/rdialogs.rb +10 -2
- data/lib/rbcurse/core/util/viewer.rb +1 -1
- data/lib/rbcurse/core/widgets/divider.rb +1 -1
- data/lib/rbcurse/core/widgets/rlist.rb +11 -2
- data/lib/rbcurse/core/widgets/rmessagebox.rb +6 -2
- data/lib/rbcurse/core/widgets/rtextarea.rb +8 -0
- data/lib/rbcurse/core/widgets/rtextview.rb +9 -49
- data/lib/rbcurse/core/widgets/rwidget.rb +64 -44
- data/lib/rbcurse.rb +1 -1
- data/rbcurse-core.gemspec +4 -2
- metadata +6 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
**2012-01-04**
|
2
|
+
## 0.0.3 rbcurse-core
|
3
|
+
* ActionManager added to widgets so actions can be
|
4
|
+
used from multiple places
|
5
|
+
* changes in ncurses setting cbreak and halfdelay etc
|
6
|
+
since C-c was crashing program out
|
7
|
+
* Added history to field
|
8
|
+
|
1
9
|
**2011-12-13**
|
2
10
|
## 0.0.2 rbcurse-core
|
3
11
|
Mostly refactoring of multi-row components
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
data/examples/abasiclist.rb
CHANGED
@@ -34,6 +34,7 @@ require 'rbcurse/core/widgets/rlist'
|
|
34
34
|
# just a simple test to ensure that rbasiclistbox is running inside a container.
|
35
35
|
App.new do
|
36
36
|
def disp_menu
|
37
|
+
# ideally this shuld get action_manager and add_action so these are added to widgets actions
|
37
38
|
f = @form.get_current_field
|
38
39
|
|
39
40
|
if f.name == "lb1"
|
@@ -1,5 +1,21 @@
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
2
|
+
# File: action.rb
|
3
|
+
# Description: A common action class which can be used with buttons, popupmenu
|
4
|
+
# and anythign else that takes an action or command
|
5
|
+
# Author: rkumar http://github.com/rkumar/rbcurse/
|
6
|
+
# Date: been around since the beginning
|
7
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
8
|
+
# Last update: use ,,L
|
9
|
+
# NOTE: I don't like the dependence on rwidget and EventHandler. Seems it needs
|
10
|
+
# that only for fire_handler and not sure if that's used. I've not bound :FIRE
|
11
|
+
# ever.
|
12
|
+
#
|
13
|
+
# Darn, do i really need to have dsl_accessors and property This is not a
|
14
|
+
# widget and there's no repaint. Do button's and popups really repaint
|
15
|
+
# themselves when a dsl_property is modified ?
|
16
|
+
# ----------------------------------------------------------------------------- #
|
17
|
+
#
|
1
18
|
require 'rbcurse/core/widgets/rwidget'
|
2
|
-
#include Ncurses # FFI 2011-09-8
|
3
19
|
include RubyCurses
|
4
20
|
module RubyCurses
|
5
21
|
## encapsulates behaviour allowing centralization
|
@@ -12,8 +28,8 @@ module RubyCurses
|
|
12
28
|
# ...
|
13
29
|
# end
|
14
30
|
class Action < Proc
|
15
|
-
include EventHandler
|
16
|
-
include ConfigSetup
|
31
|
+
include EventHandler # removed 2012-01-3 maybe you can bind FIRE
|
32
|
+
#include ConfigSetup # removed 2012-01-3
|
17
33
|
# name used on button or menu
|
18
34
|
dsl_property :name
|
19
35
|
dsl_property :enabled
|
@@ -27,14 +43,38 @@ module RubyCurses
|
|
27
43
|
@name = name
|
28
44
|
@name.freeze
|
29
45
|
@enabled = true
|
30
|
-
|
46
|
+
# removing dependency from config
|
47
|
+
#config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
|
48
|
+
@config = config
|
49
|
+
keys = @config.keys
|
50
|
+
keys.each do |e|
|
51
|
+
variable_set(e, @config[e])
|
52
|
+
end
|
31
53
|
@_events = [:FIRE]
|
32
54
|
end
|
33
55
|
def call
|
34
56
|
return unless @enabled
|
35
|
-
|
57
|
+
# seems to be here, if you've bound :FIRE no this, not on any widget
|
58
|
+
fire_handler :FIRE, self
|
36
59
|
super
|
37
60
|
end
|
61
|
+
# the next 3 are to adapt this to CMenuitems
|
62
|
+
def hotkey
|
63
|
+
return @mnemonic if @mnemonic
|
64
|
+
ix = @name.index('&')
|
65
|
+
if ix
|
66
|
+
return @name[ix+1, 1].downcase
|
67
|
+
end
|
68
|
+
end
|
69
|
+
# to adapt this to CMenuitems
|
70
|
+
def label
|
71
|
+
@name.sub('&','')
|
72
|
+
end
|
73
|
+
# to adapt this to CMenuitems
|
74
|
+
def action
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
38
78
|
end # class
|
39
79
|
end # module
|
40
80
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
2
|
+
# File: actionmanager.rb
|
3
|
+
# Description: a class that manages actions for a widget
|
4
|
+
#
|
5
|
+
# Author: rkumar http://github.com/rkumar/rbcurse/
|
6
|
+
# Date: 2012-01-4
|
7
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
8
|
+
# Last update: ,,L
|
9
|
+
# ----------------------------------------------------------------------------- #
|
10
|
+
#
|
11
|
+
# Maintains actions for a widget
|
12
|
+
module RubyCurses
|
13
|
+
class ActionManager
|
14
|
+
include Io
|
15
|
+
attr_reader :actions
|
16
|
+
|
17
|
+
def initialize #form, config={}, &block
|
18
|
+
@actions = []
|
19
|
+
#instance_eval &block if block_given?
|
20
|
+
end
|
21
|
+
def add_action act
|
22
|
+
@actions << act
|
23
|
+
end
|
24
|
+
def remove_action act
|
25
|
+
@actions.remove act
|
26
|
+
end
|
27
|
+
#
|
28
|
+
# insert an item at given position (index)
|
29
|
+
def insert_action pos, *val
|
30
|
+
@actions[pos] = val
|
31
|
+
end
|
32
|
+
#def create_menuitem *args
|
33
|
+
#PromptMenu.create_menuitem *args
|
34
|
+
#end
|
35
|
+
|
36
|
+
# popup the hist
|
37
|
+
#
|
38
|
+
def show_actions
|
39
|
+
return if @actions.empty?
|
40
|
+
list = @actions
|
41
|
+
menu = PromptMenu.new self do |m|
|
42
|
+
list.each { |e|
|
43
|
+
m.add *e
|
44
|
+
}
|
45
|
+
end
|
46
|
+
menu.display_new :title => 'Widget Menu (Press letter)'
|
47
|
+
end
|
48
|
+
end # class
|
49
|
+
end # mod RubyC
|
@@ -78,9 +78,15 @@ module RubyCurses
|
|
78
78
|
# prompts user for unix command and displays output in viewer
|
79
79
|
#
|
80
80
|
def shell_output
|
81
|
-
|
81
|
+
$shell_history ||= []
|
82
|
+
cmd = get_string("Enter shell command:", :maxlen => 50) do |f|
|
83
|
+
require 'rbcurse/core/include/rhistory'
|
84
|
+
f.extend(FieldHistory)
|
85
|
+
f.history($shell_history)
|
86
|
+
end
|
82
87
|
if cmd && !cmd.empty?
|
83
88
|
run_command cmd
|
89
|
+
$shell_history.push(cmd) unless $shell_history.include? cmd
|
84
90
|
end
|
85
91
|
end
|
86
92
|
|
@@ -314,7 +314,7 @@ module Io
|
|
314
314
|
@caller = caller
|
315
315
|
@text = text
|
316
316
|
@options = []
|
317
|
-
|
317
|
+
yield_or_eval &block if block_given?
|
318
318
|
end
|
319
319
|
def add *menuitem
|
320
320
|
item = nil
|
@@ -330,6 +330,14 @@ module Io
|
|
330
330
|
# if user only sends key and symbol
|
331
331
|
menuitem[3] = menuitem[1]
|
332
332
|
item = CMenuItem.new(*menuitem.flatten)
|
333
|
+
when 1
|
334
|
+
if menuitem.first.is_a? Action
|
335
|
+
item = menuitem.first
|
336
|
+
else
|
337
|
+
raise ArgumentError, "Don't know how to handle #{menuitem.size} : #{menuitem} "
|
338
|
+
end
|
339
|
+
else
|
340
|
+
raise ArgumentError, "Don't know how to handle #{menuitem.size} : #{menuitem} "
|
333
341
|
end
|
334
342
|
@options << item
|
335
343
|
end
|
@@ -339,6 +347,10 @@ module Io
|
|
339
347
|
def create_mitem *args
|
340
348
|
item = CMenuItem.new(*args.flatten)
|
341
349
|
end
|
350
|
+
# Added this, since actually it could have been like this 2011-12-22
|
351
|
+
def self.create_menuitem *args
|
352
|
+
item = CMenuItem.new(*args.flatten)
|
353
|
+
end
|
342
354
|
# create the whole thing using a MenuTree which has minimal information.
|
343
355
|
# It uses a hotkey and a code only. We are supposed to resolve the display text
|
344
356
|
# and actual proc from the caller using this code.
|
@@ -369,7 +381,7 @@ module Io
|
|
369
381
|
def display_columns config={}
|
370
382
|
prompt = config[:prompt] || "Choose: "
|
371
383
|
require 'rbcurse/core/util/rcommandwindow'
|
372
|
-
layout = { :height => 5, :width => Ncurses.COLS-
|
384
|
+
layout = { :height => 5, :width => Ncurses.COLS-0, :top => Ncurses.LINES-6, :left => 0 }
|
373
385
|
rc = CommandWindow.new nil, :layout => layout, :box => true, :title => config[:title] || "Menu"
|
374
386
|
w = rc.window
|
375
387
|
r = 4
|
@@ -385,7 +397,11 @@ module Io
|
|
385
397
|
valid = []
|
386
398
|
labels = []
|
387
399
|
menu.each{ |item|
|
388
|
-
|
400
|
+
if item.respond_to? :hotkey
|
401
|
+
hk = item.hotkey.to_s
|
402
|
+
else
|
403
|
+
raise ArgumentError, "Promptmenu needs hotkey or mnemonic"
|
404
|
+
end
|
389
405
|
labels << "%c. %s " % [ hk, item.label ]
|
390
406
|
h[hk] = item
|
391
407
|
valid << hk
|
@@ -413,11 +429,14 @@ module Io
|
|
413
429
|
end
|
414
430
|
#$log.debug " index is #{index} "
|
415
431
|
item = h[ch]
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
432
|
+
# I don;t think this even shows now, its useless
|
433
|
+
if item.respond_to? :desc
|
434
|
+
desc = item.desc
|
435
|
+
#desc ||= "Could not find desc for #{ch} "
|
436
|
+
desc ||= ""
|
437
|
+
clear_this w, r, c, color, len
|
438
|
+
print_this(w, desc, color, r,c)
|
439
|
+
end
|
421
440
|
action = item.action
|
422
441
|
case action
|
423
442
|
#when Array
|
@@ -17,7 +17,8 @@ module RubyCurses
|
|
17
17
|
$log.debug "XXX: INSIDE LISTBINDING FOR #{self.class} "
|
18
18
|
bind_key(Ncurses::KEY_LEFT, 'cursor backward'){ cursor_backward } if respond_to? :cursor_backward
|
19
19
|
bind_key(Ncurses::KEY_RIGHT, 'cursor_forward'){ cursor_forward } if respond_to? :cursor_forward
|
20
|
-
|
20
|
+
# very irritating when user pressed up arrow, commented off 2012-01-4 can be made optional
|
21
|
+
bind_key(Ncurses::KEY_UP, 'previous row'){ ret = up; } #get_window.ungetch(KEY_BTAB) if ret == :NO_PREVIOUS_ROW }
|
21
22
|
# the next was irritating if user wanted to add a row ! 2011-10-10
|
22
23
|
#bind_key(Ncurses::KEY_DOWN){ ret = down ; get_window.ungetch(KEY_TAB) if ret == :NO_NEXT_ROW }
|
23
24
|
bind_key(Ncurses::KEY_DOWN, 'next row'){ ret = down ; }
|
@@ -271,12 +271,20 @@ module ListScrollable
|
|
271
271
|
end
|
272
272
|
def ask_search
|
273
273
|
options = ["Search backwards", "case insensitive", "Wrap around"]
|
274
|
-
defaults = [@search_direction_prev
|
274
|
+
defaults = [@search_direction_prev, @search_case, @search_wrap]
|
275
275
|
regex = @last_regex || ""
|
276
|
+
# persist search history so one can popup and see
|
277
|
+
# How does user know that there is some history here.
|
278
|
+
$list_search_history ||= []
|
279
|
+
$list_search_history << @last_regex if @last_regex && !$list_search_history.include?(@last_regex)
|
276
280
|
|
277
281
|
mb = MessageBox.new :title => "Search" , :width => 70 do
|
278
|
-
|
279
|
-
:bgcolor => :cyan
|
282
|
+
fld = Field.new :label => 'Enter regex to search', :name => "patt", :display_length => 30,
|
283
|
+
:bgcolor => :cyan #, :text => regex
|
284
|
+
require 'rbcurse/core/include/rhistory'
|
285
|
+
fld.extend(FieldHistory)
|
286
|
+
fld.history($list_search_history)
|
287
|
+
add fld
|
280
288
|
add CheckBox.new :text => options[0], :value => defaults[0], :name => "0"
|
281
289
|
add CheckBox.new :text => options[1], :value => defaults[1], :name => "1"
|
282
290
|
add CheckBox.new :text => options[2], :value => defaults[2], :name => "2"
|
@@ -285,7 +293,10 @@ module ListScrollable
|
|
285
293
|
end
|
286
294
|
index = mb.run
|
287
295
|
return if index != 0
|
288
|
-
regex = mb.widget("patt").text
|
296
|
+
regex = mb.widget("patt").text || regex # if user enters nothing use existing regex
|
297
|
+
regex = @last_regex if regex == ""
|
298
|
+
return if regex.nil? || regex == ""
|
299
|
+
#$list_search_history << @last_regex if @last_regex
|
289
300
|
@search_direction_prev = mb.widget("0").value
|
290
301
|
@search_case = mb.widget("1").value
|
291
302
|
@search_wrap = mb.widget("2").value
|
@@ -391,7 +402,8 @@ module ListScrollable
|
|
391
402
|
##
|
392
403
|
# find backwards
|
393
404
|
# Using this to start a search or continue search
|
394
|
-
def _find_prev regex=@last_regex, start = @search_found_ix
|
405
|
+
def _find_prev regex=@last_regex, start = @search_found_ix, first_time = false
|
406
|
+
#TODO the firsttime part, see find_next
|
395
407
|
#raise "No previous search" if regex.nil?
|
396
408
|
warn "No previous search" and return if regex.nil?
|
397
409
|
#$log.debug " _find_prev #{@search_found_ix} : #{@current_index}"
|
@@ -20,16 +20,29 @@
|
|
20
20
|
module RubyCurses
|
21
21
|
extend self
|
22
22
|
module FieldHistory
|
23
|
+
def self.extended(obj)
|
24
|
+
|
25
|
+
obj.instance_exec {
|
26
|
+
@history ||= []
|
27
|
+
$history_key ||= ?\M-h
|
28
|
+
# ensure that the field is not overriding this in handle_key
|
29
|
+
bind_key($history_key) { _show_history }
|
30
|
+
# widget should have CHANGED event, or this will either give error, or just not work
|
31
|
+
# else please update history whenever you want a value to be retrieved
|
32
|
+
bind(:CHANGED) { @history << @text if @text && (!@history.include? @text) }
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
23
36
|
# pass the array of history values
|
37
|
+
# Trying out a change where an item can also be sent in.
|
38
|
+
# I am lost, i want the initialization to happen once.
|
24
39
|
def history arr
|
25
40
|
return @history unless arr
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# else please update history whenever you want a value to be retrieved
|
32
|
-
bind(:CHANGED) { @history << @text if @text && (!@history.include? @text) }
|
41
|
+
if arr.is_a? Array
|
42
|
+
@history = arr
|
43
|
+
else
|
44
|
+
@history << arr unless @history.include? arr
|
45
|
+
end
|
33
46
|
end
|
34
47
|
def history=(x); history(x); end
|
35
48
|
|
@@ -50,7 +63,9 @@ module RubyCurses
|
|
50
63
|
raise ArgumentError, "show_history got nil list" unless list
|
51
64
|
# calculate r and c
|
52
65
|
# col if fine, except for when there's a label.
|
53
|
-
|
66
|
+
wcol = 0 # taking care of when dialog uses history 2012-01-4
|
67
|
+
wcol = self.form.window.left if self.form
|
68
|
+
c = wcol + ( @field_col || @col) # this is also dependent on window coords, as in a status_window or messagebox
|
54
69
|
sz = @history.size
|
55
70
|
wrow = 0
|
56
71
|
wrow = self.form.window.top if self.form
|
@@ -67,6 +82,7 @@ module RubyCurses
|
|
67
82
|
#r = @row + 1
|
68
83
|
#end
|
69
84
|
r = @_history_config[:row] || r
|
85
|
+
c = @_history_config[:col] || c
|
70
86
|
ret = popuplist(list, :row => r, :col => c, :title => " History ")
|
71
87
|
if ret
|
72
88
|
self.text = list[ret]
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# ----------------------------------------------------------------------------- #
|
2
|
+
# File: widgetmenu.rb
|
3
|
+
# Description: a module that displays a menu for customization of a field
|
4
|
+
# e.g.,
|
5
|
+
# field.extend(WidgetMenu)
|
6
|
+
#
|
7
|
+
# Author: rkumar http://github.com/rkumar/rbcurse/
|
8
|
+
# Date: 2011-12-2x
|
9
|
+
# License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
10
|
+
# Last update: 2011-12-26 - 20:25
|
11
|
+
# ----------------------------------------------------------------------------- #
|
12
|
+
#
|
13
|
+
# Provide a system for us to define a menu for customizing a widget, such that
|
14
|
+
# applicatin can also add more menuitems
|
15
|
+
module RubyCurses
|
16
|
+
extend self
|
17
|
+
module WidgetMenu
|
18
|
+
include Io # added 2011-12-26
|
19
|
+
# add a menu item which can any one of
|
20
|
+
# @param key, label, desc, action | symbol
|
21
|
+
# key, symbol
|
22
|
+
# Action
|
23
|
+
# Action[] (maybe)
|
24
|
+
def self.extended(obj)
|
25
|
+
# don't want this executed each time
|
26
|
+
@objects ||= []
|
27
|
+
return if @objects.include? obj
|
28
|
+
@objects << obj
|
29
|
+
|
30
|
+
obj.instance_exec {
|
31
|
+
@_menuitems ||= []
|
32
|
+
# callign this method means that no other programs can use those actions else
|
33
|
+
# that method will be called more than once, so it must either be called in the constructor
|
34
|
+
# or else have a check that it is only called once.
|
35
|
+
obj.init_menu if obj.respond_to? :init_menu
|
36
|
+
}
|
37
|
+
|
38
|
+
end
|
39
|
+
def add_menu_item *val
|
40
|
+
#@_menuitems ||= []
|
41
|
+
@_menuitems << val
|
42
|
+
end
|
43
|
+
#
|
44
|
+
# insert an item at given position (index)
|
45
|
+
def insert_menu_item pos, *val
|
46
|
+
#@_menuitems ||= []
|
47
|
+
@_menuitems[pos] = val
|
48
|
+
end
|
49
|
+
def create_menuitem *args
|
50
|
+
PromptMenu.create_menuitem *args
|
51
|
+
end
|
52
|
+
|
53
|
+
# popup the hist
|
54
|
+
#
|
55
|
+
def _show_menu
|
56
|
+
return if @_menuitems.nil? || @_menuitems.empty?
|
57
|
+
list = @_menuitems
|
58
|
+
menu = PromptMenu.new self do |m|
|
59
|
+
list.each { |e|
|
60
|
+
m.add *e
|
61
|
+
}
|
62
|
+
end
|
63
|
+
menu.display_new :title => 'Widget Menu (Press letter)'
|
64
|
+
end
|
65
|
+
end # mod History
|
66
|
+
end # mod RubyC
|
@@ -7,6 +7,11 @@ module VER
|
|
7
7
|
def start_ncurses
|
8
8
|
return if $ncurses_started
|
9
9
|
$ncurses_started = true
|
10
|
+
# in case we want a blocking getch, you may want to first
|
11
|
+
# set wtimeout to -1, and then reset it to this value.
|
12
|
+
# Please first check that we are using this.
|
13
|
+
$ncurses_wtimeout = 500 # used by windows for timeout of wgetch
|
14
|
+
|
10
15
|
# The initscr code determines the terminal type and initializes all curses
|
11
16
|
# data structures.
|
12
17
|
# initscr also causes the first call to refresh to clear the screen.
|
@@ -59,7 +64,9 @@ module VER
|
|
59
64
|
# erase/kill character-processing (interrupt and flow control characters
|
60
65
|
# are unaffected), making characters typed by the user immediately
|
61
66
|
# available to the program.
|
62
|
-
Ncurses.cbreak
|
67
|
+
#Ncurses.cbreak
|
68
|
+
# I have removed cbreak and halfdelay since they were causing C-c
|
69
|
+
# to crash if i pressed it in succession
|
63
70
|
|
64
71
|
# The echo and noecho routines control whether characters typed by the user
|
65
72
|
# are echoed by getch as they are typed.
|
@@ -80,12 +87,19 @@ module VER
|
|
80
87
|
# nothing has been typed.
|
81
88
|
# The value of tenths must be a number between 1 and 255.
|
82
89
|
# Use nocbreak to leave half-delay mode.
|
83
|
-
Ncurses::halfdelay(tenths = 10)
|
90
|
+
#Ncurses::halfdelay(tenths = 10)
|
91
|
+
# See above why switched off
|
84
92
|
|
85
93
|
# The nodelay option causes getch to be a non-blocking call. If no input is
|
86
94
|
# ready, getch returns ERR. If disabled (bf is FALSE), getch waits until a
|
87
95
|
# key is pressed.
|
88
|
-
#
|
96
|
+
# I am using the next line for the window when creating, this does not
|
97
|
+
# have any impact on window.
|
98
|
+
# For this to have any effect your getch should be Ncurses.getch and not
|
99
|
+
# wgetch(@window), For that do this with window.
|
100
|
+
# I am disableing this 2011-12-20 since it does not work with combinations
|
101
|
+
# such as gg. Any routine that does a getch will just immediatelt return an ERR.
|
102
|
+
#Ncurses::nodelay(stdscr.pointer, bf = true)
|
89
103
|
end
|
90
104
|
|
91
105
|
# this should happen only in outermost program that started ncurses
|
@@ -71,6 +71,7 @@ module VER
|
|
71
71
|
$status_message ||= RubyCurses::Variable.new # in case not an App
|
72
72
|
|
73
73
|
$key_map ||= :vim
|
74
|
+
$esc_esc = true; # gove me double esc as 2727 so i can map it.
|
74
75
|
init_vars
|
75
76
|
|
76
77
|
|
@@ -78,6 +79,11 @@ module VER
|
|
78
79
|
def init_vars
|
79
80
|
@window_type = :WINDOW
|
80
81
|
Ncurses::keypad(@window, true)
|
82
|
+
# Added this so we can get Esc, and also C-c pressed in succession does not crash system
|
83
|
+
# 2011-12-20 half-delay crashes system as does cbreak
|
84
|
+
#This causes us to be unable to process gg qq since getch won't wait.
|
85
|
+
#Ncurses::nodelay(@window, bf = true)
|
86
|
+
Ncurses::wtimeout(@window, $ncurses_timeout || 500) # will wait a second on wgetch so we can get gg and qq
|
81
87
|
@stack = []
|
82
88
|
@name ||="#{self}"
|
83
89
|
@modified = true
|
@@ -327,11 +333,17 @@ module VER
|
|
327
333
|
|
328
334
|
def getch
|
329
335
|
#c = @window.getch
|
330
|
-
c =
|
336
|
+
c = FFI::NCurses.wgetch(@window)
|
337
|
+
# 2011-12-20 - i am trying setting a timer on wgetch, see timeout
|
338
|
+
#c = FFI::NCurses.getch # this will keep waiting, nodelay won't be used on it, since
|
339
|
+
# we've put nodelay on window
|
331
340
|
#if c == Ncurses::KEY_RESIZE
|
332
341
|
|
333
|
-
rescue Interrupt
|
342
|
+
rescue SystemExit, Interrupt
|
343
|
+
#FFI::NCurses.flushinp
|
334
344
|
3 # is C-c
|
345
|
+
rescue StandardError
|
346
|
+
-1 # is C-c
|
335
347
|
end
|
336
348
|
|
337
349
|
# 2011-09-23 @since 1.3.1
|
@@ -352,8 +364,8 @@ module VER
|
|
352
364
|
# 2 cases, so abandoned.
|
353
365
|
def getchar
|
354
366
|
while 1
|
355
|
-
ch = getch
|
356
|
-
|
367
|
+
ch = self.getch
|
368
|
+
#$log.debug "window getchar() GOT: #{ch}" if ch != -1
|
357
369
|
sf = @stack.first
|
358
370
|
if ch == -1
|
359
371
|
# the returns escape 27 if no key followed it, so its SLOW if you want only esc
|
@@ -393,7 +405,8 @@ module VER
|
|
393
405
|
# experimental. 2 escapes in quick succession to make exit faster
|
394
406
|
if @stack.size == 1 && ch == 27
|
395
407
|
@stack.clear
|
396
|
-
return
|
408
|
+
return 2727 if $esc_esc # this is double-esc if you wanna trap it, trying out
|
409
|
+
return 27
|
397
410
|
end
|
398
411
|
# possible F1..F3 on xterm-color
|
399
412
|
if ch == 79 || ch == 91
|
@@ -166,7 +166,7 @@ module RubyCurses
|
|
166
166
|
@form.handle_key ch
|
167
167
|
rescue => err
|
168
168
|
$log.debug( "handle_key rescue reached ")
|
169
|
-
$log.debug( err)
|
169
|
+
$log.debug( err.to_s)
|
170
170
|
$log.debug(err.backtrace.join("\n"))
|
171
171
|
textdialog [err.to_s, *err.backtrace], :title => "Exception"
|
172
172
|
end
|
@@ -43,7 +43,12 @@ end
|
|
43
43
|
# Alert user with a block of text. This will popup a textview in which the user can scroll
|
44
44
|
# Use this if you are not sure of the size of the text, such as printing a stack trace,
|
45
45
|
# exception
|
46
|
+
# 2011-12-25 just pass in an exceptino object and we do the rest
|
46
47
|
def textdialog mess, config={}
|
48
|
+
if mess.is_a? Exception
|
49
|
+
mess = [mess.to_s, *mess.backtrace]
|
50
|
+
config[:title] ||= "Exception"
|
51
|
+
end
|
47
52
|
config[:title] ||= "Alert"
|
48
53
|
tp = MessageBox.new config do
|
49
54
|
button_type :ok
|
@@ -81,8 +86,8 @@ def get_string label, config={} # yield Field
|
|
81
86
|
defwid = config[:default].nil? ? 30 : config[:default].size + 13
|
82
87
|
w = [label.size + 8, defwid, field_config[:width]+13 ].max
|
83
88
|
config[:width] ||= w
|
84
|
-
|
85
|
-
|
89
|
+
#$log.debug "XXX: FIELD SIZE #{w} "
|
90
|
+
#$log.debug "XXX: FIELD CONFIG #{field_config} "
|
86
91
|
tp = MessageBox.new config do
|
87
92
|
button_type :ok_cancel
|
88
93
|
default_button 0
|
@@ -373,6 +378,9 @@ def popuplist list, config={}, &block
|
|
373
378
|
end
|
374
379
|
config.delete :relative_to
|
375
380
|
width = config[:width] || longest_in_list(list)+2 # borders take 2
|
381
|
+
if config[:title]
|
382
|
+
width = config[:title].size + 2 if width < config[:title].size
|
383
|
+
end
|
376
384
|
height = config[:height]
|
377
385
|
height ||= [max_visible_items || 10+2, list.length+2].min
|
378
386
|
#layout(1+height, width+4, row, col)
|
@@ -89,7 +89,7 @@ module RubyCurses
|
|
89
89
|
# allow closing using q and Ctrl-q in addition to any key specified
|
90
90
|
# user should not need to specify key, since that becomes inconsistent across usages
|
91
91
|
while((ch = v_window.getchar()) != ?\C-q.getbyte(0) )
|
92
|
-
break if ch == config[:close_key] || ch == ?q.ord
|
92
|
+
break if ch == config[:close_key] || ch == ?q.ord || ch == 2727 # added double esc 2011-12-27
|
93
93
|
# if you've asked for ENTER then i also check for 10 and 13
|
94
94
|
break if (ch == 10 || ch == 13) && config[:close_key] == KEY_ENTER
|
95
95
|
v_form.handle_key ch
|
@@ -129,7 +129,7 @@ module RubyCurses
|
|
129
129
|
|
130
130
|
# first print a right side vertical line
|
131
131
|
#bc = $bottomcolor # dark blue
|
132
|
-
bc = $datacolor
|
132
|
+
bc = get_color($datacolor, :cyan, :black)
|
133
133
|
bordercolor = @border_color || bc
|
134
134
|
borderatt = @border_attrib || Ncurses::A_REVERSE
|
135
135
|
if @focussed
|
@@ -50,6 +50,7 @@ module RubyCurses
|
|
50
50
|
#dsl_accessor :default_values # array of default values
|
51
51
|
#dsl_accessor :is_popup # if it is in a popup and single select, selection closes
|
52
52
|
attr_accessor :current_index
|
53
|
+
# selection mode multiple, single and none (none added 2011-12-26)
|
53
54
|
dsl_accessor :selection_mode
|
54
55
|
dsl_accessor :selected_color, :selected_bgcolor, :selected_attr
|
55
56
|
dsl_accessor :max_visible_items # how many to display 2009-01-11 16:15
|
@@ -96,11 +97,11 @@ module RubyCurses
|
|
96
97
|
@row_offset = @col_offset = 1
|
97
98
|
@should_show_focus = true # Here's its on since the cellrenderer will show it on repaint
|
98
99
|
@one_key_selection = false # use vim keys
|
100
|
+
@selection_mode = :multiple # default is multiple, anything else given becomes single
|
99
101
|
super
|
100
102
|
@_events.push(*[:ENTER_ROW, :LEAVE_ROW, :LIST_SELECTION_EVENT, :PRESS])
|
101
103
|
# I have moved this here so user can override keys.
|
102
104
|
map_keys unless @keys_mapped
|
103
|
-
@selection_mode ||= :multiple # default is multiple, anything else given becomes single
|
104
105
|
@win = @graphic # 2010-01-04 12:36 BUFFERED replace form.window with graphic
|
105
106
|
@win_left = 0
|
106
107
|
@win_top = 0
|
@@ -113,6 +114,7 @@ module RubyCurses
|
|
113
114
|
if @list && !@selected_index.nil? # XXX
|
114
115
|
set_focus_on @selected_index # the new version
|
115
116
|
end
|
117
|
+
init_actions
|
116
118
|
end
|
117
119
|
# this is called several times, from constructor
|
118
120
|
# and when list data changed, so only put relevant resets here.
|
@@ -138,7 +140,7 @@ module RubyCurses
|
|
138
140
|
bind_key(?f, 'next row starting with char'){ ask_selection_for_char() }
|
139
141
|
bind_key(?\M-v, 'toggle one_key_selection'){ @one_key_selection = !@one_key_selection }
|
140
142
|
bind_key(13, 'fire action event'){ fire_action_event }
|
141
|
-
list_bindings # listselectable
|
143
|
+
list_bindings unless @selection_mode == :none # listselectable
|
142
144
|
@keys_mapped = true
|
143
145
|
|
144
146
|
end
|
@@ -670,6 +672,13 @@ module RubyCurses
|
|
670
672
|
end
|
671
673
|
alias :selected_values :get_selected_values
|
672
674
|
|
675
|
+
# Define actions that can be popped up by PromptMenu or other menubar
|
676
|
+
# Currently, only PromptMenu, but we can start contextually appending to Menubar or others
|
677
|
+
def init_actions
|
678
|
+
am = action_manager()
|
679
|
+
am.add_action(Action.new("&Disable selection") { @selection_mode = :none; unbind_key(32); bind_key(32, :scroll_forward); } )
|
680
|
+
am.add_action(Action.new("&Edit Toggle") { @edit_toggle = !@edit_toggle; $status_message.value = "Edit toggle is #{@edit_toggle}" })
|
681
|
+
end
|
673
682
|
|
674
683
|
|
675
684
|
# ADD HERE
|
@@ -65,7 +65,8 @@ module RubyCurses
|
|
65
65
|
@bgcolor ||= :white
|
66
66
|
@maxrow = 3
|
67
67
|
|
68
|
-
instance_eval &block if block_given?
|
68
|
+
#instance_eval &block if block_given?
|
69
|
+
yield_or_eval &block if block_given?
|
69
70
|
|
70
71
|
end
|
71
72
|
def item widget
|
@@ -163,6 +164,7 @@ module RubyCurses
|
|
163
164
|
@maxrow = 3
|
164
165
|
yield message_label if block_given?
|
165
166
|
end
|
167
|
+
alias :message= :message
|
166
168
|
|
167
169
|
# This is for larger messages, or messages where the size is not known.
|
168
170
|
# A textview object is created and yielded.
|
@@ -214,13 +216,15 @@ module RubyCurses
|
|
214
216
|
yield message_label if block_given?
|
215
217
|
|
216
218
|
end
|
219
|
+
alias :text= :text
|
220
|
+
|
217
221
|
# returns button index (or in some cases, whatever value was thrown
|
218
222
|
# if user did not specify any button_type but gave his own and did throw (:close, x)
|
219
223
|
private
|
220
224
|
def handle_keys
|
221
225
|
buttonindex = catch(:close) do
|
222
226
|
while((ch = @window.getchar()) != FFI::NCurses::KEY_F10 )
|
223
|
-
break if ch == ?\C-q.getbyte(0)
|
227
|
+
break if ch == ?\C-q.getbyte(0) || ch == 2727 # added double esc
|
224
228
|
begin
|
225
229
|
@form.handle_key(ch)
|
226
230
|
@window.wrefresh
|
@@ -74,6 +74,7 @@ module RubyCurses
|
|
74
74
|
install_keys
|
75
75
|
init_vars
|
76
76
|
bordertitle_init
|
77
|
+
init_actions
|
77
78
|
end
|
78
79
|
def init_vars
|
79
80
|
@repaint_required = true
|
@@ -945,6 +946,13 @@ module RubyCurses
|
|
945
946
|
}
|
946
947
|
rb_puts "#{name} written."
|
947
948
|
end
|
949
|
+
|
950
|
+
def init_actions
|
951
|
+
editor = ENV['EDITOR'] || 'vi'
|
952
|
+
am = action_manager()
|
953
|
+
am.add_action(Action.new("&Edit in #{editor} ") { edit_external })
|
954
|
+
am.add_action(Action.new("&Saveas") { saveas() } )
|
955
|
+
end
|
948
956
|
end # class textarea
|
949
957
|
##
|
950
958
|
end # modul
|
@@ -64,6 +64,7 @@ module RubyCurses
|
|
64
64
|
install_keys # do something about this nonsense FIXME
|
65
65
|
bordertitle_init
|
66
66
|
init_vars
|
67
|
+
init_actions
|
67
68
|
end
|
68
69
|
def init_vars #:nodoc:
|
69
70
|
@curpos = @pcol = @toprow = @current_index = 0
|
@@ -91,8 +92,8 @@ module RubyCurses
|
|
91
92
|
bind_key(32, 'scroll forward'){ scroll_forward() }
|
92
93
|
# have placedhere so multi-bufer can override BS to prev buffer
|
93
94
|
bind_keys([KEY_BACKSPACE,KEY_BSPACE,KEY_DELETE], :cursor_backward)
|
94
|
-
bind_key(?r) { getstr("Enter a word: ") } if $log.debug?
|
95
|
-
bind_key(?m, :disp_menu) if $log.debug?
|
95
|
+
#bind_key(?r) { getstr("Enter a word: ") } if $log.debug?
|
96
|
+
#bind_key(?m, :disp_menu) if $log.debug?
|
96
97
|
end
|
97
98
|
##
|
98
99
|
# send in a list
|
@@ -619,53 +620,6 @@ module RubyCurses
|
|
619
620
|
return "" if ret != 0
|
620
621
|
return str
|
621
622
|
end
|
622
|
-
# this is just a test of the simple "most" menu
|
623
|
-
# How can application add to this, or override
|
624
|
-
# TODO: use another window at bottom, statuswindow
|
625
|
-
def disp_menu #:nodoc:
|
626
|
-
# we need to put this into data-structure so that i can be manipulated by calling apps
|
627
|
-
# This should not be at the widget level, too many types of menus. It should be at the app
|
628
|
-
# level only if the user wants his app to use this kind of menu.
|
629
|
-
|
630
|
-
if false
|
631
|
-
#@menu = RubyCurses::MenuTree.new "Main", { s: :goto_start, r: :scroll_right, l: :scroll_left, m: :submenu }
|
632
|
-
#@menu.submenu :m, "submenu", {s: :noignorecase, t: :goto_last_position, f: :next3 }
|
633
|
-
#menu = PromptMenu.new self
|
634
|
-
#menu.menu_tree @menu
|
635
|
-
#menu.display @form.window, $error_message_row, $error_message_col, $datacolor #, menu
|
636
|
-
end
|
637
|
-
# trying to find a more rubyesque way of doing
|
638
|
-
menu = PromptMenu.new self do
|
639
|
-
item :s, :goto_start
|
640
|
-
item :b, :goto_bottom
|
641
|
-
item :r, :scroll_backward
|
642
|
-
item :l, :scroll_forward
|
643
|
-
submenu :m, "submenu..." do
|
644
|
-
item :p, :goto_last_position
|
645
|
-
item :r, :scroll_right
|
646
|
-
item :l, :scroll_left
|
647
|
-
end
|
648
|
-
end
|
649
|
-
#menu.display @form.window, $error_message_row, $error_message_col, $datacolor #, menu
|
650
|
-
menu.display_new :title => "Menu"
|
651
|
-
|
652
|
-
|
653
|
-
=begin
|
654
|
-
require 'rbcurse/extras/widgets/menutree'
|
655
|
-
menu = PromptMenu.new self
|
656
|
-
menu.add( menu.create_mitem( 's', "Goto start ", "Going to start", Proc.new { goto_start} ))
|
657
|
-
menu.add(menu.create_mitem( 'r', "scroll right", "I have scrolled ", :scroll_right ))
|
658
|
-
menu.add(menu.create_mitem( 'l', "scroll left", "I have scrolled ", :scroll_left ))
|
659
|
-
item = menu.create_mitem( 'm', "submenu", "submenu options" )
|
660
|
-
menu1 = PromptMenu.new( self, "Submenu Options")
|
661
|
-
menu1.add(menu1.create_mitem( 's', "CASE sensitive", "Ignoring Case in search" ))
|
662
|
-
menu1.add(menu1.create_mitem( 't', "goto last position", "moved to previous position", Proc.new { goto_last_position} ))
|
663
|
-
item.action = menu1
|
664
|
-
menu.add(item)
|
665
|
-
# how do i know what's available. the application or window should know where to place
|
666
|
-
#menu.display @form.window, 23, 1, $datacolor #, menu
|
667
|
-
=end
|
668
|
-
end
|
669
623
|
##
|
670
624
|
# dynamically load a module and execute init method.
|
671
625
|
# Hopefully, we can get behavior like this such as vieditable or multibuffers
|
@@ -768,6 +722,12 @@ module RubyCurses
|
|
768
722
|
set_content(lines, :content_type => @old_content_type)
|
769
723
|
end
|
770
724
|
end
|
725
|
+
def init_actions
|
726
|
+
editor = ENV['EDITOR'] || 'vi'
|
727
|
+
am = action_manager()
|
728
|
+
am.add_action( Action.new("&Edit in #{editor} ") { edit_external } )
|
729
|
+
am.add_action( Action.new("&Saveas") { saveas() })
|
730
|
+
end
|
771
731
|
|
772
732
|
|
773
733
|
end # class textview
|
@@ -57,22 +57,14 @@ class Module
|
|
57
57
|
if val.empty?
|
58
58
|
@#{sym}
|
59
59
|
else
|
60
|
-
#if @frozen # 2011-10-1 prevent object from being changed # changed 2011 dts
|
61
|
-
#return if @frozen && (@frozen_list.nil? || @frozen_list.include?(:#{sym}) )
|
62
|
-
#end
|
63
60
|
@#{sym} = val.size == 1 ? val[0] : val
|
64
61
|
# i am itching to deprecate next line XXX
|
65
|
-
@config["#{sym}"]=@#{sym}
|
62
|
+
# @config["#{sym}"]=@#{sym} # commented out 2011-12-18 to simplify
|
66
63
|
self # 2011-10-2
|
67
64
|
end
|
68
65
|
end
|
69
66
|
# can the next bypass validations
|
70
|
-
# I don't think anyone will expect self to be returned if using = to assign
|
71
67
|
attr_writer sym #2011-10-2
|
72
|
-
#def #{sym}=(val)
|
73
|
-
##{sym}(val)
|
74
|
-
# self
|
75
|
-
#end
|
76
68
|
}
|
77
69
|
}
|
78
70
|
end
|
@@ -86,7 +78,6 @@ class Module
|
|
86
78
|
if val.empty?
|
87
79
|
@#{sym}
|
88
80
|
else
|
89
|
-
#return(self) if @frozen && (@frozen_list.nil? || @frozen_list.include?(:#{sym}) )
|
90
81
|
oldvalue = @#{sym}
|
91
82
|
# @#{sym} = val.size == 1 ? val[0] : val
|
92
83
|
tmp = val.size == 1 ? val[0] : val
|
@@ -94,7 +85,7 @@ class Module
|
|
94
85
|
# i am itching to deprecate config setting
|
95
86
|
if oldvalue.nil? || @_object_created.nil?
|
96
87
|
@#{sym} = tmp
|
97
|
-
@config["#{sym}"]=@#{sym}
|
88
|
+
# @config["#{sym}"]=@#{sym} # 2011-12-18
|
98
89
|
end
|
99
90
|
return(self) if oldvalue.nil? || @_object_created.nil?
|
100
91
|
|
@@ -251,11 +242,11 @@ module RubyCurses
|
|
251
242
|
when S_F9
|
252
243
|
return "S_F9"
|
253
244
|
else
|
254
|
-
others=[?\M--,?\M-+,?\M-=,?\M-',?\M-",?\M-;,?\M-:,?\M-\,, ?\M-.,?\M-<,?\M->,?\M-?,?\M
|
245
|
+
others=[?\M--,?\M-+,?\M-=,?\M-',?\M-",?\M-;,?\M-:,?\M-\,, ?\M-.,?\M-<,?\M->,?\M-?,?\M-/,?\M-!]
|
255
246
|
others.collect! {|x| x.getbyte(0) } ## added 2009-10-04 14:25 for 1.9
|
256
|
-
s_others=%w[M-- M-+ M-= M-' M-" M-; M-: M-, M-. M-< M-> M-? M-/ ]
|
247
|
+
s_others=%w[M-- M-+ M-= M-' M-" M-; M-: M-, M-. M-< M-> M-? M-/ M-!]
|
257
248
|
if others.include? keycode
|
258
|
-
index =
|
249
|
+
index = others.index keycode
|
259
250
|
return s_others[index]
|
260
251
|
end
|
261
252
|
# all else failed
|
@@ -364,7 +355,7 @@ module RubyCurses
|
|
364
355
|
# 2010-02-24 12:43 trying to take in multiple key bindings, TODO unbind
|
365
356
|
# TODO add symbol so easy to map from config file or mapping file
|
366
357
|
def bind_key keycode, *args, &blk
|
367
|
-
|
358
|
+
#$log.debug " #{@name} bind_key received #{keycode} "
|
368
359
|
@key_handler ||= {}
|
369
360
|
#
|
370
361
|
# added on 2011-12-4 so we can pass a description for a key and print it
|
@@ -407,18 +398,25 @@ module RubyCurses
|
|
407
398
|
@key_args[keycode] = args
|
408
399
|
|
409
400
|
end
|
401
|
+
# Display key bindings for current widget and form in dialog
|
410
402
|
def print_key_bindings *args
|
411
403
|
f = get_current_field
|
412
404
|
#labels = [@key_label, f.key_label]
|
413
|
-
labels = [@key_label]
|
414
|
-
labels << f.key_label if f.key_label
|
405
|
+
#labels = [@key_label]
|
406
|
+
#labels << f.key_label if f.key_label
|
407
|
+
labels = []
|
408
|
+
labels << (f.key_label || {}) #if f.key_label
|
409
|
+
labels << @key_label
|
415
410
|
arr = []
|
411
|
+
if get_current_field.help_text
|
412
|
+
arr << get_current_field.help_text
|
413
|
+
end
|
416
414
|
labels.each_with_index { |h, i|
|
417
415
|
case i
|
418
416
|
when 0
|
419
|
-
arr << " ===
|
417
|
+
arr << " === Current widget bindings ==="
|
420
418
|
when 1
|
421
|
-
arr << " ===
|
419
|
+
arr << " === Form bindings ==="
|
422
420
|
end
|
423
421
|
|
424
422
|
h.each_pair { |name, val|
|
@@ -459,14 +457,22 @@ module RubyCurses
|
|
459
457
|
blk = @key_handler[keycode]
|
460
458
|
return :UNHANDLED if blk.nil?
|
461
459
|
if blk.is_a? OrderedHash
|
460
|
+
#Ncurses::nodelay(window.get_window, bf = false)
|
461
|
+
# if you set nodelay in ncurses.rb then this will not
|
462
|
+
# wait for second key press, so you then must either make it blocking
|
463
|
+
# here, or set a wtimeout here.
|
462
464
|
ch = window.getch
|
465
|
+
#Ncurses::nodelay(window.get_window, bf = true)
|
466
|
+
|
467
|
+
$log.debug " process_key: got #{keycode} , #{ch} "
|
463
468
|
if ch < 0 || ch > 255
|
464
|
-
#next
|
465
469
|
return nil
|
466
470
|
end
|
467
|
-
$log.debug " process_key: got #{keycode} , #{ch} "
|
468
471
|
yn = ch.chr
|
469
472
|
blk1 = blk[ch]
|
473
|
+
# FIXME we are only returning the second key, what if form
|
474
|
+
# has mapped first and second combo. We should unget keycode and ch. 2011-12-23
|
475
|
+
# check this out first.
|
470
476
|
window.ungetch(ch) if blk1.nil? # trying 2011-09-27
|
471
477
|
return :UNHANDLED if blk1.nil? # changed nil to unhandled 2011-09-27
|
472
478
|
$log.debug " process_key: found block for #{keycode} , #{ch} "
|
@@ -668,6 +674,7 @@ module RubyCurses
|
|
668
674
|
|
669
675
|
|
670
676
|
class Widget
|
677
|
+
require 'rbcurse/core/include/action' # added 2012-01-3 for add_action
|
671
678
|
include EventHandler
|
672
679
|
include ConfigSetup
|
673
680
|
include RubyCurses::Utils
|
@@ -1128,7 +1135,13 @@ module RubyCurses
|
|
1128
1135
|
bind :CHANGED, *args, &block
|
1129
1136
|
end
|
1130
1137
|
end
|
1131
|
-
|
1138
|
+
# return an object of actionmanager class, creating if required
|
1139
|
+
# Widgets and apps may add_action and show_menu using the same
|
1140
|
+
def action_manager
|
1141
|
+
require 'rbcurse/core/include/actionmanager'
|
1142
|
+
@action_manager ||= ActionManager.new
|
1143
|
+
end
|
1144
|
+
#
|
1132
1145
|
## ADD HERE WIDGET
|
1133
1146
|
end
|
1134
1147
|
|
@@ -1230,7 +1243,7 @@ module RubyCurses
|
|
1230
1243
|
mb.toggle_key ||= Ncurses.KEY_F2
|
1231
1244
|
if !mb.toggle_key.nil?
|
1232
1245
|
ch = mb.toggle_key
|
1233
|
-
bind_key(ch) do |_form|
|
1246
|
+
bind_key(ch, 'Menu Bar') do |_form|
|
1234
1247
|
if !@menu_bar.nil?
|
1235
1248
|
@menu_bar.toggle
|
1236
1249
|
@menu_bar.handle_keys
|
@@ -1683,13 +1696,19 @@ module RubyCurses
|
|
1683
1696
|
def map_keys
|
1684
1697
|
return if @keys_mapped
|
1685
1698
|
bind_keys([?\M-?,?\?], 'show field help') {
|
1686
|
-
if get_current_field.help_text
|
1687
|
-
textdialog(get_current_field.help_text, 'title' => 'Help Text', :bgcolor => 'green', :color => :white)
|
1688
|
-
else
|
1699
|
+
#if get_current_field.help_text
|
1700
|
+
#textdialog(get_current_field.help_text, 'title' => 'Help Text', :bgcolor => 'green', :color => :white)
|
1701
|
+
#else
|
1689
1702
|
print_key_bindings
|
1690
|
-
end
|
1703
|
+
#end
|
1691
1704
|
}
|
1692
1705
|
bind_key(FFI::NCurses::KEY_F9, "Print keys", :print_key_bindings) # show bindings, tentative on F9
|
1706
|
+
bind_key(?\M-:, 'show menu') {
|
1707
|
+
fld = get_current_field
|
1708
|
+
am = fld.action_manager()
|
1709
|
+
#fld.init_menu
|
1710
|
+
am.show_actions
|
1711
|
+
}
|
1693
1712
|
@keys_mapped = true
|
1694
1713
|
end
|
1695
1714
|
|
@@ -1735,7 +1754,7 @@ module RubyCurses
|
|
1735
1754
|
field = get_current_field
|
1736
1755
|
if $log.debug?
|
1737
1756
|
keycode = keycode_tos(ch)
|
1738
|
-
|
1757
|
+
#$log.debug " form HK #{ch} #{self}, #{@name}, #{keycode}, field: giving to: #{field}, #{field.name} " if field
|
1739
1758
|
end
|
1740
1759
|
handled = :UNHANDLED
|
1741
1760
|
handled = field.handle_key ch unless field.nil? # no field focussable
|
@@ -2158,17 +2177,17 @@ module RubyCurses
|
|
2158
2177
|
end
|
2159
2178
|
def map_keys
|
2160
2179
|
return if @keys_mapped
|
2161
|
-
bind_key(FFI::NCurses::KEY_LEFT
|
2162
|
-
bind_key(FFI::NCurses::KEY_RIGHT
|
2163
|
-
bind_key(FFI::NCurses::KEY_BACKSPACE
|
2164
|
-
bind_key(127
|
2165
|
-
bind_key(330
|
2166
|
-
bind_key(?\C-a
|
2167
|
-
bind_key(?\C-e
|
2168
|
-
bind_key(?\C-k
|
2169
|
-
bind_key(?\C-_
|
2180
|
+
bind_key(FFI::NCurses::KEY_LEFT, :cursor_backward )
|
2181
|
+
bind_key(FFI::NCurses::KEY_RIGHT, :cursor_forward )
|
2182
|
+
bind_key(FFI::NCurses::KEY_BACKSPACE, :delete_prev_char )
|
2183
|
+
bind_key(127, :delete_prev_char )
|
2184
|
+
bind_key(330, :delete_curr_char )
|
2185
|
+
bind_key(?\C-a, :cursor_home )
|
2186
|
+
bind_key(?\C-e, :cursor_end )
|
2187
|
+
bind_key(?\C-k, :delete_eol )
|
2188
|
+
bind_key(?\C-_, :undo_delete_eol )
|
2170
2189
|
#bind_key(27){ set_buffer @original_value }
|
2171
|
-
bind_key(?\C-g){ set_buffer @original_value } # 2011-09-29 V1.3.1 ESC did not work
|
2190
|
+
bind_key(?\C-g, 'revert'){ set_buffer @original_value } # 2011-09-29 V1.3.1 ESC did not work
|
2172
2191
|
@keys_mapped = true
|
2173
2192
|
end
|
2174
2193
|
|
@@ -2537,10 +2556,10 @@ module RubyCurses
|
|
2537
2556
|
# meta key
|
2538
2557
|
mch = ?\M-a.getbyte(0) + (ch - ?a.getbyte(0)) ## 1.9
|
2539
2558
|
if (@label_for.is_a? RubyCurses::Button ) && (@label_for.respond_to? :fire)
|
2540
|
-
@form.bind_key(mch, @label_for) { |_form, _butt|
|
2559
|
+
@form.bind_key(mch, "hotkey for button #{@label_for.text} ") { |_form, _butt| @label_for.fire }
|
2541
2560
|
else
|
2542
2561
|
$log.debug " bind_hotkey label for: #{@label_for}"
|
2543
|
-
@form.bind_key(mch,
|
2562
|
+
@form.bind_key(mch, "hotkey for label #{text} ") { |_form, _field| @label_for.focus }
|
2544
2563
|
end
|
2545
2564
|
end
|
2546
2565
|
end
|
@@ -2649,6 +2668,7 @@ module RubyCurses
|
|
2649
2668
|
s.slice!(ix,1)
|
2650
2669
|
# 2011-10-20 NOTE XXX I have removed form check since bindkey is called conditionally
|
2651
2670
|
@underline = ix #unless @form.nil? # this setting a fake underline in messageboxes
|
2671
|
+
@text = s # mnemo needs this for setting description
|
2652
2672
|
mnemonic s[ix,1]
|
2653
2673
|
end
|
2654
2674
|
@text = s
|
@@ -2676,7 +2696,8 @@ module RubyCurses
|
|
2676
2696
|
# meta key
|
2677
2697
|
ch = ?\M-a.getbyte(0) + (ch - ?a.getbyte(0)) unless @hotkey
|
2678
2698
|
$log.debug " #{self} setting MNEMO to #{char} #{ch}, #{@hotkey} "
|
2679
|
-
|
2699
|
+
_t = self.text || self.name || "Unnamed #{self.class} "
|
2700
|
+
@form.bind_key(ch, "hotkey for button #{_t} ") { |_form, _butt| self.fire }
|
2680
2701
|
end
|
2681
2702
|
|
2682
2703
|
##
|
@@ -2697,7 +2718,7 @@ module RubyCurses
|
|
2697
2718
|
@mnemonic = _value[@underline,1]
|
2698
2719
|
# meta key
|
2699
2720
|
mch = ?\M-a.getbyte(0) + (ch - ?a.getbyte(0))
|
2700
|
-
@form.bind_key(mch, self) { |_form, _butt|
|
2721
|
+
@form.bind_key(mch, "hotkey for button #{self.text}" ) { |_form, _butt| self.fire }
|
2701
2722
|
end
|
2702
2723
|
def default_button tf=nil
|
2703
2724
|
return @default_button unless tf
|
@@ -2706,7 +2727,7 @@ module RubyCurses
|
|
2706
2727
|
@default_button = tf
|
2707
2728
|
if tf
|
2708
2729
|
@surround_chars = @default_chars
|
2709
|
-
@form.bind_key(13, self) { |_form, _butt|
|
2730
|
+
@form.bind_key(13, "fire #{self.text} ") { |_form, _butt| self.fire }
|
2710
2731
|
else
|
2711
2732
|
# i have no way of reversing the above
|
2712
2733
|
end
|
@@ -2967,7 +2988,6 @@ module RubyCurses
|
|
2967
2988
|
|
2968
2989
|
##
|
2969
2990
|
# A checkbox, may be selected or unselected
|
2970
|
-
# TODO hotkey should work here too.
|
2971
2991
|
#
|
2972
2992
|
class CheckBox < ToggleButton
|
2973
2993
|
dsl_accessor :align_right # the button will be on the right 2008-12-09 23:41
|
data/lib/rbcurse.rb
CHANGED
data/rbcurse-core.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "rbcurse-core"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rahul Kumar"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2012-01-05"
|
13
13
|
s.description = "Ruby curses/ncurses widgets for easy application development on text terminals (ruby 1.9, 1.8)"
|
14
14
|
s.email = "sentinel1879@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -54,6 +54,7 @@ Gem::Specification.new do |s|
|
|
54
54
|
"lib/rbcurse.rb",
|
55
55
|
"lib/rbcurse/core/docs/index.txt",
|
56
56
|
"lib/rbcurse/core/include/action.rb",
|
57
|
+
"lib/rbcurse/core/include/actionmanager.rb",
|
57
58
|
"lib/rbcurse/core/include/appmethods.rb",
|
58
59
|
"lib/rbcurse/core/include/bordertitle.rb",
|
59
60
|
"lib/rbcurse/core/include/chunk.rb",
|
@@ -70,6 +71,7 @@ Gem::Specification.new do |s|
|
|
70
71
|
"lib/rbcurse/core/include/rhistory.rb",
|
71
72
|
"lib/rbcurse/core/include/rinputdataevent.rb",
|
72
73
|
"lib/rbcurse/core/include/vieditable.rb",
|
74
|
+
"lib/rbcurse/core/include/widgetmenu.rb",
|
73
75
|
"lib/rbcurse/core/system/colormap.rb",
|
74
76
|
"lib/rbcurse/core/system/keyboard.rb",
|
75
77
|
"lib/rbcurse/core/system/keydefs.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbcurse-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi-ncurses
|
16
|
-
requirement: &
|
16
|
+
requirement: &70102876538580 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 0.4.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70102876538580
|
25
25
|
description: Ruby curses/ncurses widgets for easy application development on text
|
26
26
|
terminals (ruby 1.9, 1.8)
|
27
27
|
email: sentinel1879@gmail.com
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- lib/rbcurse.rb
|
69
69
|
- lib/rbcurse/core/docs/index.txt
|
70
70
|
- lib/rbcurse/core/include/action.rb
|
71
|
+
- lib/rbcurse/core/include/actionmanager.rb
|
71
72
|
- lib/rbcurse/core/include/appmethods.rb
|
72
73
|
- lib/rbcurse/core/include/bordertitle.rb
|
73
74
|
- lib/rbcurse/core/include/chunk.rb
|
@@ -84,6 +85,7 @@ files:
|
|
84
85
|
- lib/rbcurse/core/include/rhistory.rb
|
85
86
|
- lib/rbcurse/core/include/rinputdataevent.rb
|
86
87
|
- lib/rbcurse/core/include/vieditable.rb
|
88
|
+
- lib/rbcurse/core/include/widgetmenu.rb
|
87
89
|
- lib/rbcurse/core/system/colormap.rb
|
88
90
|
- lib/rbcurse/core/system/keyboard.rb
|
89
91
|
- lib/rbcurse/core/system/keydefs.rb
|