graphic design tool
git clone https://git.lucas.co/cce-designer.git
Refactor: Resolve compilation warnings, deprecated APIs, visibility issues, and redundant HTTP server logic
Makefile | 2 +-
src/app.rs | 42 ++++-------------
src/geometry.rs | 2 +-
src/main.rs | 140 +++-----------------------------------------------------
src/project.rs | 7 ++-
src/render.rs | 29 ++----------
src/window.rs | 5 +-
7 files changed, 25 insertions(+), 202 deletions(-)
diff --git a/Makefile b/Makefile
index 6c15473..d684483 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ build:
install: build
mkdir -p ~/.local/bin
- install -m 755 target/release/cce-design-interface ~/.local/bin/cce-design-interface
+ install -m 755 ../target/release/cce-design-interface ~/.local/bin/cce-design-interface
run:
cargo run
diff --git a/src/app.rs b/src/app.rs
index 9f31eb6..c14f570 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -2,7 +2,7 @@ use std::time::Instant;
use std::fs;
use std::path::Path;
use std::net::TcpListener;
-use std::io::{BufRead, BufReader, Read, Write};
+use std::io::BufReader;
use serde::{Deserialize, Serialize};
@@ -21,7 +21,7 @@ use smithay_client_toolkit::{
},
shell::{
xdg::{
- window::{Window as XdgWindow, WindowConfigure, WindowHandler, WindowDecorations},
+ window::{Window as XdgWindow, WindowConfigure, WindowDecorations},
XdgShell,
},
WaylandSurface,
@@ -331,10 +331,7 @@ fn default_show_camera_pivot() -> bool { false }
fn default_camera_pivot_size() -> f32 { 1.0 }
fn default_node_color() -> [f32; 3] { [0.10, 0.45, 0.70] }
fn default_grid_color() -> [f32; 3] { [0.35, 0.35, 0.40] }
-fn default_uniform_background() -> bool { false }
-fn default_network_opacity() -> f32 { 0.95 }
-fn default_cell_opacity() -> f32 { 0.95 }
-fn default_gap_opacity() -> f32 { 0.95 }
+
fn default_cell_color() -> [f32; 3] { [0.13, 0.13, 0.16] }
fn default_gap_color() -> [f32; 3] { [0.07, 0.07, 0.09] }
@@ -647,27 +644,10 @@ pub fn push_circle_border_vertices(
}
}
-fn push_quad_vertices_clipped(
- x: f32, y: f32, w: f32, h: f32,
- surface_w: f32, surface_h: f32,
- color: [f32; 4],
- clip: (f32, f32, f32, f32),
- clip_circle: [f32; 3],
- out: &mut Vec<Vertex>,
-) {
- let (cx0, cy0, cx1, cy1) = clip;
- let ix0 = x.max(cx0);
- let iy0 = y.max(cy0);
- let ix1 = (x + w).min(cx1);
- let iy1 = (y + h).min(cy1);
- if ix1 <= ix0 || iy1 <= iy0 {
- return;
- }
- out.extend_from_slice(&quad_vertices_with_clip(ix0, iy0, ix1 - ix0, iy1 - iy0, surface_w, surface_h, color, clip_circle));
-}
+
#[derive(Clone, Copy, Debug, PartialEq)]
-struct ResizeDirection {
+pub struct ResizeDirection {
pub left: bool,
pub right: bool,
pub top: bool,
@@ -2201,7 +2181,7 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec
let device = &wgpu_adapter.device;
let queue = &wgpu_adapter.queue;
- let surface = &wgpu_adapter.surface;
+
let config = &wgpu_adapter.config;
let backdrop_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
@@ -3403,8 +3383,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec
let mut vp_y = 0.0;
let mut vp_h = 0.0;
- let mut sp_menub_y = 0.0;
- let mut sp_menub_h = 0.0;
let mut sp_y = 0.0;
let mut sp_h = 0.0;
@@ -3414,16 +3392,12 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec
let spreadsheet_h = body_h - viewport_h;
vp_y = 0.0;
vp_h = viewport_h;
- sp_menub_y = 0.0;
- sp_menub_h = 0.0;
sp_y = viewport_h;
sp_h = spreadsheet_h;
} else if viewport_visible {
vp_y = 0.0;
vp_h = body_h;
} else if spreadsheet_visible {
- sp_menub_y = 0.0;
- sp_menub_h = 0.0;
sp_y = 0.0;
sp_h = body_h;
}
@@ -5788,13 +5762,13 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec
// Copy backdrop to output swapchain texture
if !self.is_detached_network {
encoder.copy_texture_to_texture(
- wgpu::ImageCopyTexture {
+ wgpu::TexelCopyTextureInfo {
texture: &self.backdrop_texture,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
- wgpu::ImageCopyTexture {
+ wgpu::TexelCopyTextureInfo {
texture: &output.texture,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
diff --git a/src/geometry.rs b/src/geometry.rs
index 03584b1..908c44e 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -878,7 +878,7 @@ fn init_opencl() -> Option<OpenClCache> {
let device_id = device_id?;
let device = Device::new(device_id);
let context = Context::from_device(&device).ok()?;
- let queue = unsafe { CommandQueue::create(&context, device_id, 0) }.ok()?;
+ let queue = unsafe { CommandQueue::create_with_properties(&context, device_id, 0, 0) }.ok()?;
Some(OpenClCache {
device,
context,
diff --git a/src/main.rs b/src/main.rs
index c6389d6..a2c3668 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,6 @@
use std::time::Instant;
use std::fs;
use std::path::Path;
-use std::net::TcpListener;
-use std::io::{BufRead, BufReader, Read, Write};
use serde::{Deserialize, Serialize};
@@ -13,7 +11,7 @@ use smithay_client_toolkit::{
delegate_compositor, delegate_keyboard, delegate_pointer, delegate_registry,
delegate_seat, delegate_shm, delegate_xdg_shell, delegate_xdg_window, delegate_output,
registry::{ProvidesRegistryState, RegistryState},
- output::{OutputHandler, OutputState},
+ output::OutputState,
seat::{
keyboard::KeyboardHandler,
pointer::{PointerHandler, ThemedPointer, ThemeSpec, CursorIcon},
@@ -24,7 +22,6 @@ use smithay_client_toolkit::{
window::{Window as XdgWindow, WindowConfigure, WindowHandler, WindowDecorations},
XdgShell,
},
- WaylandSurface,
},
shm::{Shm, ShmHandler},
};
@@ -35,9 +32,8 @@ use wayland_client::{
};
use calloop_wayland_source::WaylandSource;
+use clear_ui::widget::{Breadcrumb, Canvas, MenuBar, Plate, ParametersBg, Splitter, Spreadsheet, StatusBar, ViewportBg, GraphNode, Graph, Paginator, Button, Checkbox, Slider, Spinbox, ScrollingList, Label, ColorSelector, Switcher};
use wgpu::util::DeviceExt;
-use clear_ui::widget::{Breadcrumb, Canvas, MenuBar, Plate, ParametersBg, Splitter, Spreadsheet, StatusBar, TextLabel, ViewportBg, Element, GraphNode, Graph, Paginator, Button, Checkbox, Slider, Spinbox, ScrollingList, Label, ColorSelector, Switcher};
-use clear_ui::colors;
use glyphon::{Attrs, Buffer, Cache, FontSystem, Metrics, Resolution, SwashCache, TextArea, TextAtlas, TextBounds, TextRenderer, Viewport};
use glam::{Mat4, Vec3};
@@ -50,12 +46,9 @@ pub mod project;
pub mod render;
pub mod shortcut;
-use app::{State, CustomEvent, HttpAction, ModifiersState, TouchPhase, DesignSettings, param_display, FsNode, Project, ProjectViewState, ParamDef};
+use app::{State, CustomEvent, HttpAction, ModifiersState};
use window::{AppState, WindowEvent};
use api::start_http_server;
-use geometry::*;
-use project::*;
-use render::*;
fn main() {
let args: Vec<String> = std::env::args().collect();
@@ -126,129 +119,7 @@ fn main() {
}
if !is_detached_network {
- let server_sender = sender.clone();
- std::thread::spawn(move || {
- let listener = match TcpListener::bind("127.0.0.1:3000") {
- Ok(l) => l,
- Err(e) => {
- eprintln!("Failed to bind HTTP server to port 3000: {:?}", e);
- return;
- }
- };
- println!("Embedded HTTP Server listening on http://127.0.0.1:3000");
-
- for stream in listener.incoming() {
- let stream = match stream {
- Ok(s) => s,
- Err(_) => continue,
- };
-
- let server_sender = server_sender.clone();
- std::thread::spawn(move || {
- let mut write_stream = match stream.try_clone() {
- Ok(s) => s,
- Err(_) => return,
- };
- let mut reader = BufReader::new(stream);
- let mut request_line = String::new();
- if reader.read_line(&mut request_line).is_err() {
- return;
- }
-
- if request_line.starts_with("GET /state") {
- let (tx, rx) = std::sync::mpsc::channel();
- if server_sender.send(CustomEvent::GetState(tx)).is_ok() {
- let response_body = rx.recv().unwrap_or_else(|_| "null".to_string());
- let response = format!(
- "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
- response_body.len(),
- response_body
- );
- let _ = write_stream.write_all(response.as_bytes());
- }
- } else if request_line.starts_with("POST /action") {
- let mut content_length = 0;
- loop {
- let mut header_line = String::new();
- if reader.read_line(&mut header_line).is_err() || header_line == "\r\n" || header_line == "\n" || header_line.is_empty() {
- break;
- }
- let lower = header_line.to_lowercase();
- if lower.starts_with("content-length:") {
- if let Some(val) = lower.split(':').nth(1) {
- if let Ok(len) = val.trim().parse::<usize>() {
- content_length = len;
- }
- }
- }
- }
-
- let mut body = vec![0; content_length];
- if reader.read_exact(&mut body).is_ok() {
- let body_str = String::from_utf8_lossy(&body);
- if let Ok(action) = serde_json::from_str::<HttpAction>(&body_str) {
- let (tx, rx) = std::sync::mpsc::channel();
- if server_sender.send(CustomEvent::PostAction(action, tx)).is_ok() {
- let res = rx.recv().unwrap_or_else(|_| Err("internal error".to_string()));
- let response = match res {
- Ok(msg) => {
- let body = format!("{{\"status\":\"success\",\"message\":\"{}\"}}", msg);
- format!(
- "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
- body.len(),
- body
- )
- }
- Err(err) => {
- let body = format!("{{\"status\":\"error\",\"error\":\"{}\"}}", err);
- format!(
- "HTTP/1.1 400 Bad Request\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
- body.len(),
- body
- )
- }
- };
- let _ = write_stream.write_all(response.as_bytes());
- } else {
- let body = "{\"status\":\"error\",\"error\":\"failed to send action to event loop\"}";
- let response = format!(
- "HTTP/1.1 500 Internal Server Error\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
- body.len(),
- body
- );
- let _ = write_stream.write_all(response.as_bytes());
- }
- } else {
- let body = "{\"status\":\"error\",\"error\":\"failed to parse action JSON\"}";
- let response = format!(
- "HTTP/1.1 400 Bad Request\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
- body.len(),
- body
- );
- let _ = write_stream.write_all(response.as_bytes());
- }
- } else {
- let body = "{\"status\":\"error\",\"error\":\"failed to read complete body\"}";
- let response = format!(
- "HTTP/1.1 400 Bad Request\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
- body.len(),
- body
- );
- let _ = write_stream.write_all(response.as_bytes());
- }
- } else {
- let body = "{\"error\":\"not found\"}";
- let response = format!(
- "HTTP/1.1 404 Not Found\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
- body.len(),
- body
- );
- let _ = write_stream.write_all(response.as_bytes());
- }
- let _ = write_stream.flush();
- });
- }
- });
+ start_http_server(sender.clone());
}
let mut event_loop = calloop::EventLoop::try_new().unwrap();
@@ -394,8 +265,9 @@ fn create_memfd_with_data(name: &str, data: &[u8]) -> std::io::Result<std::os::u
#[cfg(test)]
mod tests {
use super::*;
- use crate::app::{get_next_visible_pane, LEFT_MENUBAR_IDX, RIGHT_MENUBAR_IDX, PARAM_MENUBAR_IDX, SPREADSHEET_MENUBAR_IDX};
+ use crate::app::{get_next_visible_pane, LEFT_MENUBAR_IDX, RIGHT_MENUBAR_IDX, PARAM_MENUBAR_IDX, SPREADSHEET_MENUBAR_IDX, DesignSettings, param_display, FsNode, Project, ProjectViewState, ParamDef, TouchPhase};
use crate::shortcut::{Shortcut, ShortcutManager, Action};
+ use crate::geometry::{GAttribute, GVertex, Geometry, line_vertices};
#[test]
fn test_load_default_project() {
diff --git a/src/project.rs b/src/project.rs
index 8a56a9f..f88421f 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -1,9 +1,8 @@
use std::fs;
-use std::path::{Path, PathBuf};
-use std::time::Instant;
+use std::path::Path;
-use clear_ui::widget::{Button, Element};
-use crate::app::{State, Project, FsNode, ProjectViewState, param_display, CONTENT_IDX, ParamDef};
+use clear_ui::widget::Button;
+use crate::app::{State, Project, FsNode, ProjectViewState, CONTENT_IDX, ParamDef};
impl State {
diff --git a/src/render.rs b/src/render.rs
index c756c2f..33cc841 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -1,5 +1,3 @@
-use std::time::Instant;
-use std::path::Path;
use glyphon::{Buffer, Resolution, TextArea, TextBounds};
use clear_ui::widget::TextLabel;
@@ -7,12 +5,12 @@ use clear_ui::colors;
use clear_ui::widget::Element;
use crate::app::{
- State, FsNode, CustomEvent,
+ State, FsNode,
make_text_buffer, make_text_buffer_with_font,
CONTENT_IDX, VIEWPORT_IDX, PARAM_IDX, PARAM_PLATE_IDX,
BREADCRUMB_IDX, STATUS_IDX, HEADER_IDX, RIGHT_MENUBAR_IDX,
- SPREADSHEET_MENUBAR_IDX, SPLITTER1_IDX, SPLITTER2_IDX,
- MENUBAR_H, STATUS_H, HEADER_H, SPLITTER_W,
+ SPREADSHEET_MENUBAR_IDX,
+ MENUBAR_H, STATUS_H,
LEFT_MENUBAR_IDX, PARAM_MENUBAR_IDX, NETWORK_PANEL_IDX,
push_circle_vertices, push_circle_border_vertices,
};
@@ -985,23 +983,4 @@ impl State {
}
-fn push_widget_popover_vertices(px: f32, py: f32, pw: f32, ph: f32, sw: f32, sh: f32, verts: &mut Vec<Vertex>) {
- let color = [0.12, 0.12, 0.15, 0.95];
- let ndc_x = (px / sw) * 2.0 - 1.0;
- let ndc_y = 1.0 - (py / sh) * 2.0;
- let ndc_w = (pw / sw) * 2.0;
- let ndc_h = (ph / sh) * 2.0;
-
- let v_tl = Vertex { position: [ndc_x, ndc_y], color, clip_circle: [0.0, 0.0, 0.0] };
- let v_tr = Vertex { position: [ndc_x + ndc_w, ndc_y], color, clip_circle: [0.0, 0.0, 0.0] };
- let v_bl = Vertex { position: [ndc_x, ndc_y - ndc_h], color, clip_circle: [0.0, 0.0, 0.0] };
- let v_br = Vertex { position: [ndc_x + ndc_w, ndc_y - ndc_h], color, clip_circle: [0.0, 0.0, 0.0] };
-
- verts.push(v_tl);
- verts.push(v_tr);
- verts.push(v_bl);
-
- verts.push(v_tr);
- verts.push(v_br);
- verts.push(v_bl);
-}
+
diff --git a/src/window.rs b/src/window.rs
index f9dd0e9..3135d77 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -2,7 +2,7 @@ use std::time::Instant;
use std::fs;
use std::path::Path;
use std::net::TcpListener;
-use std::io::{BufRead, BufReader, Read, Write};
+
use serde::{Deserialize, Serialize};
@@ -24,7 +24,7 @@ use smithay_client_toolkit::{
window::{Window as XdgWindow, WindowConfigure, WindowHandler, WindowDecorations},
XdgShell,
},
- WaylandSurface,
+
},
shm::{Shm, ShmHandler},
};
@@ -273,7 +273,6 @@ impl PointerHandler for AppState {
use smithay_client_toolkit::seat::pointer::PointerEventKind;
for event in events {
if let Some(st) = &mut self.state {
- let (cx, cy) = clear_ui::wayland::scale_pointer_pos(event.position, st.scale);
st.cursor_x = event.position.0 as f32;
st.cursor_y = event.position.1 as f32;
match &event.kind {