summaryrefslogtreecommitdiff
path: root/test/files/pos/gui.scala
blob: 3b4f49cf55622d76c6ef41ff5e84fa60e41afb7e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
object Geom {
  trait Shape
  case class Point(x: Int, y: Int) extends Shape
  case class Rectangle(ll: Point, ur: Point) extends Shape {
    def inset(delta: Int) =
      Rectangle(Point(ll.x - delta, ll.y - delta), Point(ur.x + delta, ur.y + delta));
  }
}

object Color {
  type Color = Int
  val black = 0x000000
  val grey  = 0x808080
}

trait Screen {
  type Color = Int
  def drawRect(r: Geom.Rectangle, c: Color): Unit
  def fillRect(r: Geom.Rectangle, c: Color): Unit
}

object DummyScreen extends Screen {
  def drawRect(r: Geom.Rectangle, c: Color) {
    Console.println("draw " + r + " with " + c)
  }
  def fillRect(r: Geom.Rectangle, c: Color) {
    Console.println("fill " + r + " with " + c)
  }
}

object GUI {

  object Controller {
    def addMouseCtl(c: MouseCtl) = ()
  }

  trait Glyph {
    def getRect: Geom.Rectangle
    def setLoc(p: Geom.Point): Unit
    def draw() { Console.println("draw " + this) }
  }

  class Label(scr: Screen, p: Geom.Point, name: String) extends Glyph {
    private var origin = p
    def getRect = Geom.Rectangle(origin, origin).inset(10);
    def setLoc(p: Geom.Point) = { origin = p }
  }

  trait Ctl {
    def getGlyph: Glyph
    def enable(b: Boolean): this.type
  }

  trait MouseCtl extends Ctl {
    def mouseDown(p: Geom.Point): Unit
  }

  abstract class Button(scr: Screen, p: Geom.Point, name: String)
  extends Glyph with MouseCtl {
    var enabled: Boolean = false
    val label = new Label(scr, p, name)

    /* Glyph methods */
    override def draw() {
      if (enabled) scr.drawRect(getRect, Color.black)
      else scr.fillRect(getRect, Color.grey);
      label.draw();
    }
    def setLoc(p: Geom.Point) = label.setLoc(p);
    def getRect = label.getRect.inset(-2);

    /* Ctl methods */
    def enable(b: Boolean): this.type = { enabled = b; draw(); this }
    def getGlyph = label
    final def mouseDown(p: Geom.Point) {
      if (enabled) doit() else Console.println("button is disabled");
    }
    /* deferred method to be specified by client */
    def doit(): Unit
  }
}

object GUIClient {

  class App {
    def quit() { Console.println("application exited") }
  }

  class QuitButton (scr: Screen, p: Geom.Point, name: String, a: App)
  extends GUI.Button(scr, p, name) {
    def doit() { a.quit() }
  }

  def main(args: Array[String]) {
    val b = new QuitButton(
      DummyScreen, Geom.Point(1, 1), "quit", new App);
    b.draw();
    b.enable(true).mouseDown(Geom.Point(1, 2));
  }
}