ppcurses 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24ac08644952676975408eb133016f10f3a39825
4
- data.tar.gz: 0f7536cf358e3e4fce9db59d7eb912a59891d23f
3
+ metadata.gz: c8bdbca428f64c67ef820fe58eadf61028d1d98a
4
+ data.tar.gz: 504bb1ea95801d31262d2c94b9f3ca5df72766cb
5
5
  SHA512:
6
- metadata.gz: 206b4615b6471629bc3cd087f7bfa5c32e57a42c55db96df5ac6675fd803e3136dc77f087683dadb985fa674cac9bd76c8c006187d07c077cea540fb916ec307
7
- data.tar.gz: f62bf00745e11818ab02a52283a81e5251c35e01aaac07d8ded82ac643133cb0c87fbd798987ac1e359dddd4ee4abd6e3fcf9fb5f08ba5724b16dd87421f5700
6
+ metadata.gz: fdbfd2743fb1b43742a91fc750e5450c6045f1d247f94f5e6f619fa600ad6c0ae946f9ea183b1a44c0ff9a6e3ab43db3f168574768bac418b95a5fa72c8e5e0c
7
+ data.tar.gz: 1108125d7b75d5612d149e7ec31a066c8381d2a9f7a96453956bd71036ca186ca3efc523a70c296aab818cfea7094b00fc178062ba911171c8ec6ac410a3c4f7
data/lib/ppcurses.rb CHANGED
@@ -30,6 +30,7 @@ module PPCurses
30
30
 
31
31
 
32
32
  require_relative 'ppcurses/application.rb'
33
+ require_relative 'ppcurses/notification_centre.rb'
33
34
  require_relative 'ppcurses/view.rb'
34
35
  require_relative 'ppcurses/menu_bar.rb'
35
36
  require_relative 'ppcurses/Screen.rb'
@@ -102,6 +102,10 @@ module PPCurses
102
102
  Curses.stdscr.setpos(y, x)
103
103
  end
104
104
 
105
+ def clrtoeol
106
+ Curses.stdscr.clrtoeol
107
+ end
108
+
105
109
  def attron(attributes)
106
110
  Curses.stdscr.attron(attributes)
107
111
  end
@@ -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
@@ -54,8 +54,8 @@ module PPCurses
54
54
  attr_accessor :selected
55
55
  attr_accessor :selected_element
56
56
 
57
- attr_reader :button1
58
- attr_reader :button2
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
- 1
75
+ 2
76
76
  end
77
77
 
78
78
  def set_curs_pos(screen)
@@ -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
- y = 1
65
- x = 1
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]
@@ -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
- class Rect
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
@@ -35,7 +35,7 @@ module PPCurses
35
35
 
36
36
 
37
37
  def show
38
- y = 2
38
+ y = 2
39
39
  x = 2
40
40
 
41
41
  str_array = @meta_info.month_str_array
@@ -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
@@ -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
- def selected_row
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 loosely on ...
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
- def number_of_rows_in_table
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
- def object_value_for(column, row_index)
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
- @app = PPCurses::Application.new
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
- table_view = PPCurses::TableView.new
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
- @app.content_view = table_view
16
- @app.launch
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.0
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-12 00:00:00.000000000 Z
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