mars_base_10 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd093ec957e418592f791bb2dfc1e1e7efa56973fd553534278a6dcb818f3482
4
- data.tar.gz: 478b185df1d0c2280788691e4bd61bfac817c200348e63bb29a7a36e05f1eb84
3
+ metadata.gz: 9ea353d6a59cf0d1ad388a521fa07a121cd94942eb4556c23ee4a11603622141
4
+ data.tar.gz: 6fd28ad9bd47d54172c4a3c6a0f64e5e4da244af6065ad8514f779cc388dc0c6
5
5
  SHA512:
6
- metadata.gz: e9044477c9eb149f2212f5dd5e7e44eb8d0fa247e0db7a382aa5256708ba53027e8c48c18f992b4c2c7dde36281cd5f725f86662283d71f713f50ed6a08662a2
7
- data.tar.gz: ac4c86d4ab841a92e262138bdf6a290af01d93e65d1afe514d6076681bb217dc59bde4ec2e90ccd3e10d4936ae298387ae0d662565e3030e88658a1f0a78deb6
6
+ metadata.gz: 248ae50be666debca25a7c253822e941af1c3ba19ac484b6e21423526497c9777419b4b2417756a565bc890afb9dc817d0eb3060eb0b7db34bab0ae5c396ac58
7
+ data.tar.gz: 20e525d483036e6a815f0e46a3529cdf6d1bee8e4a96bc8c32cc0d27b774331e13d1ae3c76177904da39b845224ed12cfa6b4dc3cb667e943704c75799cb7360
@@ -11,7 +11,7 @@ module MarsBase10
11
11
  end
12
12
 
13
13
  def self.Default
14
- ActionBar.new actions: {'j': 'Move Down', 'k': 'Move Up', 'J': 'Page Down', 'K': 'Page Up', 'q': 'Quit'}
14
+ ActionBar.new actions: {'j': 'Move Down', 'k': 'Move Up', 'J': 'Page Down', 'K': 'Page Up', 'X': 'Switch App', 'q': 'Quit'}
15
15
  end
16
16
 
17
17
  def actions_first_col
@@ -2,6 +2,7 @@
2
2
  require 'urbit'
3
3
 
4
4
  require_relative 'graph_rover'
5
+ require_relative 'group_room'
5
6
  require_relative 'viewport'
6
7
 
7
8
  module MarsBase10
@@ -10,22 +11,38 @@ module MarsBase10
10
11
  class CommCentral
11
12
  def initialize(config_filename:)
12
13
  @viewport = Viewport.new
13
- @rover = GraphRover.new ship_connection: Urbit.connect(config_file: config_filename),
14
- viewport: @viewport
14
+ @ship = Urbit.connect(config_file: config_filename)
15
+ @ship.login
16
+ sleep 2 # This is temporary for now, we need a way to know that the subscription callbacks have finished.
17
+ @controller = GroupRoom.new manager: self, ship_connection: @ship, viewport: @viewport
15
18
  end
16
19
 
17
20
  def activate
18
- self.rover.start
21
+ self.controller.start
22
+ end
23
+
24
+ def swap_controller
25
+ self.controller.stop
26
+ if GroupRoom == self.controller.class
27
+ @controller = GraphRover.new manager: self, ship_connection: self.ship, viewport: @viewport
28
+ else
29
+ @controller = GroupRoom.new manager: self, ship_connection: self.ship, viewport: @viewport
30
+ end
31
+ self.controller.start
19
32
  end
20
33
 
21
34
  def shutdown
22
- self.rover.stop
35
+ self.controller.stop
23
36
  end
24
37
 
25
38
  private
26
39
 
27
- def rover
28
- @rover
40
+ def controller
41
+ @controller
42
+ end
43
+
44
+ def ship
45
+ @ship
29
46
  end
30
47
  end
31
48
  end
@@ -6,9 +6,10 @@ require_relative 'subject'
6
6
 
7
7
  module MarsBase10
8
8
  class GraphRover
9
- attr_reader :panes, :ship, :viewport
9
+ attr_reader :manager, :panes, :ship, :viewport
10
10
 
