graphic design tool
git clone https://git.lucas.co/cce-designer.git
Add viewport background color parameters to configure popup
src/main.rs | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 104 insertions(+), 10 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index cce367b..f3efa64 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -227,6 +227,10 @@ struct ConfigDialog {
show_origin_enabled: bool,
show_origin_pending: Option<bool>,
show_origin_hovered: bool,
+ viewport_r: f32,
+ viewport_g: f32,
+ viewport_b: f32,
+ viewport_color_pending: Option<(usize, f32)>,
}
impl ConfigDialog {
@@ -259,6 +263,10 @@ impl ConfigDialog {
show_origin_enabled: true,
show_origin_pending: None,
show_origin_hovered: false,
+ viewport_r: 0.05,
+ viewport_g: 0.05,
+ viewport_b: 0.10,
+ viewport_color_pending: None,
}
}
@@ -277,6 +285,11 @@ impl ConfigDialog {
let row1_y = py + 178.0; // Grid Y
let row2_y = py + 200.0; // Skipped Row H
let row3_y = py + 222.0; // Skipped Col W
+
+ let v_row0_y = py + 226.0; // Background R
+ let v_row1_y = py + 248.0; // Background G
+ let v_row2_y = py + 270.0; // Background B
+
vec![
(0, px + 160.0, row0_y - 2.0),
(1, px + 210.0, row0_y - 2.0),
@@ -286,6 +299,13 @@ impl ConfigDialog {
(5, px + 210.0, row2_y - 2.0),
(6, px + 160.0, row3_y - 2.0),
(7, px + 210.0, row3_y - 2.0),
+
+ (8, px + 160.0, v_row0_y - 2.0),
+ (9, px + 210.0, v_row0_y - 2.0),
+ (10, px + 160.0, v_row1_y - 2.0),
+ (11, px + 210.0, v_row1_y - 2.0),
+ (12, px + 160.0, v_row2_y - 2.0),
+ (13, px + 210.0, v_row2_y - 2.0),
]
}
@@ -348,11 +368,20 @@ impl Widget for ConfigDialog {
1 => self.grid_size_y = val,
2 => self.skipped_row_h = val,
3 => self.skipped_col_w = val,
+ 4 => self.viewport_r = val,
+ 5 => self.viewport_g = val,
+ 6 => self.viewport_b = val,
_ => {}
}
}
fn take_config_spin(&mut self) -> Option<(usize, f32)> {
- self.grid_size_pending.take()
+ if let Some(v) = self.grid_size_pending.take() {
+ Some(v)
+ } else if let Some(v) = self.viewport_color_pending.take() {
+ Some(v)
+ } else {
+ None
+ }
}
fn hit_test(&self, px: f32, py: f32) -> bool {
@@ -401,7 +430,7 @@ impl Widget for ConfigDialog {
self.network_grid_hovered = px >= ppx + 16.0 && px < ppx + 200.0
&& py >= row2_y - 2.0 && py < row2_y + 18.0;
for &(btn_id, bx, by) in &self.spin_btns(ppx, ppy) {
- if px >= bx && px < bx + 22.0 && py >= by && py < by + 20.0 {
+ if btn_id < 8 && px >= bx && px < bx + 22.0 && py >= by && py < by + 20.0 {
self.hovered_spin_btn = Some(btn_id);
break;
}
@@ -416,6 +445,12 @@ impl Widget for ConfigDialog {
let row3_y = ppy + 132.0;
self.show_origin_hovered = px >= ppx + 16.0 && px < ppx + 200.0
&& py >= row3_y - 2.0 && py < row3_y + 18.0;
+ for &(btn_id, bx, by) in &self.spin_btns(ppx, ppy) {
+ if btn_id >= 8 && px >= bx && px < bx + 22.0 && py >= by && py < by + 20.0 {
+ self.hovered_spin_btn = Some(btn_id);
+ break;
+ }
+ }
}
was != self.hovered || old_close != self.close_hovered || old_tab != self.hovered_tab
@@ -503,6 +538,25 @@ impl Widget for ConfigDialog {
self.show_origin_pending = Some(self.show_origin_enabled);
return true;
}
+ for &(btn_id, bx, by) in &self.spin_btns(ppx, ppy) {
+ if btn_id >= 8 && px >= bx && px < bx + 22.0 && py >= by && py < by + 20.0 {
+ let (val, delta, min_val, max_val, pending_id) = match btn_id {
+ 8 => (&mut self.viewport_r, -0.05, 0.0, 1.0, 4),
+ 9 => (&mut self.viewport_r, 0.05, 0.0, 1.0, 4),
+ 10 => (&mut self.viewport_g, -0.05, 0.0, 1.0, 5),
+ 11 => (&mut self.viewport_g, 0.05, 0.0, 1.0, 5),
+ 12 => (&mut self.viewport_b, -0.05, 0.0, 1.0, 6),
+ 13 => (&mut self.viewport_b, 0.05, 0.0, 1.0, 6),
+ _ => unreachable!(),
+ };
+ let new = (*val + delta).clamp(min_val, max_val);
+ if (new - *val).abs() > 0.001 {
+ *val = new;
+ self.viewport_color_pending = Some((pending_id, *val));
+ }
+ return true;
+ }
+ }
}
false
}
@@ -578,6 +632,20 @@ impl Widget for ConfigDialog {
let row3_y = py + 132.0;
quads.push((px + 14.0, row3_y - 2.0, 186.0, 20.0, [0.25, 0.25, 0.35, 0.4]));
}
+ if let Some(sb) = self.hovered_spin_btn {
+ for &(btn_id, bx, by) in &self.spin_btns(px, py) {
+ if btn_id == sb {
+ quads.push((bx, by, 22.0, 20.0, [0.35, 0.35, 0.45, 0.5]));
+ break;
+ }
+ }
+ }
+ let preview_x = px + 300.0;
+ let preview_y = py + 226.0;
+ let preview_w = 120.0;
+ let preview_h = 64.0;
+ quads.push((preview_x - 2.0, preview_y - 2.0, preview_w + 4.0, preview_h + 4.0, [0.35, 0.35, 0.45, 1.0]));
+ quads.push((preview_x, preview_y, preview_w, preview_h, [self.viewport_r, self.viewport_g, self.viewport_b, 1.0]));
}
quads
@@ -647,6 +715,25 @@ impl Widget for ConfigDialog {
labels.push(TextLabel { text: cube_text.into(), x: px + 20.0, y: content_y + 50.0, font_size: 12.0, color: [0xaa, 0xaa, 0xbb] });
let origin_text = if self.show_origin_enabled { "[\u{2713}] Show Origin Axes" } else { "[ ] Show Origin Axes" };
labels.push(TextLabel { text: origin_text.into(), x: px + 20.0, y: content_y + 74.0, font_size: 12.0, color: [0xaa, 0xaa, 0xbb] });
+
+ labels.push(TextLabel { text: "Background Color".into(), x: px + 16.0, y: content_y + 110.0, font_size: 12.0, color: [0x88, 0x88, 0x99] });
+
+ labels.push(TextLabel { text: "Red:".into(), x: px + 16.0, y: content_y + 132.0, font_size: 12.0, color: [0xbb, 0xbb, 0xcc] });
+ labels.push(TextLabel { text: "\u{2212}".into(), x: px + 170.0, y: content_y + 132.0, font_size: 12.0, color: [0xcc, 0xcc, 0xd4] });
+ labels.push(TextLabel { text: format!("{:.2}", self.viewport_r), x: px + 188.0, y: content_y + 132.0, font_size: 12.0, color: [0xdd, 0xdd, 0x88] });
+ labels.push(TextLabel { text: "+".into(), x: px + 220.0, y: content_y + 132.0, font_size: 12.0, color: [0xcc, 0xcc, 0xd4] });
+
+ labels.push(TextLabel { text: "Green:".into(), x: px + 16.0, y: content_y + 154.0, font_size: 12.0, color: [0xbb, 0xbb, 0xcc] });
+ labels.push(TextLabel { text: "\u{2212}".into(), x: px + 170.0, y: content_y + 154.0, font_size: 12.0, color: [0xcc, 0xcc, 0xd4] });
+ labels.push(TextLabel { text: format!("{:.2}", self.viewport_g), x: px + 188.0, y: content_y + 154.0, font_size: 12.0, color: [0xdd, 0xdd, 0x88] });
+ labels.push(TextLabel { text: "+".into(), x: px + 220.0, y: content_y + 154.0, font_size: 12.0, color: [0xcc, 0xcc, 0xd4] });
+
+ labels.push(TextLabel { text: "Blue:".into(), x: px + 16.0, y: content_y + 176.0, font_size: 12.0, color: [0xbb, 0xbb, 0xcc] });
+ labels.push(TextLabel { text: "\u{2212}".into(), x: px + 170.0, y: content_y + 176.0, font_size: 12.0, color: [0xcc, 0xcc, 0xd4] });
+ labels.push(TextLabel { text: format!("{:.2}", self.viewport_b), x: px + 188.0, y: content_y + 176.0, font_size: 12.0, color: [0xdd, 0xdd, 0x88] });
+ labels.push(TextLabel { text: "+".into(), x: px + 220.0, y: content_y + 176.0, font_size: 12.0, color: [0xcc, 0xcc, 0xd4] });
+
+ labels.push(TextLabel { text: "Preview:".into(), x: px + 300.0, y: content_y + 110.0, font_size: 12.0, color: [0x88, 0x88, 0x99] });
} else {
labels.push(TextLabel { text: "Keyboard Shortcuts".into(), x: px + 16.0, y: content_y, font_size: 13.0, color: [0xcc, 0xcc, 0xd4] });
let shortcuts = [
@@ -1401,6 +1488,7 @@ struct State {
show_grid: bool,
show_cube: bool,
show_origin: bool,
+ viewport_bg_color: [f32; 3],
vertex_buffer_origin: wgpu::Buffer,
vertex_count_origin: u32,
@@ -2298,6 +2386,7 @@ fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec<Vec<String
show_grid: true,
show_cube: false,
show_origin: true,
+ viewport_bg_color: [0.05, 0.05, 0.10],
vertex_buffer_origin,
vertex_count_origin,
fs_root,
@@ -2573,6 +2662,9 @@ fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec<Vec<String
self.widgets[CONFIG_DIALOG_IDX].set_config_spin(1, self.grid_size_y);
self.widgets[CONFIG_DIALOG_IDX].set_config_spin(2, self.skipped_row_h);
self.widgets[CONFIG_DIALOG_IDX].set_config_spin(3, self.skipped_col_w);
+ self.widgets[CONFIG_DIALOG_IDX].set_config_spin(4, self.viewport_bg_color[0]);
+ self.widgets[CONFIG_DIALOG_IDX].set_config_spin(5, self.viewport_bg_color[1]);
+ self.widgets[CONFIG_DIALOG_IDX].set_config_spin(6, self.viewport_bg_color[2]);
self.widgets[CONFIG_DIALOG_IDX].set_visible(true);
}
self.upload_vertices();
@@ -3622,7 +3714,12 @@ fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec<Vec<String
view: &view,
resolve_target: None,
ops: wgpu::Operations {
- load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.05, g: 0.05, b: 0.10, a: 1.0 }),
+ load: wgpu::LoadOp::Clear(wgpu::Color {
+ r: self.viewport_bg_color[0] as f64,
+ g: self.viewport_bg_color[1] as f64,
+ b: self.viewport_bg_color[2] as f64,
+ a: 1.0,
+ }),
store: wgpu::StoreOp::Store,
},
})],
@@ -3798,13 +3895,7 @@ impl ApplicationHandler for App {
changed = true;
}
3 => { // Configure
- state.widgets[CONFIG_DIALOG_IDX].set_config_toggle(0, state.grid_snap_enabled);
- state.widgets[CONFIG_DIALOG_IDX].set_config_toggle(1, state.network_grid_visible);
- state.widgets[CONFIG_DIALOG_IDX].set_config_spin(0, state.grid_size_x);
- state.widgets[CONFIG_DIALOG_IDX].set_config_spin(1, state.grid_size_y);
- state.widgets[CONFIG_DIALOG_IDX].set_config_spin(2, state.skipped_row_h);
- state.widgets[CONFIG_DIALOG_IDX].set_config_spin(3, state.skipped_col_w);
- state.widgets[CONFIG_DIALOG_IDX].set_visible(true);
+ state.execute_action(Action::ToggleConfigure);
changed = true;
}
4 => { // Exit
@@ -3911,6 +4002,9 @@ impl ApplicationHandler for App {
1 => state.grid_size_y = val,
2 => state.skipped_row_h = val,
3 => state.skipped_col_w = val,
+ 4 => state.viewport_bg_color[0] = val,
+ 5 => state.viewport_bg_color[1] = val,
+ 6 => state.viewport_bg_color[2] = val,
_ => {}
}
for &i in &state.node_slots {