rbcurse-core 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|