chore: initial commit
This commit is contained in:
commit
f8497769f3
|
@ -0,0 +1 @@
|
|||
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "ruler2"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
eframe = { version = "0.17", features = ["persistence"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
|
@ -0,0 +1,104 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use eframe::{egui, epi};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(default)]
|
||||
pub struct App {
|
||||
|
||||
}
|
||||
|
||||
impl Default for App {
|
||||
fn default() -> Self {
|
||||
App {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl epi::App for App {
|
||||
fn name(&self) -> &str {
|
||||
"Ruler 2"
|
||||
}
|
||||
|
||||
fn setup(&mut self, _ctx: &egui::Context, _frame: &epi::Frame, storage: Option<&dyn epi::Storage>) {
|
||||
if let Some(storage) = storage {
|
||||
*self = epi::get_value(storage, epi::APP_KEY).unwrap_or_default();
|
||||
}
|
||||
}
|
||||
|
||||
fn save(&mut self, storage: &mut dyn epi::Storage) {
|
||||
epi::set_value(storage, epi::APP_KEY, self);
|
||||
}
|
||||
|
||||
fn clear_color(&self) -> egui::Rgba {
|
||||
egui::Rgba::from_black_alpha(0.5)
|
||||
}
|
||||
|
||||
fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
fill: egui::Color32::TRANSPARENT,
|
||||
stroke: egui::Stroke {
|
||||
width: 1.0,
|
||||
color: egui::Color32::BLACK,
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.show(ctx, |ui| {
|
||||
let avail = ui.available_size();
|
||||
|
||||
// allocate all available size for drawing and senses
|
||||
let resp = ui.allocate_response(avail, egui::Sense::drag());
|
||||
|
||||
// allow dragging the window by dragging anywhere
|
||||
if resp.dragged_by(egui::PointerButton::Primary) && !ctx.input().modifiers.shift {
|
||||
frame.drag_window();
|
||||
}
|
||||
|
||||
// draw lines for x axis
|
||||
let painter = ui.painter();
|
||||
let ppp = ui.ctx().pixels_per_point();
|
||||
let unit = 1.0 / ppp;
|
||||
|
||||
for i in 0..avail.x as u64 {
|
||||
let length = if i % 10 == 0 {
|
||||
8.0
|
||||
} else if i % 2 == 0 {
|
||||
4.0
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let rounded = painter.round_to_pixel(i as f32);
|
||||
painter.line_segment(
|
||||
[egui::Pos2::new(rounded, 0.0), egui::Pos2::new(rounded, length)],
|
||||
(unit, egui::Color32::WHITE),
|
||||
);
|
||||
}
|
||||
|
||||
// draw line where hovered
|
||||
let hover = ui.input().pointer.hover_pos().clone();
|
||||
if let Some(pos) = hover {
|
||||
let rounded = painter.round_to_pixel(pos.x);
|
||||
painter.line_segment(
|
||||
[egui::Pos2::new(rounded, 0.0), egui::Pos2::new(rounded, avail.y)],
|
||||
(unit, egui::Color32::RED),
|
||||
);
|
||||
|
||||
let text = painter.layout_no_wrap(
|
||||
format!("{}, {}", rounded * ppp, painter.round_to_pixel(pos.y) * ppp),
|
||||
egui::FontId::proportional(14.0),
|
||||
egui::Color32::WHITE,
|
||||
);
|
||||
let y = avail.y - text.mesh_bounds.max.y - 4.0;
|
||||
painter.galley(egui::Pos2::new(4.0, y), text);
|
||||
}
|
||||
|
||||
// show context menu
|
||||
resp.context_menu(|ui| {
|
||||
if ui.button("Quit").clicked() {
|
||||
frame.quit();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
mod app;
|
||||
|
||||
fn main() {
|
||||
let app = crate::app::App::default();
|
||||
let native_options = eframe::NativeOptions {
|
||||
decorated: false,
|
||||
transparent: true,
|
||||
resizable: true,
|
||||
initial_window_size: Some(eframe::egui::Vec2::new(450.0, 100.0)),
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(Box::new(app), native_options);
|
||||
}
|
Loading…
Reference in New Issue