summaryrefslogtreecommitdiff
path: root/test-nsc/files/pos/gui.scala
blob: b40759fb01665ae9eaaab7626aac08fe55745b9d (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
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): unit =
    System.out.println("draw " + r + " with " + c);
  def fillRect(r: Geom.Rectangle, c: Color): unit =
    System.out.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() = System.out.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(): unit = {
      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): unit =
      if (enabled) doit() else System.out.println("button is disabled");

    /* deferred method to be specified by client */
    def doit(): unit;
  }
}

object GUIClient {

  class Application {
    def quit() = System.out.println("application exited");
  }

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

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