diff options
Diffstat (limited to 'src/gui/boardwidget.rs')
| -rw-r--r-- | src/gui/boardwidget.rs | 426 |
1 files changed, 213 insertions, 213 deletions
diff --git a/src/gui/boardwidget.rs b/src/gui/boardwidget.rs index d831ed1..2708f21 100644 --- a/src/gui/boardwidget.rs +++ b/src/gui/boardwidget.rs @@ -1,18 +1,18 @@ /* - This file is part of Takwrap. + This file is part of Takwrap. - Takwrap is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Takwrap is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - Takwrap is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Takwrap is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Takwrap. If not, see <https://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with Takwrap. If not, see <https://www.gnu.org/licenses/>. */ use fltk::{app::*, button::*, draw::*}; @@ -25,240 +25,240 @@ use crate::game::*; // when rendering in button.draw2(...) later. We do, however, need to // use compute_square_size because the widget may be resized. struct BoardRenderer { - even_square_colour: Color, - odd_square_colour: Color, - black_colour: Color, - white_colour: Color, - stone_size: f32, - game_size: i32, - frame_pad: i32, - xorg: i32, - yorg: i32, + even_square_colour: Color, + odd_square_colour: Color, + black_colour: Color, + white_colour: Color, + stone_size: f32, + game_size: i32, + frame_pad: i32, + xorg: i32, + yorg: i32, } impl BoardRenderer { - fn default() -> BoardRenderer { - BoardRenderer { - // Sandy brown - odd_square_colour: Color::from_rgb(244, 164, 96), - // Moccasin - even_square_colour: Color::from_rgb(255, 228, 181), - // Colours for pieces - black_colour: Color::from_rgb(178, 34, 34), - white_colour: Color::from_rgb(250, 235, 215), - // Gap between stones and edged of square - stone_size: 0.8, - // Defaults - game_size: 5, - frame_pad: 5, - xorg: 0, - yorg: 0, - } - } + fn default() -> BoardRenderer { + BoardRenderer { + // Sandy brown + odd_square_colour: Color::from_rgb(244, 164, 96), + // Moccasin + even_square_colour: Color::from_rgb(255, 228, 181), + // Colours for pieces + black_colour: Color::from_rgb(178, 34, 34), + white_colour: Color::from_rgb(250, 235, 215), + // Gap between stones and edged of square + stone_size: 0.8, + // Defaults + game_size: 5, + frame_pad: 5, + xorg: 0, + yorg: 0, + } + } - fn with_size(mut self, size: i32) -> BoardRenderer { - self.game_size = size; - return self; - } + fn with_size(mut self, size: i32) -> BoardRenderer { + self.game_size = size; + return self; + } - fn with_org(mut self, button: &Button) -> BoardRenderer { - let x0 = button.x(); - let y0 = button.y(); - self.xorg = x0 + self.frame_pad; - self.yorg = y0 + self.frame_pad; - return self; - } + fn with_org(mut self, button: &Button) -> BoardRenderer { + let x0 = button.x(); + let y0 = button.y(); + self.xorg = x0 + self.frame_pad; + self.yorg = y0 + self.frame_pad; + return self; + } - fn compute_square_size(&self, button: &Button) -> i32 { - let board_size = i32::min(button.width(), button.height()) - self.frame_pad * 2; - return board_size / self.game_size; - } + fn compute_square_size(&self, button: &Button) -> i32 { + let board_size = i32::min(button.width(), button.height()) - self.frame_pad * 2; + return board_size / self.game_size; + } - fn render_stone( - &self, - square_size: i32, - player: Player, - stone: Stone, - row: i32, - col: i32, - shift: i32, - ) { - set_draw_color(match player { - Player::Black => self.black_colour, - Player::White => self.white_colour, - }); + fn render_stone( + &self, + square_size: i32, + player: Player, + stone: Stone, + row: i32, + col: i32, + shift: i32, + ) { + set_draw_color(match player { + Player::Black => self.black_colour, + Player::White => self.white_colour, + }); - // Gap scales with square size - let stone_gap = (square_size as f32 * (1.00 - self.stone_size)).round() as i32; - let d = square_size - stone_gap * 2; - let shift = (shift * d) / 8; - let x1 = self.xorg + col * square_size + stone_gap + shift; - let y1 = self.yorg + row * square_size + stone_gap - shift; + // Gap scales with square size + let stone_gap = (square_size as f32 * (1.00 - self.stone_size)).round() as i32; + let d = square_size - stone_gap * 2; + let shift = (shift * d) / 8; + let x1 = self.xorg + col * square_size + stone_gap + shift; + let y1 = self.yorg + row * square_size + stone_gap - shift; - // Outline with thickness varying by stone size - let setup_border_pen = || { - set_line_style(LineStyle::Solid, i32::max(1, d / 24)); - set_draw_color(Color::Black); - }; + // Outline with thickness varying by stone size + let setup_border_pen = || { + set_line_style(LineStyle::Solid, i32::max(1, d / 24)); + set_draw_color(Color::Black); + }; - match stone { - Stone::Capstone => { - draw_pie(x1, y1, d, d, 0.0, 360.0); - setup_border_pen(); - let r = (d as f64) / 2.0; - draw_circle(r + x1 as f64, r + y1 as f64, r); - } - Stone::Flat => { - draw_rectf(x1, y1, d, d); - setup_border_pen(); - draw_rect_with_color(x1, y1, d, d, Color::Black); - } - Stone::Standing => { - // These look bad shifted so we shift it back if was - let df = d as f64; - // and we have to fudge it a little? Some rounding things presumably - let ds = if shift > 0 { df / 8.0 - 0.5 } else { 0.0 }; - let x1 = x1 as f64 - ds; - let y1 = y1 as f64 + ds; + match stone { + Stone::Capstone => { + draw_pie(x1, y1, d, d, 0.0, 360.0); + setup_border_pen(); + let r = (d as f64) / 2.0; + draw_circle(r + x1 as f64, r + y1 as f64, r); + } + Stone::Flat => { + draw_rectf(x1, y1, d, d); + setup_border_pen(); + draw_rect_with_color(x1, y1, d, d, Color::Black); + } + Stone::Standing => { + // These look bad shifted so we shift it back if was + let df = d as f64; + // and we have to fudge it a little? Some rounding things presumably + let ds = if shift > 0 { df / 8.0 - 0.5 } else { 0.0 }; + let x1 = x1 as f64 - ds; + let y1 = y1 as f64 + ds; - let verts = [ - (x1 + df * 0.3, y1 + df * 0.075), - (x1 + df * 0.925, y1 + df * 0.7), - (x1 + df * 0.7, y1 + df * 0.925), - (x1 + df * 0.075, y1 + df * 0.3), - ]; + let verts = [ + (x1 + df * 0.3, y1 + df * 0.075), + (x1 + df * 0.925, y1 + df * 0.7), + (x1 + df * 0.7, y1 + df * 0.925), + (x1 + df * 0.075, y1 + df * 0.3), + ]; - begin_polygon(); - for (x, y) in verts.iter() { - vertex(*x, *y) - } - end_polygon(); + begin_polygon(); + for (x, y) in verts.iter() { + vertex(*x, *y) + } + end_polygon(); - setup_border_pen(); - begin_loop(); - for (x, y) in verts.iter() { - vertex(*x, *y); - } - end_loop(); - } - } - set_line_style(LineStyle::Solid, 1); - } + setup_border_pen(); + begin_loop(); + for (x, y) in verts.iter() { + vertex(*x, *y); + } + end_loop(); + } + } + set_line_style(LineStyle::Solid, 1); + } - fn render_icons(&self, square_size: i32, player: Player, row: i32, col: i32, shift: i32) { - let stone_gap = square_size as f32 * (1.00 - self.stone_size); - let icon_gap = (stone_gap * 0.15).round() as i32; - let icon_width = (stone_gap * 0.7).round() as i32; - let icon_height = icon_width / 2; + fn render_icons(&self, square_size: i32, player: Player, row: i32, col: i32, shift: i32) { + let stone_gap = square_size as f32 * (1.00 - self.stone_size); + let icon_gap = (stone_gap * 0.15).round() as i32; + let icon_width = (stone_gap * 0.7).round() as i32; + let icon_height = icon_width / 2; - let x1 = self.xorg + col * square_size + icon_gap; - let y1 = self.yorg + (row + 1) * square_size - icon_gap; + let x1 = self.xorg + col * square_size + icon_gap; + let y1 = self.yorg + (row + 1) * square_size - icon_gap; - set_line_style(LineStyle::Solid, i32::max(1, icon_width / 8)); - set_draw_color(Color::Black); + set_line_style(LineStyle::Solid, i32::max(1, icon_width / 8)); + set_draw_color(Color::Black); - set_draw_color(match player { - Player::Black => self.black_colour, - Player::White => self.white_colour, - }); - let y2 = y1 - icon_height * (1 + shift as i32); - draw_rectf(x1, y2, icon_width, icon_height); - draw_rect_with_color(x1, y2, icon_width, icon_height, Color::Black); + set_draw_color(match player { + Player::Black => self.black_colour, + Player::White => self.white_colour, + }); + let y2 = y1 - icon_height * (1 + shift as i32); + draw_rectf(x1, y2, icon_width, icon_height); + draw_rect_with_color(x1, y2, icon_width, icon_height, Color::Black); - set_line_style(LineStyle::Solid, 1); - } + set_line_style(LineStyle::Solid, 1); + } - fn render_stack(&self, square_size: i32, row: i32, col: i32, stack: &Stack) { - // Is there a better way than usize::min((...), i32::MAX as usize) as i32 ? - let cutoff = stack.len() as i32 - self.game_size; + fn render_stack(&self, square_size: i32, row: i32, col: i32, stack: &Stack) { + // Is there a better way than usize::min((...), i32::MAX as usize) as i32 ? + let cutoff = stack.len() as i32 - self.game_size; - for (shift, piece) in stack.iter().enumerate() { - let shift = shift as i32; // TODO: please don't overflow - if shift < cutoff { - self.render_icons(square_size, piece.player, row, col, shift); - } else { - self.render_stone( - square_size, - piece.player, - piece.stone, - row, - col, - shift - i32::max(0, cutoff), - ); - } - } - } + for (shift, piece) in stack.iter().enumerate() { + let shift = shift as i32; // TODO: please don't overflow + if shift < cutoff { + self.render_icons(square_size, piece.player, row, col, shift); + } else { + self.render_stone( + square_size, + piece.player, + piece.stone, + row, + col, + shift - i32::max(0, cutoff), + ); + } + } + } - fn render_board(&self, square_size: i32, board: &Vec<Stack>) { - let mut x = 0; - let mut y = 0; - for stack in board.iter() { - self.render_stack(square_size, x, y, stack); - x += 1; - if x + 1 >= self.game_size { - x = 0; - y += 1; - if y + 1 >= self.game_size { - panic!("Game size mismatch between renderer and internal state."); - } - } - } - } + fn render_board(&self, square_size: i32, board: &Vec<Stack>) { + let mut x = 0; + let mut y = 0; + for stack in board.iter() { + self.render_stack(square_size, x, y, stack); + x += 1; + if x + 1 >= self.game_size { + x = 0; + y += 1; + if y + 1 >= self.game_size { + panic!("Game size mismatch between renderer and internal state."); + } + } + } + } - fn render_background(&self, square_size: i32) { - for x in 0..self.game_size { - for y in 0..self.game_size { - if (x + y) % 2 == 0 { - set_draw_color(self.even_square_colour); - } else { - set_draw_color(self.odd_square_colour); - } - draw_rectf( - self.xorg + x * square_size, - self.yorg + y * square_size, - square_size, - square_size, - ); - } - } - } + fn render_background(&self, square_size: i32) { + for x in 0..self.game_size { + for y in 0..self.game_size { + if (x + y) % 2 == 0 { + set_draw_color(self.even_square_colour); + } else { + set_draw_color(self.odd_square_colour); + } + draw_rectf( + self.xorg + x * square_size, + self.yorg + y * square_size, + square_size, + square_size, + ); + } + } + } } pub struct BoardWidget { - button: Button, - renderer: Rc<BoardRenderer>, + button: Button, + renderer: Rc<BoardRenderer>, } impl BoardWidget { - pub fn new(button: Button, size: i32) -> BoardWidget { - let renderer = Rc::new(BoardRenderer::default().with_size(size).with_org(&button)); - let mut g = BoardWidget { button, renderer }; - g.button.draw2(g.generate_draw(&Vec::new())); - return g; - } + pub fn new(button: Button, size: i32) -> BoardWidget { + let renderer = Rc::new(BoardRenderer::default().with_size(size).with_org(&button)); + let mut g = BoardWidget { button, renderer }; + g.button.draw2(g.generate_draw(&Vec::new())); + return g; + } - pub fn to_square(&self, x: i32, y: i32) -> (i32, i32) { - let square_size = self.renderer.compute_square_size(&self.button); + pub fn to_square(&self, x: i32, y: i32) -> (i32, i32) { + let square_size = self.renderer.compute_square_size(&self.button); - let x = x - self.renderer.xorg; - let y = y - self.renderer.yorg; + let x = x - self.renderer.xorg; + let y = y - self.renderer.yorg; - (x / square_size, y / square_size) - } + (x / square_size, y / square_size) + } - pub fn generate_draw(&self, board: &Vec<Stack>) -> impl FnMut(&mut Button) { - let renderer = self.renderer.clone(); - let board = board.clone(); + pub fn generate_draw(&self, board: &Vec<Stack>) -> impl FnMut(&mut Button) { + let renderer = self.renderer.clone(); + let board = board.clone(); - move |button: &mut Button| { - let square_size = renderer.compute_square_size(&button); - renderer.render_background(square_size); - renderer.render_board(square_size, &board); + move |button: &mut Button| { + let square_size = renderer.compute_square_size(&button); + renderer.render_background(square_size); + renderer.render_board(square_size, &board); - // // Test code for now - // renderer.render_stack(square_size, 1, 4, &stack); - // renderer.render_stone(square_size, Player::Black, Stone::Capstone, 1, 2, 0); - // renderer.render_stone(square_size, Player::Black, Stone::Standing, 2, 2, 0); - } - } + // // Test code for now + // renderer.render_stack(square_size, 1, 4, &stack); + // renderer.render_stone(square_size, Player::Black, Stone::Capstone, 1, 2, 0); + // renderer.render_stone(square_size, Player::Black, Stone::Standing, 2, 2, 0); + } + } } |
