/[eiffelstudio]/branches/Eiffel_57_docking/Src/Eiffel/interface/new_graphical/case_tool/eiffel_view/inheritance_layout.e
ViewVC logotype

Contents of /branches/Eiffel_57_docking/Src/Eiffel/interface/new_graphical/case_tool/eiffel_view/inheritance_layout.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62171 - (show annotations)
Tue Aug 1 01:27:17 2006 UTC (13 years, 4 months ago) by larryl
File size: 13740 byte(s)
First commit docking tabbed Eiffel Studio.
1 indexing
2 description: "Placement of class bubbles in a EIFFEL_WORLD."
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 date: "$Date$"
6 revision: "$Revision$"
7
8 class
9 EIFFEL_INHERITANCE_LAYOUT
10
11 inherit
12 EG_LAYOUT
13 redefine
14 default_create,
15 world
16 end
17
18 create
19 make_with_world
20
21 feature {NONE} -- Initialization
22
23 default_create is
24 -- Initialize `table'.
25 do
26 create table.make (20)
27 vertical_spacing := {EB_DIAGRAM_TOOL}.default_bon_vertical_spacing
28 horizontal_spacing := {EB_DIAGRAM_TOOL}.default_bon_horizontal_spacing
29 end
30
31 feature -- Access
32
33 table: ARRAYED_LIST [like row]
34 -- List of rows of class bubbles.
35
36 vertical_spacing: INTEGER
37 -- Vertical space between class figures.
38
39 horizontal_spacing: INTEGER
40 -- Horizontal space between class figures.
41
42 world: EIFFEL_WORLD
43
44 feature -- Element change
45
46 set_spacing (horizontal, vertical: INTEGER) is
47 -- Set `horizontal_spacing' to `horizontal' and `vertical_spacing' to `vertical'.
48 do
49 horizontal_spacing := horizontal
50 vertical_spacing := vertical
51 ensure
52 spacings_set: horizontal_spacing = horizontal and vertical_spacing = vertical
53 end
54
55 feature {NONE} -- Implementation
56
57 vertical_scaled_spacing: INTEGER
58 horizontal_scaled_spacing: INTEGER
59
60 row: ARRAYED_LIST [EG_LINKABLE_FIGURE] is
61 -- To use `like row'.
62 do
63 -- Never called.
64 check
65 False
66 end
67 end
68
69 layout_linkables (linkables: ARRAYED_LIST [EG_LINKABLE_FIGURE]; level: INTEGER; cluster: EG_CLUSTER_FIGURE) is
70 -- arrange `linkables' that are elements of `clusters' at `level'.
71 local
72 bcf: EIFFEL_CLUSTER_FIGURE
73 ew: EIFFEL_WORLD
74 do
75 ew := world
76 vertical_scaled_spacing := (ew.scale_factor * vertical_spacing).truncated_to_integer
77 horizontal_scaled_spacing := (ew.scale_factor * horizontal_spacing).truncated_to_integer
78
79 table.wipe_out
80 set_clusters_and_classes (linkables)
81 if not has_cluster then
82 arrange_by_generation
83 arrange_clients
84 else
85 arrange_by_size
86 end
87 execute
88 bcf ?= cluster
89 if bcf /= Void then
90 --Speeeeeeeeed Up
91 ew.update
92 bcf.set_to_minimum_size
93 end
94 if ew.is_right_angles then
95 ew.apply_right_angles
96 end
97 end
98
99 clusters: ARRAYED_LIST [EG_CLUSTER_FIGURE]
100 -- Clusters in linkables currently layouted.
101
102 classes: ARRAYED_LIST [EG_LINKABLE_FIGURE]
103 -- Classes in linkables currently layouted.
104
105 set_clusters_and_classes (linkables: ARRAYED_LIST [EG_LINKABLE_FIGURE]) is
106 -- Build list `clusters' and `classes'.
107 require
108 linkables_not_void: linkables /= Void
109 local
110 i, nb: INTEGER
111 cf: EG_CLUSTER_FIGURE
112 l_item: EG_LINKABLE_FIGURE
113 do
114 create clusters.make (linkables.count)
115 create classes.make (linkables.count)
116 from
117 i := 1
118 nb := linkables.count
119 until
120 i > nb
121 loop
122 l_item := linkables.i_th (i)
123 if l_item.is_show_requested then
124 cf ?= l_item
125 if cf /= Void then
126 clusters.extend (cf)
127 else
128 classes.extend (l_item)
129 end
130 end
131 i := i + 1
132 end
133 ensure
134 clusters_not_void: clusters /= Void
135 classes_not_void: classes /= Void
136 end
137
138 has_cluster: BOOLEAN is
139 -- Is `clusters' not empty?
140 require
141 clusters_not_void: clusters /= Void
142 do
143 Result := not clusters.is_empty
144 end
145
146 has_classes: BOOLEAN is
147 -- Is `classes' not empty?
148 require
149 classes_not_void: classes /= Void
150 do
151 Result := not classes.is_empty
152 end
153
154 arrange_by_size is
155 -- Place figures such that space is
156 -- not wasted in the diagram.
157 local
158 i, nb: INTEGER
159 do
160 arrange_by_generation
161 arrange_clients
162
163 from
164 i := 1
165 nb := clusters.count
166 until
167 i > nb
168 loop
169 add_linkable_figure (clusters.i_th (i))
170 i := i + 1
171 end
172 end
173
174 add_linkable_figure (lf: EG_LINKABLE_FIGURE) is
175 -- Add `lf' in any row/column not caring about links.
176 local
177 r: like row
178 do
179 if height > width // 2 then
180 r := smallest_row
181 else
182 create r.make (0)
183 table.extend (r)
184 end
185 r.extend (lf)
186 end
187
188 height: INTEGER is
189 -- Vertical dimension in pixels of current placement.
190 local
191 i: INTEGER
192 do
193 from
194 i := 1
195 until
196 i > table.count
197 loop
198 Result := Result + row_height (table.i_th (i))
199 i := i + 1
200 if i <= table.count then
201 Result := Result + vertical_scaled_spacing
202 end
203 end
204 end
205
206 row_height (r: like row): INTEGER is
207 -- Height in pixels of `r'.
208 do
209 if r /= Void then
210 from
211 r.start
212 until
213 r.after
214 loop
215 if r.item /= Void then
216 Result := Result.max (r.item.height)
217 end
218 r.forth
219 end
220 end
221 end
222
223 width: INTEGER is
224 -- Horizontal dimension of widest row.
225 local
226 max_widths: ARRAYED_LIST [INTEGER]
227 i: INTEGER
228 do
229 if has_classes then
230 max_widths := max_x_widths
231 from
232 max_widths.start
233 until
234 max_widths.after
235 loop
236 Result := Result + max_widths.item + horizontal_scaled_spacing
237 max_widths.forth
238 end
239 else
240 from
241 i := 1
242 until
243 i > table.count
244 loop
245 Result := Result.max (row_width (table.i_th (i)))
246 i := i + 1
247 end
248 Result := Result + horizontal_scaled_spacing
249 end
250 end
251
252 max_x_widths: ARRAYED_LIST [INTEGER] is
253 -- Array of maximum bubles width to line them up vertically and horizontally.
254 -- | Result is a list from 1 to max column count where each entry is the max width of this column.
255 local
256 r: like row
257 size, max_width, index: INTEGER
258 cf: EG_CLUSTER_FIGURE
259 cur_item: EG_LINKABLE_FIGURE
260 do
261 from
262 table.start
263 until
264 table.after
265 loop
266 if table.item /= Void and then table.item.count > size then
267 size := table.item.count
268 end
269 table.forth
270 end
271
272 create Result.make (size)
273 from
274 index := 1
275 until
276 index > size
277 loop
278 max_width := 0
279 from
280 table.start
281 until
282 table.after
283 loop
284 r := table.item
285 if r /= Void then
286 if index <= r.count then
287 cur_item := r.i_th (index)
288 cf ?= cur_item
289 if cur_item /= Void and then cf = Void and then cur_item.width > max_width then
290 max_width := cur_item.width
291 end
292 end
293 end
294 table.forth
295 end
296 Result.extend (max_width)
297 index := index + 1
298 end
299 end
300
301 row_width (r: like row): INTEGER is
302 -- Width in pixels of `r'.
303 do
304 if r /= Void then
305 from
306 r.start
307 until
308 r.after
309 loop
310 if r.item /= Void then
311 Result := Result + r.item.width
312 end
313 r.forth
314 if not r.after and then r.item /= Void then
315 Result := Result + horizontal_scaled_spacing
316 end
317 end
318 end
319 end
320
321 smallest_row: like row is
322 -- Row with smallest width.
323 local
324 w: INTEGER
325 r: like row
326 do
327 from table.start until table.after loop
328 r := table.item
329 if w = 0 then
330 Result := r
331 w := row_width (r)
332 else
333 if w > row_width (r) then
334 Result := r
335 w := row_width (r)
336 end
337 end
338 table.forth
339 end
340 end
341
342 arrange_by_generation is
343 -- Place class bubbles so that descendants are always below
344 -- their ancestors.
345 local
346 r: like row
347 do
348 from
349 r := first_generation
350 until
351 r.is_empty
352 loop
353 remove_from_table (r)
354 table.extend (r)
355 r := next_generation (r)
356 end
357 end
358
359 first_generation: like row is
360 -- Classes in `figure_set' that have no ancestors
361 -- in same cluster but descendants in same cluster.
362 local
363 l_classes: like classes
364 l_item: EG_LINKABLE_FIGURE
365 do
366 l_classes := classes
367 create Result.make (0)
368 from
369 l_classes.start
370 until
371 l_classes.after
372 loop
373 l_item := l_classes.item
374 if
375 not has_ancestor_in_same_cluster (l_item) and then
376 has_descendant_in_same_cluster (l_item)
377 then
378 Result.extend (l_item)
379 end
380 l_classes.forth
381 end
382 end
383
384 next_generation (r: like row): like row is
385 -- Direct descendants of `r' in same cluster.
386 local
387 l_links: ARRAYED_LIST [EG_LINK_FIGURE]
388 bil: EIFFEL_INHERITANCE_FIGURE
389 i, nb: INTEGER
390 l_item, descendant: EG_LINKABLE_FIGURE
391 do
392 create Result.make (0)
393 from
394 r.start
395 until
396 r.after
397 loop
398 l_item := r.item
399 l_links := l_item.links
400 from
401 i := 1
402 nb := l_links.count
403 until
404 i > nb
405 loop
406 bil ?= l_links.i_th (i)
407 if bil /= Void then
408 descendant := bil.descendant
409 if
410 descendant.is_show_requested and then
411 descendant /= l_item and then
412 descendant.cluster = l_item.cluster and then
413 not Result.has (descendant)
414 then
415 Result.extend (descendant)
416 end
417 end
418 i := i + 1
419 end
420 r.forth
421 end
422 end
423
424 has_ancestor_in_same_cluster (linkable: EG_LINKABLE_FIGURE): BOOLEAN is
425 -- Does `linkable' have an ancestor in the same cluster?
426 require
427 linkable_not_void: linkable /= Void
428 local
429 bil: EIFFEL_INHERITANCE_FIGURE
430 l_links: ARRAYED_LIST [EG_LINK_FIGURE]
431 i, nb: INTEGER
432 do
433 Result := False
434 from
435 l_links := linkable.links
436 i := 1
437 nb := l_links.count
438 until
439 Result or else i > nb
440 loop
441 bil ?= l_links.i_th (i)
442 if bil /= Void then
443 if bil.ancestor /= linkable and then bil.ancestor.cluster = linkable.cluster then
444 Result := True
445 end
446 end
447 i := i + 1
448 end
449 end
450
451 has_descendant_in_same_cluster (linkable: EG_LINKABLE_FIGURE): BOOLEAN is
452 -- Does `linkable' have an descendant in the same cluster?
453 require
454 linkable_not_void: linkable /= Void
455 local
456 bil: EIFFEL_INHERITANCE_FIGURE
457 l_links: ARRAYED_LIST [EG_LINK_FIGURE]
458 i, nb: INTEGER
459 do
460 Result := False
461 from
462 l_links := linkable.links
463 i := 1
464 nb := l_links.count
465 until
466 Result or else i > nb
467 loop
468 bil ?= l_links.i_th (i)
469 if bil /= Void then
470 if bil.descendant /= linkable and then bil.descendant.cluster = linkable.cluster then
471 Result := True
472 end
473 end
474 i := i + 1
475 end
476 end
477
478 remove_from_table (r: like row) is
479 -- Remove any class in `r' if present from `table'.
480 local
481 tr: like row
482 i : INTEGER
483 do
484 from
485 table.start
486 until
487 table.after
488 loop
489 tr := table.item
490 from i := 1 until i > r.count loop
491 tr.prune_all (r.i_th (i))
492 i := i + 1
493 end
494 table.forth
495 end
496 end
497
498 arrange_clients is
499 -- Place class bubbles that are linked to diagram classes
500 -- only by client/supplier links.
501 local
502 l: like classes
503 do
504 l := classes
505 from
506 l.start
507 until
508 l.after
509 loop
510 if not has (l.item) then
511 add_linkable_figure (l.item)
512 end
513 l.forth
514 end
515 end
516
517 has (lf: EG_LINKABLE_FIGURE): BOOLEAN is
518 -- Does `table' contain `lf'?
519 require
520 lf_not_void: lf /= Void
521 local
522 r: like row
523 do
524 from
525 table.start
526 until
527 Result or table.after
528 loop
529 r := table.item
530 Result := r.has (lf)
531 table.forth
532 end
533 end
534
535 execute is
536 -- Perform the actual placement.
537 local
538 cur_x, cur_y: INTEGER
539 l_row_height, max_width: INTEGER
540 r: like row
541 do
542 max_width := 0
543 from
544 table.start
545 until
546 table.after
547 loop
548 max_width := max_width.max (row_width (table.item))
549 table.forth
550 end
551 cur_y := vertical_scaled_spacing
552 from
553 table.start
554 until
555 table.after
556 loop
557 r := table.item
558 if r /= Void then
559 cur_x := max_width // 2 - row_width (r) // 2 + horizontal_scaled_spacing
560 l_row_height := row_height (r)
561 cur_y := cur_y + l_row_height // 2
562
563 from
564 r.start
565 until
566 r.after
567 loop
568 r.item.set_port_position (cur_x + r.item.width // 2, cur_y)
569 cur_x := cur_x + r.item.width + horizontal_scaled_spacing
570
571 r.forth
572 end
573 cur_y := cur_y + l_row_height // 2 + vertical_scaled_spacing
574 end
575 table.forth
576 end
577 end
578
579 center_rows is
580 -- Add void elements in `table' in order to center rows.
581 -- Applies only for class views.
582 local
583 lgw, class_offset, i: INTEGER
584 r: like row
585 do
586 lgw := largest_row_width
587 from
588 table.start
589 until
590 table.after
591 loop
592 r := table.item
593 class_offset := (lgw - r.count) // 2
594 from
595 i := 1
596 until
597 i > class_offset
598 loop
599 r.put_front (Void)
600 i := i + 1
601 end
602 table.forth
603 end
604 end
605
606 largest_row_width: INTEGER is
607 -- Number of figures in largest row of `table'.
608 do
609 from
610 table.start
611 Result := 0
612 until
613 table.after
614 loop
615 Result := Result.max (table.item.count)
616 table.forth
617 end
618 end
619
620 indexing
621 copyright: "Copyright (c) 1984-2006, Eiffel Software"
622 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
623 licensing_options: "http://www.eiffel.com/licensing"
624 copying: "[
625 This file is part of Eiffel Software's Eiffel Development Environment.
626
627 Eiffel Software's Eiffel Development Environment is free
628 software; you can redistribute it and/or modify it under
629 the terms of the GNU General Public License as published
630 by the Free Software Foundation, version 2 of the License
631 (available at the URL listed under "license" above).
632
633 Eiffel Software's Eiffel Development Environment is
634 distributed in the hope that it will be useful, but
635 WITHOUT ANY WARRANTY; without even the implied warranty
636 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
637 See the GNU General Public License for more details.
638
639 You should have received a copy of the GNU General Public
640 License along with Eiffel Software's Eiffel Development
641 Environment; if not, write to the Free Software Foundation,
642 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
643 ]"
644 source: "[
645 Eiffel Software
646 356 Storke Road, Goleta, CA 93117 USA
647 Telephone 805-685-1006, Fax 805-685-6869
648 Website http://www.eiffel.com
649 Customer support http://support.eiffel.com
650 ]"
651
652 end -- class EIFFEL_INHERITANCE_LAYOUT

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23