|
1 import Element.elem |
|
2 abstract class Element{ |
|
3 def contents: Array[String] |
|
4 |
|
5 def height: Int = contents.length |
|
6 def width: Int = contents(0).length |
|
7 |
|
8 |
|
9 |
|
10 def above(that: Element): Element = { |
|
11 //new ArrayElement(this.contents ++ that.contents) |
|
12 val this1 = this widen that.width |
|
13 val that1 = that widen this.width |
|
14 elem(this1.contents ++ that1.contents) |
|
15 } |
|
16 def left_align(that: Element): Element = { |
|
17 if (this.width == that.width){ |
|
18 this above that |
|
19 } |
|
20 else if (this.width < that.width) { |
|
21 (this beside elem(' ', that.width - this.width, this.height)) above that |
|
22 } |
|
23 else { |
|
24 this above (that beside elem(' ', this.width - that.width, that.height)) |
|
25 } |
|
26 } |
|
27 def up_align(that: Element): Element = { |
|
28 if (this.height == that.height){ |
|
29 this beside that |
|
30 } |
|
31 else if (this.height < that.height) { |
|
32 (this above elem(' ', this.width, that.height - this.height)) beside that |
|
33 } |
|
34 else { |
|
35 this beside (that above elem(' ', that.width, this.height - that.height)) |
|
36 } |
|
37 } |
|
38 def beside(that: Element): Element = { |
|
39 val this1 = this heighten that.height |
|
40 val that1 = that heighten this.height |
|
41 elem( |
|
42 for ((line1, line2) <- this1.contents zip that1.contents) |
|
43 yield line1 + line2) |
|
44 } |
|
45 def widen(w: Int): Element = |
|
46 if(w <= width) this |
|
47 else { |
|
48 val left = Element.elem(' ', (w - width) / 2, height) |
|
49 var right = Element.elem(' ', w - width - left.width, height) |
|
50 left beside this beside right |
|
51 } |
|
52 def heighten(h: Int): Element = |
|
53 if (h <= height) this |
|
54 else { |
|
55 val top = Element.elem(' ', width, (h - height) / 2) |
|
56 val bot = Element.elem(' ', width, h - height - top.height) |
|
57 top above this above bot |
|
58 } |
|
59 override def toString = contents mkString "\n" |
|
60 } |
|
61 object Element { |
|
62 private class ArrayElement( |
|
63 val contents: Array[String] |
|
64 ) extends Element |
|
65 |
|
66 private class LineElement(s: String) extends Element { |
|
67 val contents = Array(s) |
|
68 override def width = s.length |
|
69 override def height = 1 |
|
70 } |
|
71 |
|
72 private class UniformElement( |
|
73 ch: Char, |
|
74 override val width: Int, |
|
75 override val height: Int |
|
76 ) extends Element { |
|
77 private val line = ch.toString * width |
|
78 def contents = Array.fill(height)(line) |
|
79 } |
|
80 |
|
81 def elem(contents: Array[String]): Element = |
|
82 new ArrayElement(contents) |
|
83 |
|
84 def elem(chr: Char, width: Int, height: Int): Element = |
|
85 new UniformElement(chr, width, height) |
|
86 |
|
87 def elem(line: String): Element = |
|
88 new LineElement(line) |
|
89 } |