11
- def initialize(ship_connection:, viewport:)
11
+ def initialize(manager:, ship_connection:, viewport:)
12
+ @manager = manager
12
13
  @ship = Ship.new connection: ship_connection
13
14
  @stack = Stack.new
14
15
  @viewport = viewport
@@ -75,6 +76,8 @@ module MarsBase10
75
76
  self.viewport.action_bar.remove_action(:p)
76
77
  end
77
78
  end
79
+ when 'X'
80
+ self.manager.swap_controller
78
81
  end
79
82
  self.resync if resync_needed
80
83
  end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ship'
4
+ require_relative 'stack'
5
+ require_relative 'subject'
6
+
7
+ module MarsBase10
8
+ class GroupRoom
9
+ attr_reader :manager, :panes, :ship, :viewport
10
+
11
+ def initialize(manager:, ship_connection:, viewport:)
12
+ @manager = manager
13
+ @ship = Ship.new connection: ship_connection
14
+ @stack = Stack.new
15
+ @viewport = viewport
16
+ @viewport.controller = self
17
+
18
+ self.wire_up_panes
19
+ self.viewport.action_bar = ActionBar.Default.add_action({'i': 'Inspect'})
20
+ self.viewport.activate pane: @pane_1
21
+ self.resync
22
+ end
23
+
24
+ def active_node
25
+ self.ship.fetch_node(resource: self.active_resource, index: self.active_node_index)
26
+ end
27
+
28
+ def active_resource
29
+ @pane_1.current_subject_index
30
+ end
31
+
32
+ def active_subject(pane:)
33
+ pane.current_subject_index
34
+ end
35
+
36
+ def load_history
37
+ return 0 unless @pane_3 == self.viewport.active_pane
38
+ new_content = self.ship.fetch_older_nodes(resource: self.active_resource, node: self.active_node)
39
+ @pane_3.subject.prepend_content(ary: new_content)
40
+ new_content.length
41
+ end
42
+
43
+ #
44
+ # Called by a pane in this controller for bubbling a key press up
45
+ #
46
+ def send(key:)
47
+ resync_needed = true
48
+ case key
49
+ when 'g' # (G)raph View
50
+ unless @pane_1.active?
51
+ self.viewport.activate pane: @pane_1
52
+ end
53
+ when 'i' # (I)nspect
54
+ begin
55
+ self.viewport.activate pane: @pane_3
56
+ self.viewport.action_bar = ActionBar.Default.add_action({'g': 'Group List'})
57
+ resync_needed = false
58
+ end
59
+ when 'X'
60
+ self.manager.swap_controller
61
+ end
62
+ self.resync if resync_needed
63
+ end
64
+
65
+ def start
66
+ self.viewport.open
67
+ end
68
+
69
+ def stop
70
+ self.viewport.close
71
+ end
72
+
73
+ private
74
+
75
+ def resync
76
+ self.resync_node_list
77
+ self.resync_node_view
78
+ end
79
+
80
+ def resync_node_list
81
+ if @pane_1 == self.viewport.active_pane
82
+ group_title = self.active_subject(pane: @pane_1)
83
+ @pane_2.clear
84
+ @pane_2.subject.title = "#{group_title}"
85
+ @pane_2.subject.contents = self.ship.fetch_group(group_title: group_title)
86
+
87
+ @pane_3.clear
88
+ @pane_3.subject.title = "Channels of #{self.active_subject(pane: @pane_1)}"
89
+ @pane_3.subject.contents = self.ship.fetch_group_channels(group_title: self.active_subject(pane: @pane_1))
90
+ end
91
+ nil
92
+ end
93
+
94
+ def resync_node_view
95
+ channel_title = self.active_subject(pane: @pane_3)
96
+ @pane_4.subject.title = "#{channel_title}"
97
+ @pane_4.clear
98
+ @pane_4.subject.contents = self.ship.fetch_channel(group_title: self.active_subject(pane: @pane_1), channel_title: channel_title)
99
+ nil
100
+ end
101
+
102
+ def wire_up_panes
103
+ @panes = []
104
+
105
+ # Pane #1 is the Group list, It is a fixed height and width in the upper left corner.
106
+ @pane_1 = @viewport.add_pane height_pct: 0.5, width_pct: 0.5
107
+ # if @ship.group_names.empty?
108
+ # @pane_1.view(subject: @ship.graph_names)
109
+ # else
110
+ @pane_1.view(subject: @ship.group_names)
111
+ # end
112
+
113
+ # Pane 2 displays the properties of the selected Group. It is variable height in the bottom left corner.
114
+ @pane_2 = @viewport.add_variable_height_pane at_row: @pane_1.last_row, width_pct: 0.5
115
+ @pane_2.view(subject: @ship.empty_node)
116
+ @pane_2.highlight = false
117
+
118
+ # The node list is a variable width, fixed height pane in the upper right.
119
+ @pane_3 = @viewport.add_variable_width_pane at_col: @pane_1.last_col, height_pct: 0.5
120
+ @pane_3.view(subject: @ship.empty_node_list)
121
+
122
+ # The single node viewer is a variable width, variable height pane in the lower right.
123
+ @pane_4 = @viewport.add_variable_both_pane at_row: @pane_3.last_row, at_col: @pane_1.last_col
124
+ @pane_4.view(subject: @ship.empty_node)
125
+ @pane_4.highlight = false
126
+ end
127
+ end
128
+ end
@@ -3,13 +3,14 @@ require 'curses'
3
3
 
