Differences From Artifact [e76b6b97ba56256b]:
- File
src/gui.d
- 2012-07-14 11:24:30 - part of checkin [bee0596f0f] on branch trunk - Refactoring. (user: kinaba) [annotate]
To Artifact [508aa0ef899fe75c]:
- File
src/gui.d
- 2012-07-14 12:29:17 - part of checkin [9d4aca73fa] on branch trunk - GUI+Solver revived. (user: kinaba) [annotate]
1 import dfl.all; 1 import dfl.all;
2 import util; 2 import util;
3 import game; 3 import game;
4 import output; <
5 import driver; 4 import driver;
6 //import solver; <
7 pragma(lib, "dfl.lib"); <
8 5
9 class GUI : Form, GameObserver | 6 class GUI(Solver) : Form, GameObserver
10 { 7 {
11 bool on_game_changed(char c, const(Game) g, bool finished) { | 8 this(const(Game) g)
> 9 {
> 10 this.solver = new Solver(g);
> 11 setup_size(g.map.W, g.map.H);
> 12 setup_resources();
> 13 setup_keyhandling();
12 draw(gr, g); | 14 draw(g);
13 invalidate(); <
14 return false; <
> 15 }
> 16
> 17 private void delegate(char c) fn;
> 18 void set_fn(F)(F f) { this.fn = f; }
> 19
> 20 void run()
> 21 {
> 22 Application.run(this);
15 } 23 }
16 24
17 private { | 25 override void on_game_changed(char c, const(Game) g, bool finished)
18 int cell; <
19 int turn = 0; <
20 | 26 {
21 Font font; <
22 Color[char] colors; <
23 string[char] render; <
24 void delegate(char c) fn; <
> 27 draw(g);
25 } 28 }
26 29
27 this(const(Game) g) | 30 private:
28 { <
29 noMessageFilter(); <
30 this.setStyle(ControlStyles.OPAQUE, true); <
31 this.fn = fn; <
> 31 int cell;
32 32
33 this.paint ~= &my_paint; | 33 void setup_size(int W, int H)
34 this.keyDown ~= &my_keydown; <
35 | 34 {
36 this.formBorderStyle = FormBorderStyle.FIXED_DIALOG; 35 this.formBorderStyle = FormBorderStyle.FIXED_DIALOG;
37 this.maximizeBox = false; 36 this.maximizeBox = false;
38 this.minimizeBox = false; 37 this.minimizeBox = false;
39 this.cell = min(1024/g.map.W, 640/g.map.H); | 38 this.cell = min(1024/W, 640/H);
40 this.clientSize = Size(g.map.W*cell, g.map.H*cell); | 39 this.clientSize = Size(W*cell, H*cell);
> 40 }
41 41
42 const scrH = this.clientSize.height; | 42 Font font;
43 const scrW = this.clientSize.width; | 43 Color[char] colors;
44 this.gr = new MemoryGraphics(scrW, scrH); | 44 string[char] render;
> 45 Graphics graphicContext;
45 46
46 // Resources | 47 void setup_resources()
> 48 {
> 49 this.graphicContext = new MemoryGraphics(this.clientSize.width,
> 50 this.setStyle(ControlStyles.OPAQUE, true);
47 this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL); 51 this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL);
48 this.backColor = Color(255,255,255); 52 this.backColor = Color(255,255,255);
49 this.colors['#'] = 53 this.colors['#'] =
50 this.colors['.'] = Color(255,191,127); 54 this.colors['.'] = Color(255,191,127);
51 this.colors['*'] = Color(255,127,127); 55 this.colors['*'] = Color(255,127,127);
52 this.colors['R'] = Color(128,128,0); 56 this.colors['R'] = Color(128,128,0);
53 this.colors['D'] = Color(255,0,0); // Dead | 57 this.colors['D'] = Color(255,0,0);
54 this.colors['\\'] = 58 this.colors['\\'] =
55 this.colors['L'] = 59 this.colors['L'] =
56 this.colors['O'] = Color(127,255,127); 60 this.colors['O'] = Color(127,255,127);
57 this.colors['W'] = Color(204,229,255); // water | 61 this.colors['W'] = Color(204,229,255);
58 <
59 this.render['#'] = "■"; 62 this.render['#'] = "■";
60 this.render['*'] = "✹"; 63 this.render['*'] = "✹";
61 this.render['.'] = "♒"; 64 this.render['.'] = "♒";
62 this.render['\\'] = "λ"; 65 this.render['\\'] = "λ";
63 this.render['R'] = "☃"; 66 this.render['R'] = "☃";
64 this.render['D'] = "☠"; 67 this.render['D'] = "☠";
65 this.render['L'] = "☒"; 68 this.render['L'] = "☒";
66 this.render['O'] = "☐"; 69 this.render['O'] = "☐";
67 draw(gr, g); | 70 this.paint ~= (Control c, PaintEventArgs ev) {
> 71 graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientS
68 } | 72 };
69 <
70 void set_fn(F)(F f) { this.fn = f; } <
71 <
72 void run() { <
73 Application.run(this); <
74 } 73 }
75 74
76 private: <
77 Graphics gr; <
78 <
79 void my_paint(Control, PaintEventArgs ev) <
80 { <
81 gr.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clien <
82 } <
83 <
84 void draw(Graphics gr, const(Game) g) | 75 void draw(const(Game) g)
85 { 76 {
86 int scrW = this.clientSize.width; 77 int scrW = this.clientSize.width;
87 int scrH = this.clientSize.height; 78 int scrH = this.clientSize.height;
> 79
88 // Fill bg. 80 // Fill bg.
89 gr.fillRectangle(this.backColor, Rect(0,0,scrW,scrH)); | 81 graphicContext.fillRectangle(this.backColor, Rect(0,0,scrW,scrH)
90 82
91 // Fill water. 83 // Fill water.
92 int w = g.water_level(); 84 int w = g.water_level();
93 gr.fillRectangle(this.colors['W'], Rect(0, scrH-cell*w-1, scrW, | 85 graphicContext.fillRectangle(this.colors['W'], Rect(0, scrH-cell
94 86
95 // Paint map. 87 // Paint map.
96 for(int y=1; y<=g.map.H; ++y) 88 for(int y=1; y<=g.map.H; ++y)
97 for(int x=1; x<=g.map.W; ++x) { 89 for(int x=1; x<=g.map.W; ++x) {
98 Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell); 90 Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell);
99 char c = g.map[y,x]; 91 char c = g.map[y,x];
100 if( c != ' ' ) { 92 if( c != ' ' ) {
101 if( c == 'R' && g.dead ) 93 if( c == 'R' && g.dead )
102 c = 'D'; 94 c = 'D';
103 gr.drawText(this.render[c], font, this.colors[c] | 95 graphicContext.drawText(this.render[c], font, th
104 } 96 }
105 } 97 }
106 98
107 set_text(g); | 99 // Update textual info.
> 100 this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ",
> 101 invalidate();
> 102 }
> 103
> 104 private:
> 105 void setup_keyhandling()
> 106 {
> 107 noMessageFilter();
> 108 this.keyDown ~= &my_keydown;
108 } 109 }
109 110
110 void my_keydown(Control c, KeyEventArgs ev) 111 void my_keydown(Control c, KeyEventArgs ev)
111 { 112 {
112 switch(ev.keyCode) 113 switch(ev.keyCode)
113 { 114 {
114 case Keys.DOWN: fn('D'); break; 115 case Keys.DOWN: fn('D'); break;
115 case Keys.UP: fn('U'); break; 116 case Keys.UP: fn('U'); break;
116 case Keys.LEFT: fn('L'); break; 117 case Keys.LEFT: fn('L'); break;
117 case Keys.RIGHT: fn('R'); break; 118 case Keys.RIGHT: fn('R'); break;
118 case Keys.W: fn('W'); break; 119 case Keys.W: fn('W'); break;
119 case Keys.A: fn('A'); break; 120 case Keys.A: fn('A'); break;
> 121 case Keys.G: fn(solver.single_step()); break;
120 default: break; 122 default: break;
121 } 123 }
122 } 124 }
123 125
124 void set_text(const(Game) g) { | 126 Solver solver;
125 this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", <
126 } <
127 } <
128 <
129 void main(string[] args) <
130 { <
131 auto d = new Driver(File(args[1])); <
132 d.addObserver!(GuardedOutput)(); <
133 GUI g = d.addObserver!(GUI)(); <
134 g.set_fn(&d.command); <
135 g.run(); <
136 } 127 }