ppcurses 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ppcurses.rb +1 -0
- data/lib/ppcurses/Screen.rb +4 -0
- data/lib/ppcurses/application.rb +15 -0
- data/lib/ppcurses/form/button.rb +3 -3
- data/lib/ppcurses/form/form.rb +8 -3
- data/lib/ppcurses/geometry.rb +49 -3
- data/lib/ppcurses/menu/date_menu.rb +1 -1
- data/lib/ppcurses/notification_centre.rb +65 -0
- data/lib/ppcurses/table_view.rb +83 -8
- data/lib/ppcurses/view.rb +23 -0
- data/test/table_view/testTableView.rb +47 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8bdbca428f64c67ef820fe58eadf61028d1d98a
|
4
|
+
data.tar.gz: 504bb1ea95801d31262d2c94b9f3ca5df72766cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdbfd2743fb1b43742a91fc750e5450c6045f1d247f94f5e6f619fa600ad6c0ae946f9ea183b1a44c0ff9a6e3ab43db3f168574768bac418b95a5fa72c8e5e0c
|
7
|
+
data.tar.gz: 1108125d7b75d5612d149e7ec31a066c8381d2a9f7a96453956bd71036ca186ca3efc523a70c296aab818cfea7094b00fc178062ba911171c8ec6ac410a3c4f7
|
data/lib/ppcurses.rb
CHANGED
data/lib/ppcurses/Screen.rb
CHANGED
data/lib/ppcurses/application.rb
CHANGED
@@ -146,6 +146,21 @@ module PPCurses
|
|
146
146
|
|
147
147
|
|
148
148
|
def content_view=(value)
|
149
|
+
|
150
|
+
if @content_view != nil then
|
151
|
+
# Clear current content_view before reassignment
|
152
|
+
frame = @content_view.frame
|
153
|
+
x = frame.origin.x
|
154
|
+
y = frame.origin.y
|
155
|
+
height = frame.size.height
|
156
|
+
|
157
|
+
for i in y..y+height-1
|
158
|
+
@screen.setpos( i, x )
|
159
|
+
@screen.clrtoeol ## TODO use width !!!
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
149
164
|
@content_view=value
|
150
165
|
@main_menu.next_responder=@content_view
|
151
166
|
end
|
data/lib/ppcurses/form/button.rb
CHANGED
@@ -54,8 +54,8 @@ module PPCurses
|
|
54
54
|
attr_accessor :selected
|
55
55
|
attr_accessor :selected_element
|
56
56
|
|
57
|
-
|
58
|
-
|
57
|
+
attr_accessor :button1
|
58
|
+
attr_accessor :button2
|
59
59
|
|
60
60
|
def initialize(button1_label, button2_label)
|
61
61
|
@button1 = Button.new(button1_label)
|
@@ -72,7 +72,7 @@ module PPCurses
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def height
|
75
|
-
|
75
|
+
2
|
76
76
|
end
|
77
77
|
|
78
78
|
def set_curs_pos(screen)
|
data/lib/ppcurses/form/form.rb
CHANGED
@@ -8,6 +8,9 @@ module PPCurses
|
|
8
8
|
# Screen should be of type Curses::Window
|
9
9
|
#
|
10
10
|
def initialize
|
11
|
+
super
|
12
|
+
origin = Point.new( 1, 1 )
|
13
|
+
setFrameOrigin(origin)
|
11
14
|
@elements = []
|
12
15
|
end
|
13
16
|
|
@@ -29,7 +32,9 @@ module PPCurses
|
|
29
32
|
if @selected_element.nil?
|
30
33
|
set_selected_element(@elements[0])
|
31
34
|
end
|
32
|
-
|
35
|
+
|
36
|
+
@frame.size.height += element.height
|
37
|
+
|
33
38
|
end
|
34
39
|
|
35
40
|
|
@@ -61,8 +66,8 @@ module PPCurses
|
|
61
66
|
|
62
67
|
# TODO -- call display of subview???
|
63
68
|
def display(screen)
|
64
|
-
|
65
|
-
|
69
|
+
y = @frame.origin.y
|
70
|
+
x = @frame.origin.x
|
66
71
|
|
67
72
|
for i in 0..@elements.length - 1
|
68
73
|
element = @elements[i]
|
data/lib/ppcurses/geometry.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
module PPCurses
|
2
2
|
|
3
|
-
|
4
3
|
class Point
|
5
4
|
|
6
5
|
attr_accessor :x, :y
|
7
6
|
|
8
|
-
def initialize( x, y )
|
7
|
+
def initialize( x=0, y=0 )
|
9
8
|
@x = x
|
10
9
|
@y = y
|
11
10
|
end
|
@@ -14,10 +13,57 @@ module PPCurses
|
|
14
13
|
"x=#{@x} y=#{@y}"
|
15
14
|
end
|
16
15
|
|
16
|
+
def Point.zeroPoint
|
17
|
+
Point.new
|
18
|
+
end
|
19
|
+
|
17
20
|
end
|
18
21
|
|
19
|
-
|
22
|
+
# -------------------------------------------------------------------
|
20
23
|
|
24
|
+
class Size
|
25
|
+
attr_accessor :width, :height
|
26
|
+
|
27
|
+
def initialize( width=0, height=0 )
|
28
|
+
@width = width
|
29
|
+
@height = height
|
30
|
+
end
|
31
|
+
|
32
|
+
def Size.zeroSize
|
33
|
+
Size.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
"width=#{@width} height=#{@height}"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# -------------------------------------------------------------------
|
43
|
+
|
44
|
+
class Rect
|
45
|
+
attr_accessor :origin, :size
|
46
|
+
|
47
|
+
def initialize ( origin, size )
|
48
|
+
@origin = origin
|
49
|
+
@size = size
|
50
|
+
end
|
51
|
+
|
52
|
+
def Rect.makeRect( x, y, w, h )
|
53
|
+
origin = Point.new(x, y)
|
54
|
+
size = Size.new(w, h)
|
55
|
+
|
56
|
+
rect = Rect.new( origin, size)
|
57
|
+
end
|
58
|
+
|
59
|
+
def Rect.zeroRect
|
60
|
+
Rect.new( Point.zeroPoint, Size.zeroSize )
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
"origin[#{@origin}] size[#{@size}]"
|
65
|
+
end
|
66
|
+
|
21
67
|
end
|
22
68
|
|
23
69
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module PPCurses
|
2
|
+
|
3
|
+
class NotificationCentre
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@listeners = Hash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
@@default_centre = PPCurses::NotificationCentre.new
|
10
|
+
|
11
|
+
def NotificationCentre.default_centre
|
12
|
+
@@default_centre
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def add_observer( observer, selector, name, sender)
|
17
|
+
|
18
|
+
if @listeners.has_key?(name)
|
19
|
+
sender_hash = @listeners.fetch(name)
|
20
|
+
else
|
21
|
+
sender_hash = Hash.new
|
22
|
+
@listeners.store(name, sender_hash)
|
23
|
+
end
|
24
|
+
|
25
|
+
sender_hash.store(sender, [observer, selector])
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def post_notification ( name, sender )
|
31
|
+
|
32
|
+
if @listeners.has_key?(name) == false then return end
|
33
|
+
|
34
|
+
sender_hash = @listeners.fetch(name)
|
35
|
+
|
36
|
+
if sender_hash.has_key?(sender) == false then return end
|
37
|
+
|
38
|
+
listener_info = sender_hash.fetch(sender)
|
39
|
+
# observer = listener_info[0] # Currently unused
|
40
|
+
callback = listener_info[1]
|
41
|
+
|
42
|
+
notification = Notification.new(name, sender)
|
43
|
+
|
44
|
+
callback.call ( notification )
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
class Notification
|
51
|
+
|
52
|
+
attr_reader :name
|
53
|
+
attr_reader :object
|
54
|
+
|
55
|
+
def initialize( name, object )
|
56
|
+
@name = name
|
57
|
+
@object = object
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
end
|
data/lib/ppcurses/table_view.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
|
+
|
2
|
+
PPTableViewSelectionDidChangeNotification = 'PPTableViewSelectionDidChangeNotification'
|
3
|
+
PPTableViewSelectionIsChangingNotification = 'PPTableViewSelectionIsChangingNotification'
|
4
|
+
PPTableViewEnterPressedNotification = 'PPTableViewEnterPressedNotification'
|
5
|
+
|
1
6
|
module PPCurses
|
7
|
+
|
8
|
+
|
9
|
+
|
2
10
|
# Based loosely on ...
|
3
11
|
#
|
4
12
|
# https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTableView_Class/index.html#//apple_ref/occ/cl/NSTableView
|
@@ -6,13 +14,17 @@ module PPCurses
|
|
6
14
|
#
|
7
15
|
class TableView < View
|
8
16
|
|
17
|
+
|
9
18
|
attr_accessor :data_source
|
19
|
+
attr_reader :selected_row
|
10
20
|
|
11
|
-
|
12
|
-
|
13
|
-
|
21
|
+
def initialize
|
22
|
+
super
|
23
|
+
origin = Point.new( 2, 2 )
|
24
|
+
setFrameOrigin(origin)
|
14
25
|
end
|
15
26
|
|
27
|
+
|
16
28
|
# A data source must implement a formal protocol
|
17
29
|
#
|
18
30
|
# - def number_of_rows_in_table(tableView)
|
@@ -21,12 +33,69 @@ class TableView < View
|
|
21
33
|
def data_source=(val)
|
22
34
|
PPCurses.implements_protocol( val, %w(number_of_rows_in_table object_value_for ))
|
23
35
|
@data_source = val
|
36
|
+
@selected_row = 0
|
37
|
+
|
38
|
+
# Determine frame size from datasource data
|
39
|
+
height = @data_source.number_of_rows_in_table(self)
|
40
|
+
width = 0
|
41
|
+
for i in 0..@data_source.number_of_rows_in_table(self)-1
|
42
|
+
x = @data_source.object_value_for(self, 0, i).length
|
43
|
+
if x > width then width = x end
|
44
|
+
end
|
45
|
+
|
46
|
+
sz = Size.new( width, height )
|
47
|
+
setFrameSize( sz )
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def display(screen)
|
52
|
+
|
53
|
+
y = @frame.origin.y
|
54
|
+
x = @frame.origin.x
|
55
|
+
|
56
|
+
for i in 0..@data_source.number_of_rows_in_table(self)-1
|
57
|
+
screen.setpos(y,x)
|
58
|
+
screen.attron(Curses::A_REVERSE) if i == selected_row
|
59
|
+
screen.addstr(@data_source.object_value_for(self, 0, i) )
|
60
|
+
screen.attroff(Curses::A_REVERSE) if i == selected_row
|
61
|
+
y += 1
|
62
|
+
end
|
24
63
|
end
|
25
64
|
|
65
|
+
|
66
|
+
# NSTableViewSelectionDidChangeNotification
|
67
|
+
# NSNotificationCentre
|
68
|
+
def key_down( key )
|
69
|
+
|
70
|
+
notary = NotificationCentre.default_centre
|
71
|
+
|
72
|
+
if key == KEY_DOWN
|
73
|
+
notary.post_notification(PPTableViewSelectionIsChangingNotification, self)
|
74
|
+
@selected_row += 1
|
75
|
+
if @selected_row > @data_source.number_of_rows_in_table(self) - 1 then
|
76
|
+
@selected_row = 0
|
77
|
+
end
|
78
|
+
notary.post_notification(PPTableViewSelectionDidChangeNotification, self)
|
79
|
+
end
|
80
|
+
|
81
|
+
if key == KEY_UP
|
82
|
+
notary.post_notification(PPTableViewSelectionIsChangingNotification, self)
|
83
|
+
@selected_row -= 1
|
84
|
+
if @selected_row < 0 then @selected_row = @data_source.number_of_rows_in_table(self) - 1 end
|
85
|
+
notary.post_notification(PPTableViewSelectionDidChangeNotification, self)
|
86
|
+
end
|
87
|
+
|
88
|
+
if key == ENTER
|
89
|
+
notary.post_notification(PPTableViewEnterPressedNotification, self)
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
end
|
94
|
+
|
26
95
|
end
|
27
96
|
|
28
97
|
|
29
|
-
# Based
|
98
|
+
# Based on ...
|
30
99
|
#
|
31
100
|
# https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSTableDataSource_Protocol/index.html#//apple_ref/occ/intf/NSTableViewDataSource
|
32
101
|
|
@@ -35,16 +104,22 @@ class SingleColumnDataSource
|
|
35
104
|
def initialize(values)
|
36
105
|
@values = values
|
37
106
|
end
|
38
|
-
|
39
|
-
|
107
|
+
|
108
|
+
# Returns the number of records managed for aTableView by the
|
109
|
+
# data source object.
|
110
|
+
def number_of_rows_in_table( aTableView)
|
40
111
|
@values.length
|
41
112
|
end
|
42
|
-
|
43
|
-
|
113
|
+
|
114
|
+
# Called by the table view to return the data object associated with
|
115
|
+
# the specified row and column.
|
116
|
+
def object_value_for(aTableview, column, row_index)
|
44
117
|
@values[row_index]
|
45
118
|
end
|
46
119
|
end
|
47
120
|
|
121
|
+
|
122
|
+
|
48
123
|
class TableViewDataSource
|
49
124
|
|
50
125
|
def TableViewDataSource.from_string_array(values)
|
data/lib/ppcurses/view.rb
CHANGED
@@ -10,6 +10,16 @@ module PPCurses
|
|
10
10
|
|
11
11
|
class View < ResponderManager
|
12
12
|
|
13
|
+
attr_accessor :frame
|
14
|
+
|
15
|
+
# Extending classes should set the appropriate frame size;
|
16
|
+
# the default implementation sets the frame to a zero rect
|
17
|
+
# which, although avoids pointer errors, isn't very useful.
|
18
|
+
def initialize
|
19
|
+
@frame = Rect.zeroRect
|
20
|
+
end
|
21
|
+
|
22
|
+
|
13
23
|
## Managing the View Hierarchy
|
14
24
|
|
15
25
|
# superview
|
@@ -40,6 +50,19 @@ module PPCurses
|
|
40
50
|
|
41
51
|
#
|
42
52
|
|
53
|
+
## Modifying the Frame Rectangle
|
54
|
+
|
55
|
+
|
56
|
+
def setFrameOrigin( origin )
|
57
|
+
@frame.origin = origin
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def setFrameSize( size )
|
62
|
+
@frame.size = size
|
63
|
+
end
|
64
|
+
|
65
|
+
|
43
66
|
end
|
44
67
|
|
45
68
|
end
|
@@ -2,15 +2,57 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require_relative '../../lib/ppcurses.rb'
|
5
|
+
# ------------------------------------------------------------------------------
|
6
|
+
# Tableview callbacks
|
7
|
+
# ------------------------------------------------------------------------------
|
8
|
+
@select_count = 0
|
9
|
+
def select_counter ( notification )
|
10
|
+
@select_count += 1
|
11
|
+
end
|
5
12
|
|
6
|
-
@
|
13
|
+
@enter_count = 0
|
14
|
+
def item_chosen ( notification )
|
15
|
+
@enter_count += 1
|
16
|
+
|
17
|
+
if notification.object.selected_row == 0
|
18
|
+
@app.content_view = @music_form
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def music_cancel
|
24
|
+
@app.content_view = @table_view
|
25
|
+
end
|
26
|
+
|
27
|
+
def music_submit
|
28
|
+
@app.content_view = @table_view
|
29
|
+
end
|
30
|
+
# ------------------------------------------------------------------------------
|
7
31
|
|
8
|
-
|
32
|
+
@music_form = PPCurses::Form.new
|
33
|
+
media = PPCurses::RadioButtonGroup.new(' Media Type', %w(CD Vinyl MP3) )
|
34
|
+
buttons = PPCurses::ButtonPair.new('Submit', 'Cancel')
|
35
|
+
buttons.button1.action = method(:music_submit)
|
36
|
+
buttons.button2.action = method(:music_cancel)
|
37
|
+
@music_form.add(media)
|
38
|
+
@music_form.add(buttons)
|
39
|
+
|
40
|
+
|
41
|
+
@app = PPCurses::Application.new
|
42
|
+
@table_view = PPCurses::TableView.new
|
9
43
|
|
10
44
|
values = %w(Music Reading Lifts)
|
11
45
|
data_source = PPCurses::SingleColumnDataSource.new(values)
|
12
46
|
|
13
|
-
table_view.data_source=data_source
|
47
|
+
@table_view.data_source=data_source
|
48
|
+
|
49
|
+
@app.content_view = @table_view
|
50
|
+
|
51
|
+
notary = PPCurses::NotificationCentre.default_centre
|
52
|
+
notary.add_observer(self, method(:select_counter), PPTableViewSelectionDidChangeNotification, @table_view )
|
53
|
+
notary.add_observer(self, method(:item_chosen), PPTableViewEnterPressedNotification, @table_view )
|
54
|
+
|
55
|
+
@app.launch
|
14
56
|
|
15
|
-
@
|
16
|
-
@
|
57
|
+
puts "Number of selection changes was: #{@select_count} "
|
58
|
+
puts "Enter was pressed #{@enter_count} times."
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ppcurses
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthieu Cormier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A curses abstraction layer.
|
14
14
|
email: mcormier@preenandprune.com
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/ppcurses/menu/date_menu.rb
|
49
49
|
- lib/ppcurses/menu/menu_item.rb
|
50
50
|
- lib/ppcurses/menu_bar.rb
|
51
|
+
- lib/ppcurses/notification_centre.rb
|
51
52
|
- lib/ppcurses/table_view.rb
|
52
53
|
- lib/ppcurses/view.rb
|
53
54
|
- lib/ppcurses/window/pp_window.rb
|