4
4
  module MarsBase10
5
5
  class Pane
6
- attr_accessor :draw_row, :draw_col, :index, :latch, :subject
6
+ attr_accessor :draw_row, :draw_col, :highlight, :index, :latch, :subject
7
7
  attr_reader :height_pct, :left_edge_col, :top_row, :viewport, :width_pct
8
8
 
9
9
  def initialize(viewport:, at_row:, at_col:, height_pct: 1, width_pct: 1)
10
10
  @top_row = at_row
11
11
  @left_edge_col = at_col
12
12
  @height_pct = height_pct
13
+ @highlight = true
13
14
  @index = 1
14
15
  @latch = ''
15
16
  @latch_depth = 0
@@ -48,10 +49,10 @@ module MarsBase10
48
49
  (first_draw_row..last_draw_row).each do |index|
49
50
  self.draw_line
50
51
  item_index = index + @visible_content_shift
51
- self.window.attron(Curses::A_REVERSE) if item_index == self.index
52
+ self.window.attron(Curses::A_REVERSE) if (item_index == self.index) && self.highlight
52
53
 
53
54
  if self.subject.line_length_at(index: item_index) > self.last_col
54
- chunks = self.subject.line_at(index: item_index).chars.each_slice(self.last_col).map(&:join)
55
+ chunks = self.subject.line_at(index: item_index).chars.each_slice(self.last_col - 2).map(&:join)
55
56
  chunks.each do |c|
56
57
  self.window.addstr(c)
57
58
  self.draw_row += 1
@@ -63,7 +64,7 @@ module MarsBase10
63
64
  self.window.addstr("#{self.subject.line_at(index: item_index)}")
64
65
  end
65
66
 
66
- self.window.attroff(Curses::A_REVERSE) if item_index == self.index
67
+ self.window.attroff(Curses::A_REVERSE) if (item_index == self.index) && self.highlight
67
68
  self.window.clrtoeol
68
69
  self.draw_row += 1
69
70
  end
@@ -244,6 +245,16 @@ module MarsBase10
244
245
  end
245
246
  end
246
247
 
248
+ class VariableHeightPane < Pane
249
+ def last_col
250
+ (self.viewport.max_cols * self.width_pct).floor
251
+ end
252
+
253
+ def last_row
254
+ self.viewport.max_rows - self.top_row
255
+ end
256
+ end
257
+
247
258
  class VariableWidthPane < Pane
248
259
  def last_col
249
260
  self.viewport.max_cols - self.left_edge_col
@@ -20,6 +20,44 @@ module MarsBase10
20
20
  Subject.new title: 'Graphs', contents: @ship.graph_names
