iconofthestoneage-doodl 0.0.2 → 0.0.4

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.
Files changed (42) hide show
  1. data/lib/app/selfrunning.rb +185 -0
  2. data/lib/app/simple_app.rb +49 -0
  3. data/lib/app/simple_controller.rb +584 -0
  4. data/lib/app/simple_model.rb +292 -0
  5. data/lib/app/simple_view.rb +148 -0
  6. data/lib/breadth_first_search.rb +69 -0
  7. data/lib/connected_components.rb +29 -0
  8. data/lib/depth_first_search.rb +73 -0
  9. data/lib/edge.rb +57 -0
  10. data/lib/graph.rb +365 -0
  11. data/lib/graph_canvas.rb +187 -0
  12. data/lib/graph_generator.rb +121 -0
  13. data/lib/jruby/renderer.rb +413 -0
  14. data/lib/layout/collapse_layout.rb +23 -0
  15. data/lib/layout/fr_layout.rb +105 -0
  16. data/lib/layout/isom_layout.rb +77 -0
  17. data/lib/layout/kk_layout.rb +203 -0
  18. data/lib/layout/layout.rb +240 -0
  19. data/lib/layout/morph_layout.rb +65 -0
  20. data/lib/node.rb +57 -0
  21. data/lib/shortest_path/all_pair.rb +35 -0
  22. data/lib/shortest_path/bellman_ford.rb +60 -0
  23. data/lib/shortest_path/dijkstra.rb +74 -0
  24. data/lib/shortest_path/floyd_warshall.rb +68 -0
  25. data/lib/shortest_path/johnson_all_pair.rb +64 -0
  26. data/lib/shortest_path/single_source.rb +32 -0
  27. data/spec/breadth_first_search_spec.rb +145 -0
  28. data/spec/connected_components_spec.rb +50 -0
  29. data/spec/depth_first_search_spec.rb +89 -0
  30. data/spec/edge_spec.rb +58 -0
  31. data/spec/graph_generator_spec.rb +277 -0
  32. data/spec/graph_spec.rb +269 -0
  33. data/spec/jruby/renderer_spec.rb +214 -0
  34. data/spec/layout/layout_spec.rb +146 -0
  35. data/spec/node_spec.rb +179 -0
  36. data/spec/rspec_helper.rb +9 -0
  37. data/spec/rspec_suite.rb +12 -0
  38. data/spec/shortest_path/bellman_ford_spec.rb +101 -0
  39. data/spec/shortest_path/dijkstra_spec.rb +133 -0
  40. data/spec/shortest_path/floyd_warshall_spec.rb +84 -0
  41. data/spec/shortest_path/johnson_all_pair_spec.rb +90 -0
  42. metadata +43 -2
