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      1   import dfl.all;
     2      2   import util;
     3      3   import game;
     4         -import output;
     5      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) {
    12         -  draw(gr, g);
    13         -  invalidate();
    14         -  return false;
            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();
           14  +  draw(g);
           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 {
    18         -  int cell;
    19         -  int turn = 0;
    20         -
    21         -  Font font;
    22         -  Color[char] colors;
    23         -  string[char] render;
    24         -  void delegate(char c) fn;
           25  + override void on_game_changed(char c, const(Game) g, bool finished)
           26  + {
           27  +  draw(g);
    25     28    }
    26     29   
    27         - this(const(Game) g)
    28         - {
    29         -  noMessageFilter();
    30         -  this.setStyle(ControlStyles.OPAQUE, true);
    31         -  this.fn = fn;
           30  +private:
           31  + int cell;
    32     32   
    33         -  this.paint ~= &my_paint;
    34         -  this.keyDown ~= &my_keydown;
    35         -
           33  + void setup_size(int W, int H)
           34  + {
    36     35     this.formBorderStyle = FormBorderStyle.FIXED_DIALOG;
    37     36     this.maximizeBox = false;
    38     37     this.minimizeBox = false;
    39         -  this.cell = min(1024/g.map.W, 640/g.map.H);
    40         -  this.clientSize = Size(g.map.W*cell, g.map.H*cell);
           38  +  this.cell = min(1024/W, 640/H);
           39  +  this.clientSize = Size(W*cell, H*cell);
           40  + }
    41     41   
    42         -  const scrH = this.clientSize.height;
    43         -  const scrW = this.clientSize.width;
    44         -  this.gr = new MemoryGraphics(scrW, scrH);
           42  + Font         font;
           43  + Color[char]  colors;
           44  + string[char] render;
           45  + Graphics     graphicContext;
    45     46   
    46         -  // Resources
           47  + void setup_resources()
           48  + {
           49  +  this.graphicContext = new MemoryGraphics(this.clientSize.width, this.clientSize.height);
           50  +  this.setStyle(ControlStyles.OPAQUE, true);
    47     51     this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL);
    48     52     this.backColor = Color(255,255,255);
    49     53     this.colors['#'] =
    50     54     this.colors['.'] = Color(255,191,127);
    51     55     this.colors['*'] = Color(255,127,127);
    52     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     58     this.colors['\\'] =
    55     59     this.colors['L'] =
    56     60     this.colors['O'] = Color(127,255,127);
    57         -  this.colors['W'] = Color(204,229,255); // water
    58         -
           61  +  this.colors['W'] = Color(204,229,255);
    59     62     this.render['#'] = "■";
    60     63     this.render['*'] = "✹";
    61     64     this.render['.'] = "♒";
    62     65     this.render['\\'] = "λ";
    63     66     this.render['R'] = "☃";
    64     67     this.render['D'] = "☠";
    65     68     this.render['L'] = "☒";
    66     69     this.render['O'] = "☐";
    67         -  draw(gr, g);
    68         - }
    69         -
    70         - void set_fn(F)(F f) { this.fn = f; }
    71         -
    72         - void run() {
    73         -  Application.run(this);
           70  +  this.paint ~= (Control c, PaintEventArgs ev) {
           71  +   graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clientSize.height));
           72  +  };
    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.clientSize.height));
    82         - }
    83         -
    84         - void draw(Graphics gr, const(Game) g)
           75  + void draw(const(Game) g)
    85     76    {
    86     77     int scrW = this.clientSize.width;
    87     78     int scrH = this.clientSize.height;
           79  +
    88     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     83     // Fill water.
    92     84     int w = g.water_level();
    93         -  gr.fillRectangle(this.colors['W'], Rect(0, scrH-cell*w-1, scrW, cell*w+1));
           85  +  graphicContext.fillRectangle(this.colors['W'], Rect(0, scrH-cell*w-1, scrW, cell*w+1));
    94     86   
    95     87     // Paint map.
    96     88     for(int y=1; y<=g.map.H; ++y)
    97     89     for(int x=1; x<=g.map.W; ++x) {
    98     90      Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell);
    99     91      char c = g.map[y,x];
   100     92      if( c != ' ' ) {
   101     93       if( c == 'R' && g.dead )
   102     94        c = 'D';
   103         -    gr.drawText(this.render[c], font, this.colors[c], r);
           95  +    graphicContext.drawText(this.render[c], font, this.colors[c], r);
   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: ", g.water_until_rise);
          101  +  invalidate();
          102  + }
          103  +
          104  +private:
          105  + void setup_keyhandling()
          106  + {
          107  +  noMessageFilter();
          108  +  this.keyDown ~= &my_keydown;
   108    109    }
   109    110   
   110    111    void my_keydown(Control c, KeyEventArgs ev)
   111    112    {
   112    113     switch(ev.keyCode)
   113    114     {
   114    115     case Keys.DOWN:  fn('D'); break;
   115    116     case Keys.UP:    fn('U'); break;
   116    117     case Keys.LEFT:  fn('L'); break;
   117    118     case Keys.RIGHT: fn('R'); break;
   118    119     case Keys.W:     fn('W'); break;
   119    120     case Keys.A:     fn('A'); break;
          121  +  case Keys.G:     fn(solver.single_step()); break;
   120    122     default:         break;
   121    123     }
   122    124    }
   123    125   
   124         - void set_text(const(Game) g) {
   125         -  this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", g.water_until_rise);
   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();
          126  + Solver solver;
   136    127   }