21
21
  end
22
22
 
23
+ def group_names
24
+ Subject.new title: 'Groups', contents: (@ship.groups.map {|g| g.to_list})
25
+ end
26
+
27
+ def fetch_channel(group_title:, channel_title:)
28
+ if (group = @ship.groups[title: group_title])
29
+ if (channel = group.graphs.select {|c| channel_title == c.title unless c.nil?}.first)
30
+ # What we are calling a channel here is really a graph in the urbit-ruby bridge.
31
+ # This is the equivalent of node.to_pretty_array
32
+ props = {
33
+ title: channel.title,
34
+ description: channel.description,
35
+ creator: channel.creator,
36
+ host_ship: channel.host_ship,
37
+ resource: channel.resource,
38
+ type: channel.type
39
+ }
40
+ return props.each.map {|k, v| "#{k}#{(' ' * [(18 - k.length), 0].max)}#{v}"}
41
+ end
42
+ end
43
+ ["Group not found."]
44
+ end
45
+
46
+ def fetch_group(group_title:)
47
+ if (group = @ship.groups[title: group_title])
48
+ # This is the equivalent of node.to_pretty_array
49
+ return group.to_h.each.map {|k, v| "#{k}#{(' ' * [(18 - k.length), 0].max)}#{v}"}
50
+ end
51
+ ["Group not found."]
52
+ end
53
+
54
+ def fetch_group_channels(group_title:)
55
+ if (group = @ship.groups[title: group_title])
56
+ return group.graphs.map {|g| g.nil? ? "Unnamed" : g.title}
57
+ end
58
+ ["No Channels Available."]
59
+ end
60
+
23
61
  def fetch_node(resource:, index:)
24
62
  @ship.graph(resource: resource).node(index: index)
25
63
  end
@@ -27,6 +27,10 @@ module MarsBase10
27
27
  @contents = a_contents_array
28
28
  end
29
29
 
30
+ def empty?
31
+ self.contents.empty?
32
+ end
33
+
30
34
  def index_width
31
35
  [self.item_count.to_s.length, 2].max
32
36
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MarsBase10
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -70,15 +70,6 @@ module MarsBase10
70
70
  @active_pane = p
71
71
  end
72
72
 
73
- def add_variable_width_pane(at_row: self.min_row, at_col: self.min_col, height_pct:)
74
- p = VariableWidthPane.new viewport: self,
75
- at_row: at_row,
76
- at_col: at_col,
77
- height_pct: height_pct
78
- @panes << p
79
- p
80
- end
81
-
82
73
  #
83
74
  # Adds a new variable width drawable area (VariableBothPane) to the
84
75
  # right-hand side of the viewport.
@@ -95,6 +86,24 @@ module MarsBase10
95
86
  p
96
87
  end
97
88
 
89
+ def add_variable_height_pane(at_row:, width_pct:)
90
+ p = VariableHeightPane.new viewport: self,
91
+ at_row: at_row,
92
+ at_col: self.min_col,
93
+ width_pct: width_pct
94
+ @panes << p
95
+ p
96
+ end
97
+
98
+ def add_variable_width_pane(at_row: self.min_row, at_col: self.min_col, height_pct:)
99
+ p = VariableWidthPane.new viewport: self,
100
+ at_row: at_row,
101
+ at_col: at_col,
102
+ height_pct: height_pct
103
+ @panes << p
104
+ p
105
+ end
106
+
98
107
  def close
99
108
  Curses.close_screen
100
109
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mars_base_10
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daryl Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-10 00:00:00.000000000 Z
11
+ date: 2022-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -152,6 +152,7 @@ files:
152
152
  - lib/mars_base_10/cli.rb
153
153
  - lib/mars_base_10/comm_central.rb
154
154
  - lib/mars_base_10/graph_rover.rb
155
+ - lib/mars_base_10/group_room.rb
155
156
  - lib/mars_base_10/pane.rb
156
157
  - lib/mars_base_10/ship.rb
157
158
  - lib/mars_base_10/stack.rb