dotzuki_renderer/
textbox.rs1use crate::text_renderer::ScreenTileBuffer;
2
3pub const TILE_TOP_LEFT: u8 = 0x79;
4pub const TILE_TOP_RIGHT: u8 = 0x7B;
5pub const TILE_BOTTOM_LEFT: u8 = 0x7D;
6pub const TILE_BOTTOM_RIGHT: u8 = 0x7E;
7pub const TILE_HORIZONTAL: u8 = 0x7A;
8pub const TILE_VERTICAL: u8 = 0x7C;
9pub const TILE_SPACE: u8 = 0x7F;
10pub const TILE_DOWN_ARROW: u8 = 0xED;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct TextBoxFrame {
14 pub x: u32,
15 pub y: u32,
16 pub width: u32,
17 pub height: u32,
18}
19
20impl TextBoxFrame {
21 pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
22 Self {
23 x,
24 y,
25 width,
26 height,
27 }
28 }
29
30 pub fn standard_dialog() -> Self {
31 Self {
32 x: 0,
33 y: 12,
34 width: 20,
35 height: 6,
36 }
37 }
38
39 pub fn menu_box(x: u32, y: u32, width: u32, height: u32) -> Self {
40 Self {
41 x,
42 y,
43 width,
44 height,
45 }
46 }
47
48 pub fn draw_frame(&self, buf: &mut ScreenTileBuffer) {
49 let x = self.x;
50 let y = self.y;
51 let w = self.width;
52 let h = self.height;
53
54 if w < 2 || h < 2 {
55 return;
56 }
57
58 let inner_w = w - 2;
59
60 buf.set(x, y, TILE_TOP_LEFT);
61 for i in 0..inner_w {
62 buf.set(x + 1 + i, y, TILE_HORIZONTAL);
63 }
64 buf.set(x + w - 1, y, TILE_TOP_RIGHT);
65
66 for row in 1..h - 1 {
67 buf.set(x, y + row, TILE_VERTICAL);
68 for col in 0..inner_w {
69 buf.set(x + 1 + col, y + row, TILE_SPACE);
70 }
71 buf.set(x + w - 1, y + row, TILE_VERTICAL);
72 }
73
74 buf.set(x, y + h - 1, TILE_BOTTOM_LEFT);
75 for i in 0..inner_w {
76 buf.set(x + 1 + i, y + h - 1, TILE_HORIZONTAL);
77 }
78 buf.set(x + w - 1, y + h - 1, TILE_BOTTOM_RIGHT);
79 }
80
81 pub fn clear(&self, buf: &mut ScreenTileBuffer) {
82 for row in 0..self.height {
83 for col in 0..self.width {
84 buf.set(self.x + col, self.y + row, TILE_SPACE);
85 }
86 }
87 }
88
89 pub fn clear_inner(&self, buf: &mut ScreenTileBuffer) {
90 if self.width < 2 || self.height < 2 {
91 return;
92 }
93 for row in 1..self.height - 1 {
94 for col in 1..self.width - 1 {
95 buf.set(self.x + col, self.y + row, TILE_SPACE);
96 }
97 }
98 }
99
100 pub fn show_down_arrow(&self, buf: &mut ScreenTileBuffer) {
101 if self.width >= 2 && self.height >= 2 {
102 let ax = self.x + self.width - 2;
103 let ay = self.y + self.height - 2;
104 buf.set(ax, ay, TILE_DOWN_ARROW);
105 }
106 }
107
108 pub fn hide_down_arrow(&self, buf: &mut ScreenTileBuffer) {
109 if self.width >= 2 && self.height >= 2 {
110 let ax = self.x + self.width - 2;
111 let ay = self.y + self.height - 2;
112 buf.set(ax, ay, TILE_SPACE);
113 }
114 }
115
116 pub fn text_start(&self) -> (u32, u32) {
117 (self.x + 1, self.y + 2)
118 }
119
120 pub fn second_line_start(&self) -> (u32, u32) {
121 (self.x + 1, self.y + 4)
122 }
123}