@@ -0,0 +1,185 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require "java"
4
+
5
+ require "logger"
6
+
7
+ require "graph"
8
+ require "jruby/renderer"
9
+ require "layout/layout"
10
+ require "layout/fr_layout"
11
+ require "layout/isom_layout"
12
+ require "layout/kk_layout"
13
+ require "shortest_path/dijkstra"
14
+
15
+ include Doodl
16
+
17
+ include_class 'javax.swing.JFrame'
18
+ include_class 'javax.swing.JLabel'
19
+ include_class 'java.awt.Dimension'
20
+ include_class 'java.awt.Color'
21
+ include_class 'java.awt.geom.Rectangle2D'
22
+
23
+ $LOG = Logger.new(STDOUT)
24
+ $LOG.sev_threshold = Logger::INFO
25
+
26
+ class Runner
27
+ def initialize(renderer)
28
+ @renderer = renderer
29
+ end
30
+ def update(observable)
31
+ @renderer.update_layout(observable)
32
+ end
33
+ end
34
+
35
+ frame = JFrame.new("Doodl: Graph Drawing with Ruby")
36
+
37
+ renderer = PluggableRenderer.new
38
+ renderer.paint_iterations = false
39
+ renderer.setPreferredSize(Dimension.new(800, 600))
40
+
41
+ label = JLabel.new("Doodl Graph Drawing!")
42
+ label.setOpaque(true)
43
+ label.setBackground(java.awt.Color::BLACK)
44
+ label.setForeground(java.awt.Color::WHITE)
45
+ label.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10))
46
+
47
+ frame.getContentPane().add(renderer, java.awt.BorderLayout::CENTER)
48
+ frame.getContentPane().add(label, java.awt.BorderLayout::SOUTH)
49
+ frame.pack
50
+ frame.setVisible(true)
51
+
52
+ graph = UndirectedGraph.new
53
+ graph.gen_random_graph(7, 10)
54
+
55
+ runner = Runner.new(renderer)
56
+
57
+
58
+
59
+ layouts = [RandomLayout, CircleLayout, FRLayout, ISOMLayout, KKLayout]
60
+
61
+ layouts.each do |lc|
62
+ l = lc.new(renderer)
63
+ l.graph = graph
64
+ l.add_observer(runner)
65
+ l.layout
66
+ label.setText("Undirected Graph - Layout: #{l.class}")
67
+ sleep(1)
68
+ end
69
+
70
+ graph.gen_ring_graph(10)
71
+ layout = ISOMLayout.new(renderer)
72
+ layout.graph = graph
73
+ layout.add_observer(runner)
74
+ layout.layout
75
+ label.setText("Graph Generator: Ring")
76
+ sleep(1)
77
+
78
+ graph.gen_linear_graph(5)
79
+ layout.layout
80
+ label.setText("Graph Generator: Linear")
81
+ sleep(1)
82
+
83
+ graph.gen_connected_graph(6)
84
+ layout.layout
85
+ label.setText("Graph Generator: Connected")
86
+ sleep(1)
87
+
88
+ graph.gen_mesh_graph(3)
89
+ layout.layout
90
+ label.setText("Graph Generator: Mesh")
91
+ sleep(1)
92
+
93
+ graph.gen_binary_tree(2)
94
+ layout.layout
95
+ label.setText("Graph Generator: Binary Tree")
96
+ sleep(1)
97
+
98
+ layout = FRLayout.new(renderer)
99
+ layout.add_observer(runner)
100
+ graph = DirectedGraph.new
101
+
102
+ graph.gen_random_graph(5, 10)
103
+ layout.graph = graph
104
+ layout.layout
105
+ label.setText("A Directed Graph")
106
+ sleep(1)
107
+
108
+ renderer.node_stroke_color_function { java.awt.Color::BLUE }
109
+ renderer.repaint
110
+ label.setText("Customize PluggableRenderer (node_stroke_color)")
111
+ sleep(1)
112
+ renderer.node_stroke_color_function { |g,l,n| if n.out_degree > 2 then Color::BLUE else Color::WHITE end}
113
+ renderer.repaint
114
+ sleep(1)
115
+ label.setText("You can define a function that defines the stoke color (e.g. if out_degree >2 then blue else white)")
116
+ renderer.node_shape_function { |g, l, n| Rectangle2D::Double.new(l[n].x-10, l[n].y-10, 20, 20) }
117
+ renderer.repaint
118
+ sleep(1)
119
+ label.setText("Customize PluggableRenderer (node_shape)")
120
+ label.setText("Zoom in and out")
121
+ 10.times do
122
+ renderer.zoom(0.9)
123
+ sleep(0.5)
124
+ end
125
+ label.setText("Zoom absolute (e.g. 100%)")
126
+ renderer.zoom_absolute(1.0)
127
+ sleep(1)
128
+ label.setText("Center on a node")
129
+ graph.nodes.each do |node|
130
+ renderer.node_stroke_color_function { |g,l,n| if node == n then Color::BLUE else Color::WHITE end }
131
+ renderer.center_on_node(node)
132
+ sleep(0.5)
133
+ end
134
+ renderer.node_stroke_color_function { |g,l,n| if n.out_degree > 2 then Color::BLUE else Color::WHITE end}
135
+
136
+ begin
137
+ renderer.set_defaults
138
+ graph.gen_binary_tree(3)
139
+
140
+ source = graph.nodes[1]
141
+ target = graph.nodes.last
142
+
143
+ stdata = graph.attach_node_data(:start)
144
+ stdata[source] = true
145
+ endata = graph.attach_node_data(:end)
146
+ endata[target] = true
147
+
148
+ dsp = DijkstraShortestPath.new(graph, source)
149
+ npath = dsp.node_path_to(target)
150
+ epath = dsp.edge_path_to(target)
151
+
152
+ edata = graph.attach_edge_data(:path)
153
+ epath.each do |e|
154
+ edata[e] = true
155
+ end
156
+ ndata = graph.attach_node_data(:path)
157
+ npath.each do |n|
158
+ ndata[n] = true
159
+ end
160
+
161
+ renderer.edge_stroke_function do |g, l, e|
162
+ if g.edge_data(:path) and g.edge_data(:path)[e]
163
+ BasicStroke.new(4)
164
+ else
165
+ BasicStroke.new(2)
166
+ end
167
+ end
168
+ renderer.node_stroke_color_function do |g, l, n|
169
+ if g.node_data(:start) and g.node_data(:start)[n]
170
+ Color::GREEN
171
+ elsif g.node_data(:end) and g.node_data(:end)[n]
172
+ Color::YELLOW
173
+ elsif g.node_data(:path) and g.node_data(:path)[n]
174
+ Color::BLUE
175
+ else
176
+ Color::WHITE
177
+ end
178
+ end
179
+
180
+ layout = KKLayout.new(renderer)
181
+ layout.add_observer(runner)
182
+ layout.layout(graph)
183
+ label.setText("You can use the PluggabeRender features to highlight a shortest path!")
184
+ end
185
+
@@ -0,0 +1,49 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
2
+
3
+ require 'java'
4
+
5
+ require 'logger'
6
+
7
+ require 'renderer'
8
+
9
+ require 'app/simple_controller'
10
+ require 'app/simple_view'
11
+ require 'app/simple_model'
12
+
13
+
14
+ require "layout/layout"
15
+
16
+ include Doodl
17
+
18
+ $LOG = Logger.new(STDOUT)
19
+ $LOG.sev_threshold = Logger::INFO
20
+ @view = SimpleView.new
21
+ @model = SimpleModel.new
22
+ controller = SimpleController.new
23
+
24
+ #setup view
25
+ @canvas = PluggableRenderer.new
26
+ @canvas.setPreferredSize(java.awt.Dimension.new(800, 600))
27
+
28
+
29
+ frame = javax.swing.JFrame.new("Graph Doodl App")
30
+ frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE);
31
+ frame.getContentPane().add(@canvas)
32
+ frame.pack
33
+ frame.setVisible(true)
34
+
35
+ @view.canvas = @canvas
36
+ @view.frame = frame
37
+
38
+ #setup model
39
+
40
+ #setup controller
41
+
42
+ #glueing
43
+ controller.view = @view
44
+ @model.view = @view
45
+ @model.add_observer(@view)
46
+ controller.model = @model
47
+
48
+ @model.set_random_layout
49
+ #model.new_connected_graph(5)
@@ -0,0 +1,584 @@
1
+ require 'java'
2
+
3
+ include_class 'java.awt.event.KeyListener'
4
+ include_class 'java.awt.event.KeyEvent'
5
+ include_class 'java.awt.event.MouseListener'
6
+ include_class 'java.awt.event.MouseMotionListener'
7
+ include_class 'java.awt.event.ActionListener'
8
+
9
+ module AppActionListener
10
+ include ActionListener
11
+
12
+ def actionPerformed(event)
13
+ end
14
+ end
15
+
16
+ module AppMouseListener
17
+ include MouseListener
18
+
19
+ def mouseEntered(event)
20
+ end
21
+
22
+ def mouseExited(event)
23
+ end
24
+
25
+ def mousePressed(event)
26
+ end
27
+
28
+ def mouseReleased(event)
29
+ end
30
+
31
+ def mouseClicked(event)
32
+ end
33
+ end
34
+
35
+ module AppMouseMotionListener
36
+ include MouseMotionListener
37
+
38
+ def mouseDragged(event)
39
+ end
40
+
41
+ def mouseMoved(event)
42
+ end
43
+ end
44
+
45
+ module AppKeyListener
46
+ include KeyListener
47
+
48
+ def keyPressed(event)
49
+ end
50
+
51
+ def keyReleased(event)
52
+ end
53
+
54
+ def keyTyped(event)
55
+ end
56
+ end
57
+
58
+ class SimpleController
59
+
60
+ attr_reader :view, :model
61
+
62
+ def view=(view)
63
+ @view = view
64
+ @view.add_key_listener(MainKeyListener.new(self))
65
+ end
66
+
67
+ def model=(model)
68
+ @model = model
69
+ end
70
+
71
+ def add_node
72
+ @view.add_mouse_listener(AddNodeMouseListener.new(self))
73
+ end
74
+
75
+ def del_node
76
+ @view.add_mouse_listener(DelNodeMouseListener.new(self))
77
+ end
78
+
79
+ def add_edge
80
+ @view.add_mouse_listener(AddEdgeMouseListener.new(self))
81
+ end
82
+
83
+ def del_edge
84
+ @view.add_mouse_listener(DelEdgeMouseListener.new(self))
85
+ end
86
+
87
+ def move_node
88
+ listener = MoveNodeMouseListener.new(self)
89
+ @view.add_mouse_motion_listener(listener)
90
+ @view.add_mouse_listener(listener)
91
+ end
92
+
93
+ def choose_layout
94
+ @view.add_info_panel("Select Layout. Enter Type [Random, Circle, FR, ISOM]")
95
+ @view.add_text_field(LayoutActionListener.new(self))
96
+ end
97
+
98
+ def choose_generator
99
+ @view.add_info_panel("Generate Graph. Enter Generation Mode [Random <s>, Linear <s>, Ring <s>, Mesh <r>, Connected <s>]")
100
+ @view.add_text_field(GenerateGraphActionListener.new(self))
101
+ end
102
+
103
+ def choose_graph_type
104
+ @view.add_info_panel("Choose graph type: [directed, undirected]")
105
+ @view.add_text_field(GraphTypeActionListener.new(self))
106
+ end
107
+
108
+ def do_layout
109
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
110
+ end
111
+
112
+ def new_graph
113
+ @model.new_empty_graph
114
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
115
+ end
116
+
117
+ def new_layout
118
+ end
119
+
120
+ def generate_graph
121
+ end
122
+
123
+ def select_node
124
+
125
+ end
126
+
127
+ def set_random_layout
128
+ @model.set_random_layout
129
+ @model.layout.layout
130
+ end
131
+
132
+ def set_circle_layout
133
+ @model.set_circle_layout
134
+ @model.layout.layout
135
+ end
136
+
137
+ def set_fr_layout
138
+ @model.set_fr_layout
139
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
140
+ end
141
+
142
+ def set_isom_layout
143
+ @model.set_isom_layout
144
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
145
+ end
146
+
147
+ def set_kk_layout
148
+ @model.set_kk_layout
149
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
150
+ end
151
+
152
+ def set_morph_layout(target_layout_class)
153
+ @model.set_morph_layout(target_layout_class)
154
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
155
+ end
156
+
157
+ def set_collapse_layout
158
+ @model.set_collapse_layout
159
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
160
+ end
161
+
162
+ def set_random(size)
163
+ @model.new_random_graph(size)
164
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
165
+ end
166
+
167
+ def set_ring(size)
168
+ @model.new_ring_graph(size)
169
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
170
+ end
171
+
172
+ def set_bintree(size)
173
+ @model.new_binary_tree(size)
174
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
175
+ end
176
+
177
+ def set_connected(size)
178
+ @model.new_connected_graph(size)
179
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
180
+ end
181
+
182
+ def set_linear(size)
183
+ @model.new_linear_graph(size)
184
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
185
+ end
186
+
187
+ def set_mesh(rows)
188
+ @model.new_mesh_graph(rows)
189
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
190
+ end
191
+
192
+ def print_info
193
+ puts @controller.model.layout
194
+ puts @controller.model.graph
195
+ end
196
+
197
+ def shortest_path
198
+ @view.add_mouse_listener(ShortestPathMouseListener.new(self))
199
+ end
200
+
201
+ def shortest_tree
202
+ @view.add_mouse_listener(ShortestTreeMouseListener.new(self))
203
+ end
204
+
205
+ def count_nodes
206
+ @model.count_nodes
207
+ end
208
+
209
+ def toggle_paint_iterations
210
+ @view.toggle_paint_iterations
211
+ $LOG.info "PluggableRenderer: paint_iterations? #{@view.canvas.paint_iterations?}"
212
+ end
213
+
214
+ def rotate_layout_right
215
+ @model.rotate_layout(2)
216
+ end
217
+
218
+ def rotate_layout_left
219
+ @model.rotate_layout(-2)
220
+ end
221
+
222
+ def move_layout_left
223
+ @model.move_layout(-5, 0)
224
+ end
225
+
226
+ def move_layout_right
227
+ @model.move_layout(5, 0)
228
+ end
229
+
230
+ def move_layout_up
231
+ @model.move_layout(0, -5)
232
+ end
233
+
234
+ def move_layout_down
235
+ @model.move_layout(0, 5)
236
+ end
237
+
238
+ def center_x
239
+ @model.center_x
240
+ end
241
+
242
+ def center_y
243
+ @model.center_y
244
+ end
245
+
246
+ end
247
+
248
+ class MainKeyListener
249
+ include AppKeyListener
250
+
251
+ def initialize(controller)
252
+ @controller = controller
253
+ end
254
+
255
+ def keyPressed(event)
256
+ case event.getKeyCode
257
+ when KeyEvent::VK_RIGHT
258
+ if event.isShiftDown
259
+ @controller.rotate_layout_right
260
+ else
261
+ @controller.move_layout_right
262
+ end
263
+ when KeyEvent::VK_LEFT
264
+ if event.isShiftDown
265
+ @controller.rotate_layout_left
266
+ else
267
+ @controller.move_layout_left
268
+ end
269
+ when KeyEvent::VK_UP
270
+ @controller.move_layout_up
271
+ when KeyEvent::VK_DOWN
272
+ @controller.move_layout_down
273
+ end
274
+ end
275
+
276
+ def keyTyped(event)
277
+ case event.key_char.chr
278
+ when 'a'
279
+ @controller.add_node
280
+ when 'c'
281
+ @controller.count_nodes
282
+ when 'd'
283
+ @controller.del_node
284
+ when 'u'
285
+ @controller.del_edge
286
+ when 'e'
287
+ @controller.add_edge
288
+ when 'n'
289
+ @controller.new_graph
290
+ when 'g'
291
+ @controller.choose_generator
292
+ when 'l'
293
+ @controller.choose_layout
294
+ when 'r'
295
+ @controller.do_layout
296
+ when 'i'
297
+ @controller.toggle_paint_iterations
298
+ when 's'
299
+ @controller.select_nodes
300
+ when 'm'
301
+ @controller.move_node
302
+ when 'p'
303
+ @controller.shortest_path
304
+ when 't'
305
+ @controller.shortest_tree
306
+ when 't'
307
+ @controller.choose_graph_type
308
+ when 'x'
309
+ @controller.center_x
310
+ when 'y'
311
+ @controller.center_y
312
+ end
313
+ end
314
+ end
315
+
316
+ class AddNodeMouseListener
317
+ include AppMouseListener
318
+
319
+ def initialize(controller)
320
+ @controller = controller
321
+ end
322
+
323
+ def mousePressed(event)
324
+ @node = @controller.model.add_node_at(event.x, event.y)
325
+ @controller.model.click(@node)
326
+ end
327
+
328
+ def mouseReleased(event)
329
+ @controller.model.unclick(@node) if @node
330
+ @controller.view.remove_mouse_listener(self)
331
+ end
332
+ end
333
+
334
+ class AddEdgeMouseListener
335
+ include AppMouseListener
336
+
337
+ def initialize(controller)
338
+ @controller = controller
339
+ end
340
+
341
+ def mousePressed(event)
342
+ if (!@first)
343
+ @first = @controller.model.get_nearest_node(event.x, event.y)
344
+ @controller.model.click(@first)
345
+ else
346
+ @second = @controller.model.get_nearest_node(event.x, event.y)
347
+ @controller.model.click(@second)
348
+ @edge = @controller.model.add_edge(@first, @second)
349
+ @controller.model.click_edge(@edge)
350
+ end
351
+ end
352
+
353
+ def mouseReleased(event)
354
+ @controller.model.unclick(@first) if @first
355
+ @controller.model.unclick_edge(@edge) if @edge
356
+ if @second
357
+ @controller.view.remove_mouse_listener(self)
358
+ @controller.model.unclick(@second) if @second
359
+ end
360
+ end
361
+ end
362
+
363
+ class DelEdgeMouseListener
364
+ include AppMouseListener
365
+
366
+ def initialize(controller)
367
+ @controller = controller
368
+ end
369
+
370
+ def mousePressed(event)
371
+ if (!@first)
372
+ @first = @controller.model.get_nearest_node(event.x, event.y)
373
+ @controller.model.click(@first)
374
+ else
375
+ @second = @controller.model.get_nearest_node(event.x, event.y)
376
+ @controller.model.click(@second)
377
+ @controller.model.click(@first)
378
+ @edge = @controller.model.get_edge(@first, @second)
379
+ @controller.model.click_edge(@edge) if @edge
380
+ end
381
+ end
382
+
383
+ def mouseReleased(event)
384
+ @controller.model.unclick(@first) if @first
385
+ if @second
386
+ @controller.view.remove_mouse_listener(self)
387
+ @controller.model.unclick(@second)
388
+ @controller.model.unclick_edge(@edge) if @edge
389
+ @controller.model.del_edge(@edge) if @edge
390
+ end
391
+ end
392
+ end
393
+
394
+ class MoveNodeMouseListener
395
+ include AppMouseMotionListener
396
+ include AppMouseListener
397
+
398
+ def initialize(controller)
399
+ @controller = controller
400
+ end
401
+
402
+ def mousePressed(event)
403
+ node = @controller.model.get_nearest_node(event.x, event.y)
404
+ @controller.model.click(node)
405
+ end
406
+
407
+ def mouseDragged(event)
408
+ if (!@node)
409
+ @node = @controller.model.get_nearest_node(event.x, event.y)
410
+ location = @controller.model.layout[@node]
411
+ @delta_x = location.x - event.x
412
+ @delta_y = location.y - event.y
413
+ end
414
+ @controller.model.set_location(@node, (event.x + @delta_x), (event.y + @delta_y))
415
+
416
+ end
417
+
418
+ def mouseReleased(event)
419
+ @controller.model.unclick(@node)
420
+ @controller.view.remove_mouse_listener(self)
421
+ @controller.view.remove_mouse_motion_listener(self)
422
+ end
423
+ end
424
+
425
+ class DelNodeMouseListener
426
+ include AppMouseListener
427
+
428
+ def initialize(controller)
429
+ @controller = controller
430
+ end
431
+
432
+ def mousePressed(event)
433
+ @node = @controller.model.get_nearest_node(event.x, event.y)
434
+ @controller.model.click(@node)
435
+ end
436
+
437
+ def mouseReleased(event)
438
+ if @node
439
+ @controller.model.unclick(@node)
440
+ @controller.model.del_node(@node)
441
+ end
442
+ @controller.view.remove_mouse_listener(self)
443
+ end
444
+
445
+ end
446
+
447
+ class ShortestTreeMouseListener
448
+ include AppMouseListener
449
+
450
+ def initialize(controller)
451
+ @controller = controller
452
+ end
453
+
454
+ def mousePressed(event)
455
+ @node = @controller.model.get_nearest_node(event.x, event.y)
456
+ @controller.model.click(@node)
457
+ end
458
+
459
+ def mouseReleased(event)
460
+ if @node
461
+ @controller.model.unclick(@node)
462
+ @controller.model.dspt(@node)
463
+ end
464
+ @controller.view.remove_mouse_listener(self)
465
+ end
466
+
467
+ end
468
+
469
+ class ShortestPathMouseListener
470
+ include AppMouseListener
471
+
472
+ def initialize(controller)
473
+ @controller = controller
474
+ end
475
+
476
+ def mousePressed(event)
477
+ if (!@first)
478
+ @first = @controller.model.get_nearest_node(event.x, event.y)
479
+ @controller.model.click(@first)
480
+ else
481
+ @second = @controller.model.get_nearest_node(event.x, event.y)
482
+ @controller.model.click(@second)
483
+ @controller.model.click(@first)
484
+ end
485
+ end
486
+
487
+ def mouseReleased(event)
488
+ if @first
489
+ @controller.model.unclick(@first)
490
+ if @second
491
+ @controller.model.unclick(@second)
492
+ @controller.view.remove_mouse_listener(self)
493
+ @controller.model.dsp(@first, @second)
494
+ end
495
+ end
496
+ end
497
+
498
+ end
499
+
500
+ class LayoutActionListener
501
+ def initialize(controller)
502
+ @controller = controller
503
+ end
504
+
505
+ def actionPerformed(event)
506
+ return_value = event.getSource.getText
507
+ a = return_value.split
508
+ case a[0].downcase
509
+ when 'random'
510
+ @controller.set_random_layout
511
+ when 'circle'
512
+ @controller.set_circle_layout
513
+ when 'fr'
514
+ @controller.set_fr_layout
515
+ when 'isom'
516
+ @controller.set_isom_layout
517
+ when 'kk'
518
+ @controller.set_kk_layout
519
+ when 'collapse'
520
+ @controller.set_collapse_layout
521
+ when 'morph'
522
+ @controller.set_morph_layout(a[1])
523
+ else
524
+ puts "Wrong Argument"
525
+ end
526
+ @controller.view.remove_text_field
527
+ @controller.view.remove_info_panel
528
+ end
529
+ end
530
+
531
+ class GenerateGraphActionListener
532
+ def initialize(controller)
533
+ @controller = controller
534
+ end
535
+
536
+ def actionPerformed(event)
537
+ return_value = event.source.getText
538
+ a = return_value.split
539
+ if a.size == 2 and a[1].to_i != 0
540
+ case a[0].downcase
541
+ when "random"
542
+ @controller.set_random(a[1].to_i)
543
+ when "bintree"
544
+ @controller.set_bintree(a[1].to_i)
545
+ when "ring"
546
+ @controller.set_ring(a[1].to_i)
547
+ when "connected"
548
+ @controller.set_connected(a[1].to_i)
549
+ when "mesh"
550
+ @controller.set_mesh(a[1].to_i)
551
+ when "linear"
552
+ @controller.set_linear(a[1].to_i)
553
+ else
554
+ puts "No Generator #{a[0]}"
555
+ end
556
+ else
557
+ puts "Wrong Syntax"
558
+ end
559
+ @controller.view.remove_text_field
560
+ @controller.view.remove_info_panel
561
+ end
562
+
563
+ end
564
+
565
+ class GraphTypeActionListener
566
+ def initialize(controller)
567
+ @controller = controller
568
+ end
569
+
570
+ def actionPerformed(event)
571
+ return_value = event.getSource.getText
572
+ case return_value.downcase
573
+ when 'directed'
574
+ @controller.model.set_directed
575
+ when 'undirected'
576
+ @controller.model.set_undirected
577
+ else
578
+ puts "Wrong Argument"
579
+ end
580
+ @controller.view.remove_text_field
581
+ @controller.view.remove_info_panel
582
+ end
583
+ end
584
+