mirror of
https://github.com/Astatin3/raylock.git
synced 2026-06-09 00:28:00 -06:00
Add transparency and lock
This commit is contained in:
+7
-2
@@ -4,5 +4,10 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
eframe = "0.29.1"
|
eframe = "0.28"
|
||||||
egui = "0.29.1"
|
egui = "0.28"
|
||||||
|
portable-pty = "0.8.1"
|
||||||
|
termwiz = "0.22.0"
|
||||||
|
vte = "0.13.0"
|
||||||
|
egui-terminal = { git = "https://github.com/Quinntyx/egui-terminal" }
|
||||||
|
ecolor = "0.29.1"
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ Unfortunatly this is not the most secure desktop locker, as it involves using sw
|
|||||||
|
|
||||||
```
|
```
|
||||||
# Add this to your sway config:
|
# Add this to your sway config:
|
||||||
mode "lock" { }
|
for_window [title="^raylock$"] sticky enable, floating enable, resize set 1920 px 1080 px, title_format "", border pixel none
|
||||||
for_window [title="^raylock$"] sticky enable, fullscreen
|
mode "lock" {
|
||||||
|
bindsym $mod+Shift+q exec true
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,19 +1,45 @@
|
|||||||
use egui::Key;
|
use egui::Key;
|
||||||
|
use std::fs::{exists, File};
|
||||||
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
const LOCK_FILEPATH: &str = "/tmp/.raylock.lock";
|
||||||
|
|
||||||
pub fn sway_lock_input() {
|
pub fn sway_lock_input() {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let _ = Command::new("swaymsg").args(["mode", "lock"]).spawn();
|
let _ = Command::new("swaymsg").args(["mode", "lock"]).spawn();
|
||||||
|
let _ = Command::new("swaymsg")
|
||||||
|
.args(["input", "type:touchpad", "events", "disabled"])
|
||||||
|
.spawn();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sway_unlock_input() {
|
pub fn sway_unlock_input() {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let _ = Command::new("swaymsg").args(["mode", "default"]).spawn();
|
let _ = Command::new("swaymsg").args(["mode", "default"]).spawn();
|
||||||
|
let _ = Command::new("swaymsg")
|
||||||
|
.args(["input", "type:touchpad", "events", "enabled"])
|
||||||
|
.spawn();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_lock() {
|
||||||
|
let _ = File::create(LOCK_FILEPATH).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_locked() -> bool {
|
||||||
|
Path::exists(Path::new(LOCK_FILEPATH))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_lock() {
|
||||||
|
if !is_locked() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fs::remove_file(Path::new(LOCK_FILEPATH));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn format_key(key: Key, shift_pressed: bool) -> String {
|
pub fn format_key(key: Key, shift_pressed: bool) -> String {
|
||||||
match key {
|
match key {
|
||||||
// Letters
|
// Letters
|
||||||
|
|||||||
+143
-12
@@ -1,17 +1,69 @@
|
|||||||
use eframe::egui;
|
use eframe::{egui, App};
|
||||||
|
use egui::FontFamily;
|
||||||
use egui::Key;
|
use egui::Key;
|
||||||
|
use egui_terminal;
|
||||||
|
use input::is_locked;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
// use egui::epaint::text::{FontInsert, InsertFontFamily};
|
||||||
|
|
||||||
|
use eframe::CreationContext;
|
||||||
|
use egui::ecolor::Color32;
|
||||||
|
use egui::FontId;
|
||||||
|
use egui::Stroke;
|
||||||
|
use egui_terminal::prelude::*;
|
||||||
|
use egui_terminal::render::CursorType;
|
||||||
|
|
||||||
|
use egui::ecolor::HexColor;
|
||||||
|
|
||||||
mod input;
|
mod input;
|
||||||
|
mod splitter;
|
||||||
mod structs;
|
mod structs;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
// Demonstrates how to add a font to the existing ones
|
||||||
|
fn add_font(ctx: &egui::Context) {
|
||||||
|
// Start with the default fonts (we will be adding to them rather than replacing them).
|
||||||
|
let mut fonts = egui::FontDefinitions::default();
|
||||||
|
|
||||||
|
// Install my own font (maybe supporting non-latin characters).
|
||||||
|
// .ttf and .otf files supported.
|
||||||
|
fonts.font_data.insert(
|
||||||
|
"my_font".to_owned(),
|
||||||
|
egui::FontData::from_static(include_bytes!(
|
||||||
|
"/home/astatin3/.fonts/UbuntuMono/UbuntuMonoNerdFontMono-Regular.ttf"
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Put my font first (highest priority) for proportional text:
|
||||||
|
// fonts
|
||||||
|
// .families
|
||||||
|
// .entry(egui::FontFamily::Proportional)
|
||||||
|
// .or_default()
|
||||||
|
// .insert(0, "my_font".to_owned());
|
||||||
|
|
||||||
|
// Put my font as last fallback for monospace:
|
||||||
|
fonts
|
||||||
|
.families
|
||||||
|
.entry(egui::FontFamily::Monospace)
|
||||||
|
.or_default()
|
||||||
|
.push("my_font".to_owned());
|
||||||
|
|
||||||
|
// Tell egui to use these fonts:
|
||||||
|
ctx.set_fonts(fonts);
|
||||||
|
}
|
||||||
|
|
||||||
|
use splitter::Splitter;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ExampleApp {
|
struct ExampleApp {
|
||||||
auth_state: Arc<Mutex<structs::AuthState>>,
|
auth_state: Arc<Mutex<structs::AuthState>>,
|
||||||
|
terminals: HashMap<String, TermHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExampleApp {
|
impl ExampleApp {
|
||||||
@@ -21,9 +73,34 @@ impl ExampleApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl eframe::App for ExampleApp {
|
impl eframe::App for ExampleApp {
|
||||||
|
fn clear_color(&self, _visuals: &egui::Visuals) -> [f32; 4] {
|
||||||
|
egui::Rgba::from_rgba_unmultiplied(0.1, 0.1, 0.1, 0.9).to_array()
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
|
// let s1 = self.terminals.get_mut("0").unwrap();
|
||||||
|
// s1.style()
|
||||||
|
// s1.cursor_trail = false;
|
||||||
|
// s1.cursor_trail_color = Some(HexColor::Hex8(Color32::LIGHT_BLUE.gamma_multiply(0.5)));
|
||||||
|
|
||||||
|
// s1.default_focus_cursor = CursorType::OpenBlock(HexColor::Hex8(Color32::RED));
|
||||||
|
// s1.default_unfocus_cursor = CursorType::None;
|
||||||
|
// for str in egui::FontDefinitions::builtin_font_names() {
|
||||||
|
// println!("{}", str);
|
||||||
|
// }
|
||||||
|
// s1.cursor_stroke = Stroke::new(1., Color32::WHITE);
|
||||||
|
|
||||||
|
// add_font(ctx);
|
||||||
|
|
||||||
|
// let font = FontId {
|
||||||
|
// size: 9.,
|
||||||
|
// family: FontFamily::Name("my_font".into()),
|
||||||
|
// };
|
||||||
|
|
||||||
|
// s1.font = font;
|
||||||
|
|
||||||
let mut state = self.auth_state.lock().unwrap();
|
let mut state = self.auth_state.lock().unwrap();
|
||||||
ctx.set_pixels_per_point(1.5);
|
//ctx.set_pixels_per_point(1.5);
|
||||||
|
|
||||||
if ctx.input(|i| i.events.len() > 0) {
|
if ctx.input(|i| i.events.len() > 0) {
|
||||||
ctx.input(|i| {
|
ctx.input(|i| {
|
||||||
@@ -62,13 +139,46 @@ impl eframe::App for ExampleApp {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
// let sine_points = PlotPoints::from_explicit_callback(|x| x.sin(), .., 5000);
|
||||||
// ui.add_space(200.0);
|
// let plot_a_lines = [Line::new(sine_points).name("Sine")];
|
||||||
// ui.heading("*".repeat(state.password.clone().len()));
|
|
||||||
// ui.add_space(20.0);
|
// let sine_points2 = PlotPoints::from_explicit_callback(|x| x.sin(), .., 5000);
|
||||||
//
|
// let plot_b_lines = [Line::new(sine_points2).name("Sine")];
|
||||||
ui::update(state, ctx, _frame, ui);
|
|
||||||
});
|
egui::CentralPanel::default()
|
||||||
|
.frame(egui::Frame::none())
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
// let ht = ui.available_height();
|
||||||
|
// for (_idx, (_id, term)) in self.terminals.iter_mut().enumerate() {
|
||||||
|
// ui.terminal_sized(term, egui::vec2(ui.available_width(), ht));
|
||||||
|
// }
|
||||||
|
// ui.add_space(200.0);
|
||||||
|
// ui.heading("*".repeat(state.password.clone().len()));
|
||||||
|
// ui.add_space(20.0);
|
||||||
|
//
|
||||||
|
|
||||||
|
// ui.terminal_sized(
|
||||||
|
// self.terminals.get_mut("0").unwrap(),
|
||||||
|
// egui::vec2(ui.available_width(), ui.available_height()),
|
||||||
|
// );
|
||||||
|
// Splitter::new("some_unique_id", splitter::SplitterAxis::Horizontal).show(
|
||||||
|
// ui,
|
||||||
|
// |ui_a, ui_b| {
|
||||||
|
// ui_a.terminal_sized(
|
||||||
|
// self.terminals.get_mut("0").unwrap(),
|
||||||
|
// egui::vec2(ui_a.available_width(), ui_a.available_height()),
|
||||||
|
// );
|
||||||
|
|
||||||
|
// ui_b.terminal_sized(
|
||||||
|
// self.terminals.get_mut("1h-1").unwrap(),
|
||||||
|
// egui::vec2(ui_a.available_width(), ui_a.available_height()),
|
||||||
|
// );
|
||||||
|
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
|
||||||
|
ui::update_password_viewer(state, ctx, _frame, ui);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +188,10 @@ fn main() -> eframe::Result<()> {
|
|||||||
..eframe::NativeOptions::default()
|
..eframe::NativeOptions::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// let system_shell = std::env::var("SHELL")
|
||||||
|
// .expect("SHELL variable is not defined")
|
||||||
|
// .to_string();
|
||||||
|
|
||||||
let state = Arc::new(Mutex::new(structs::AuthState {
|
let state = Arc::new(Mutex::new(structs::AuthState {
|
||||||
password: String::new(),
|
password: String::new(),
|
||||||
to_be_submitted: false,
|
to_be_submitted: false,
|
||||||
@@ -94,12 +208,13 @@ fn main() -> eframe::Result<()> {
|
|||||||
let result = try_sudo(&state.password);
|
let result = try_sudo(&state.password);
|
||||||
match result {
|
match result {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
println!("True");
|
// println!("True");
|
||||||
input::sway_unlock_input();
|
input::sway_unlock_input();
|
||||||
|
input::remove_lock();
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
Ok(false) => {
|
Ok(false) => {
|
||||||
println!("False");
|
// println!("False");
|
||||||
state.failed_attempts += 1;
|
state.failed_attempts += 1;
|
||||||
state.password.clear();
|
state.password.clear();
|
||||||
}
|
}
|
||||||
@@ -113,12 +228,28 @@ fn main() -> eframe::Result<()> {
|
|||||||
thread::sleep(Duration::from_millis(100));
|
thread::sleep(Duration::from_millis(100));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
// map.insert(String::from("0"), TermHandler::new_from_str("btop"));
|
||||||
|
// map.insert(String::from("1h-0"), TermHandler::new_from_str("nvitop"));
|
||||||
|
// map.insert(String::from("1h-1"), TermHandler::new_from_str("neofetch"));
|
||||||
input::sway_lock_input();
|
input::sway_lock_input();
|
||||||
|
|
||||||
|
if input::is_locked() {
|
||||||
|
println!("Raylock is already running!");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
input::create_lock();
|
||||||
|
|
||||||
eframe::run_native(
|
eframe::run_native(
|
||||||
ExampleApp::name(),
|
ExampleApp::name(),
|
||||||
native_options,
|
native_options,
|
||||||
Box::new(|_| Ok(Box::<ExampleApp>::new(ExampleApp { auth_state: state }))),
|
Box::new(|_| {
|
||||||
|
Ok(Box::<ExampleApp>::new(ExampleApp {
|
||||||
|
auth_state: state,
|
||||||
|
terminals: map,
|
||||||
|
}))
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+190
@@ -0,0 +1,190 @@
|
|||||||
|
/// https://gist.github.com/mkalte666/f9a982be0ac0276080d3434ab9ea4655
|
||||||
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
use egui::{CursorIcon, Id, Layout, Pos2, Rect, Rounding, Sense, Ui, Vec2};
|
||||||
|
|
||||||
|
/// An axis that a Splitter can use
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum SplitterAxis {
|
||||||
|
Horizontal,
|
||||||
|
Vertical,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The internal data used by a splitter. Stored into memory
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct SplitterData {
|
||||||
|
axis: SplitterAxis,
|
||||||
|
pos: f32,
|
||||||
|
min_size: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Splits a ui in half, using a draggable separator in the middle.
|
||||||
|
///
|
||||||
|
pub struct Splitter {
|
||||||
|
id: Id,
|
||||||
|
data: SplitterData,
|
||||||
|
}
|
||||||
|
impl Splitter {
|
||||||
|
/// Create a new Splitter
|
||||||
|
pub fn new(id_source: impl Hash, axis: SplitterAxis) -> Self {
|
||||||
|
Self {
|
||||||
|
id: Id::new(id_source),
|
||||||
|
data: SplitterData {
|
||||||
|
axis,
|
||||||
|
pos: 0.5,
|
||||||
|
min_size: 0.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the minimum allowed size for the area
|
||||||
|
pub fn min_size(mut self, points: f32) -> Self {
|
||||||
|
self.data.min_size = points;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Thes the default position of the splitter separator. Usually it sits in the center, this moves it around.
|
||||||
|
pub fn default_pos(mut self, pos: f32) -> Self {
|
||||||
|
self.data.pos = pos;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Show the splitter and fill it with content.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// Splitter::new("some_plot_split", SplitterAxis::Vertical)
|
||||||
|
/// .min_size(250.0)
|
||||||
|
/// .default_pos(2.0 / 3.0)
|
||||||
|
/// .show(ui, |ui_a, ui_b| {
|
||||||
|
/// Plot::new("plot_a")
|
||||||
|
/// .legend(Legend::default())
|
||||||
|
/// .x_axis_formatter(log_formatter)
|
||||||
|
/// .y_axis_formatter(log_formatter)
|
||||||
|
/// .x_axis_label("X Axis")
|
||||||
|
/// .y_axis_label("A Axis")
|
||||||
|
/// .link_axis("axis_link", true, false)
|
||||||
|
/// .link_cursor("cursor_link", true, false)
|
||||||
|
/// .show(ui_a, |plot_ui| {
|
||||||
|
/// for line in plot_a_lines {
|
||||||
|
/// plot_ui.line(line);
|
||||||
|
/// }
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// Plot::new("plot_b")
|
||||||
|
/// .legend(Legend::default())
|
||||||
|
/// .x_axis_formatter(log_formatter)
|
||||||
|
/// .x_axis_label("X Axis")
|
||||||
|
/// .y_axis_label("Y Axis")
|
||||||
|
/// .link_axis("axis_link", true, false)
|
||||||
|
/// .link_cursor("cursor_link", true, false)
|
||||||
|
/// .show(ui_b, |plot_ui| {
|
||||||
|
/// for line in plot_b_lines {
|
||||||
|
/// plot_ui.line(line);
|
||||||
|
/// }
|
||||||
|
/// });
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
pub fn show(mut self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui, &mut Ui)) {
|
||||||
|
let mut data = if let Some(d) = ui.memory(|mem| mem.data.get_temp(self.id)) {
|
||||||
|
d
|
||||||
|
} else {
|
||||||
|
self.data.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
let sep_size = 10.0;
|
||||||
|
let sep_stroke = 2.0;
|
||||||
|
let whole_area = ui.available_size();
|
||||||
|
|
||||||
|
let split_axis_size = match data.axis {
|
||||||
|
SplitterAxis::Horizontal => whole_area.x,
|
||||||
|
SplitterAxis::Vertical => whole_area.y,
|
||||||
|
};
|
||||||
|
let split_a_size = ((split_axis_size - sep_size) * data.pos);
|
||||||
|
let split_b_size = split_axis_size - sep_size - split_a_size;
|
||||||
|
|
||||||
|
let child_size_a = match data.axis {
|
||||||
|
SplitterAxis::Horizontal => Vec2::new(split_a_size, whole_area.y),
|
||||||
|
SplitterAxis::Vertical => Vec2::new(whole_area.x, split_a_size),
|
||||||
|
};
|
||||||
|
|
||||||
|
let child_size_b = match data.axis {
|
||||||
|
SplitterAxis::Horizontal => Vec2::new(split_b_size, whole_area.y),
|
||||||
|
SplitterAxis::Vertical => Vec2::new(whole_area.x, split_b_size),
|
||||||
|
};
|
||||||
|
|
||||||
|
let child_rect_a = Rect::from_min_size(ui.next_widget_position(), child_size_a);
|
||||||
|
let mut ui_a = ui.child_ui(child_rect_a, Layout::default(), None);
|
||||||
|
|
||||||
|
let sep_rect = match data.axis {
|
||||||
|
SplitterAxis::Horizontal => Rect::from_min_size(
|
||||||
|
Pos2::new(child_rect_a.max.x, child_rect_a.min.y),
|
||||||
|
Vec2::new(sep_size, whole_area.y),
|
||||||
|
),
|
||||||
|
SplitterAxis::Vertical => Rect::from_min_size(
|
||||||
|
Pos2::new(child_rect_a.min.x, child_rect_a.max.y),
|
||||||
|
Vec2::new(whole_area.x, sep_size),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let resp = ui.allocate_rect(sep_rect, Sense::hover().union(Sense::click_and_drag()));
|
||||||
|
|
||||||
|
let sep_draw_rect = match data.axis {
|
||||||
|
SplitterAxis::Horizontal => Rect::from_min_size(
|
||||||
|
Pos2::new(
|
||||||
|
sep_rect.min.x + sep_size / 2.0 - sep_stroke / 2.0,
|
||||||
|
sep_rect.min.y,
|
||||||
|
),
|
||||||
|
Vec2::new(sep_stroke, sep_rect.height()),
|
||||||
|
),
|
||||||
|
SplitterAxis::Vertical => Rect::from_min_size(
|
||||||
|
Pos2::new(
|
||||||
|
sep_rect.min.x,
|
||||||
|
sep_rect.min.y + sep_size / 2.0 - sep_stroke / 2.0,
|
||||||
|
),
|
||||||
|
Vec2::new(sep_rect.width(), sep_stroke),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
ui.painter().rect_filled(
|
||||||
|
sep_draw_rect,
|
||||||
|
Rounding::ZERO,
|
||||||
|
ui.style().visuals.noninteractive().bg_stroke.color,
|
||||||
|
);
|
||||||
|
|
||||||
|
let child_rect_b = match data.axis {
|
||||||
|
SplitterAxis::Horizontal => {
|
||||||
|
Rect::from_min_size(Pos2::new(sep_rect.max.x, sep_rect.min.y), child_size_b)
|
||||||
|
}
|
||||||
|
SplitterAxis::Vertical => {
|
||||||
|
Rect::from_min_size(Pos2::new(sep_rect.min.x, sep_rect.max.y), child_size_b)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut ui_b = ui.child_ui(child_rect_b, Layout::default(), None);
|
||||||
|
|
||||||
|
add_contents(&mut ui_a, &mut ui_b);
|
||||||
|
|
||||||
|
if resp.hovered() {
|
||||||
|
match data.axis {
|
||||||
|
SplitterAxis::Horizontal => ui.ctx().set_cursor_icon(CursorIcon::ResizeVertical),
|
||||||
|
SplitterAxis::Vertical => ui.ctx().set_cursor_icon(CursorIcon::ResizeHorizontal),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.dragged() {
|
||||||
|
let delta_pos = match data.axis {
|
||||||
|
SplitterAxis::Horizontal => resp.drag_delta().x / whole_area.x,
|
||||||
|
SplitterAxis::Vertical => resp.drag_delta().y / whole_area.y,
|
||||||
|
};
|
||||||
|
|
||||||
|
data.pos += delta_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clip pos
|
||||||
|
let min_pos = (data.min_size / split_axis_size).min(1.0);
|
||||||
|
let max_pos = (1.0 - min_pos).max(0.0);
|
||||||
|
data.pos = data.pos.max(min_pos).min(max_pos);
|
||||||
|
|
||||||
|
ui.memory_mut(|mem| {
|
||||||
|
mem.data.insert_temp(self.id, data);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ const LOGIN_FAIL_COUNT_CIRCLE_STROKE: Stroke = Stroke {
|
|||||||
color: LOGIN_FAIL_COLOR,
|
color: LOGIN_FAIL_COLOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn rotCircle(i: i16, center: Pos2, rad: f32, offset_ang: f32, ang_per_num: f32) -> Pos2 {
|
fn rot_circle(i: i16, center: Pos2, rad: f32, offset_ang: f32, ang_per_num: f32) -> Pos2 {
|
||||||
center
|
center
|
||||||
+ (egui::Vec2 {
|
+ (egui::Vec2 {
|
||||||
x: rad * f32::cos(i as f32 * ang_per_num + offset_ang),
|
x: rad * f32::cos(i as f32 * ang_per_num + offset_ang),
|
||||||
@@ -41,7 +41,7 @@ fn rotCircle(i: i16, center: Pos2, rad: f32, offset_ang: f32, ang_per_num: f32)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(
|
pub fn update_password_viewer(
|
||||||
wstate: MutexGuard<'_, structs::AuthState>,
|
wstate: MutexGuard<'_, structs::AuthState>,
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
@@ -71,7 +71,7 @@ pub fn update(
|
|||||||
let ang_per_fail = 2. * PI / state.failed_attempts as f32;
|
let ang_per_fail = 2. * PI / state.failed_attempts as f32;
|
||||||
let len: i16 = state.password.len() as i16;
|
let len: i16 = state.password.len() as i16;
|
||||||
|
|
||||||
let mut last_pos = rotCircle(
|
let mut last_pos = rot_circle(
|
||||||
len - 1,
|
len - 1,
|
||||||
center,
|
center,
|
||||||
LOGIN_CIRCLE_RADIUS,
|
LOGIN_CIRCLE_RADIUS,
|
||||||
@@ -84,7 +84,7 @@ pub fn update(
|
|||||||
if state.failed_attempts <= 1 {
|
if state.failed_attempts <= 1 {
|
||||||
center
|
center
|
||||||
} else {
|
} else {
|
||||||
rotCircle(
|
rot_circle(
|
||||||
i as i16,
|
i as i16,
|
||||||
center,
|
center,
|
||||||
LOGIN_FAIL_COUNT_CIRCLE_RADIUS,
|
LOGIN_FAIL_COUNT_CIRCLE_RADIUS,
|
||||||
@@ -107,7 +107,7 @@ pub fn update(
|
|||||||
if len <= 1 {
|
if len <= 1 {
|
||||||
center
|
center
|
||||||
} else {
|
} else {
|
||||||
rotCircle(
|
rot_circle(
|
||||||
i,
|
i,
|
||||||
center,
|
center,
|
||||||
LOGIN_CIRCLE_RADIUS,
|
LOGIN_CIRCLE_RADIUS,
|
||||||
|
|||||||
Reference in New Issue
Block a user