fix: next button disabled when user form is incomplete

- gradient_button now accepts enabled parameter; uses Sense::hover() and muted colors when disabled
- Added primary_button_enabled, secondary_button_enabled, danger_button_enabled variants
- main.rs: next button uses primary_button_enabled(..., is_valid) so it's grayed out and non-clickable when form incomplete
This commit is contained in:
Erkan IŞIK
2026-06-24 07:44:28 +03:00
parent 5e66e151bd
commit 35ddd0e933
2 changed files with 43 additions and 32 deletions
+1 -5
View File
@@ -455,11 +455,7 @@ impl eframe::App for YaliApp {
// if !is_exec && !is_finish && ui::theme::danger_button(ui, &t!("cancel")).clicked() { // if !is_exec && !is_finish && ui::theme::danger_button(ui, &t!("cancel")).clicked() {
// self.show_cancel_dialog = true; // self.show_cancel_dialog = true;
// }; // };
let next_clicked = if is_valid { let next_clicked = ui::theme::primary_button_enabled(ui, &next_label, is_valid).clicked();
ui::theme::primary_button(ui, &next_label).clicked()
} else {
ui::theme::secondary_button(ui, &next_label).clicked()
};
if next_clicked { if next_clicked {
self.state.current_step += 1; self.state.current_step += 1;
} }
+42 -27
View File
@@ -9,7 +9,7 @@ fn lerp_color(a: Color32, b: Color32, t: f32) -> Color32 {
) )
} }
fn gradient_button(ui: &mut egui::Ui, text: &str, top_color: Color32, bottom_color: Color32, text_color: Color32, hover_top: Color32, hover_bottom: Color32, border_color: Color32) -> egui::Response { fn gradient_button(ui: &mut egui::Ui, text: &str, top_color: Color32, bottom_color: Color32, text_color: Color32, hover_top: Color32, hover_bottom: Color32, border_color: Color32, enabled: bool) -> egui::Response {
let rounding = Rounding::same(6.0); let rounding = Rounding::same(6.0);
let min_size = Vec2::new(100.0, 32.0); let min_size = Vec2::new(100.0, 32.0);
let padding = Vec2::new(12.0, 6.0); let padding = Vec2::new(12.0, 6.0);
@@ -27,13 +27,26 @@ fn gradient_button(ui: &mut egui::Ui, text: &str, top_color: Color32, bottom_col
min_size.y.max(galley.size().y + 2.0 * padding.y), min_size.y.max(galley.size().y + 2.0 * padding.y),
); );
let (rect, response) = ui.allocate_exact_size(size, egui::Sense::click()); let sense = if enabled { egui::Sense::click() } else { egui::Sense::hover() };
let (rect, response) = ui.allocate_exact_size(size, sense);
let (actual_top, actual_bottom, actual_text, actual_border) = if enabled {
let hover_gradient = if response.hovered() {
(hover_top, hover_bottom)
} else {
(top_color, bottom_color)
};
(hover_gradient.0, hover_gradient.1, text_color, border_color)
} else {
let disabled = lerp_color(top_color, Color32::from_rgb(80, 80, 80), 0.5);
(disabled, disabled, Color32::from_gray(160), Color32::from_gray(100))
};
let n_strips = 16; let n_strips = 16;
for i in 0..n_strips { for i in 0..n_strips {
let t = i as f32 / n_strips as f32; let t = i as f32 / n_strips as f32;
let t2 = (i + 1) as f32 / n_strips as f32; let t2 = (i + 1) as f32 / n_strips as f32;
let c = lerp_color(top_color, bottom_color, (t + t2) * 0.5); let c = lerp_color(actual_top, actual_bottom, (t + t2) * 0.5);
let y0 = rect.top() + rect.height() * t; let y0 = rect.top() + rect.height() * t;
let y1 = rect.top() + rect.height() * t2; let y1 = rect.top() + rect.height() * t2;
let strip_rect = egui::Rect::from_min_max( let strip_rect = egui::Rect::from_min_max(
@@ -43,27 +56,12 @@ fn gradient_button(ui: &mut egui::Ui, text: &str, top_color: Color32, bottom_col
ui.painter().rect(strip_rect, Rounding::ZERO, c, Stroke::NONE); ui.painter().rect(strip_rect, Rounding::ZERO, c, Stroke::NONE);
} }
if response.hovered() { ui.painter().rect(rect, rounding, Color32::TRANSPARENT, Stroke::new(1.0, actual_border));
for i in 0..n_strips {
let t = i as f32 / n_strips as f32;
let t2 = (i + 1) as f32 / n_strips as f32;
let c = lerp_color(hover_top, hover_bottom, (t + t2) * 0.5);
let y0 = rect.top() + rect.height() * t;
let y1 = rect.top() + rect.height() * t2;
let strip_rect = egui::Rect::from_min_max(
egui::pos2(rect.left(), y0),
egui::pos2(rect.right(), y1),
);
ui.painter().rect(strip_rect, Rounding::ZERO, c, Stroke::NONE);
}
}
ui.painter().rect(rect, rounding, Color32::TRANSPARENT, Stroke::new(1.0, border_color));
ui.painter().galley( ui.painter().galley(
egui::pos2(rect.center().x - galley.size().x / 2.0, rect.center().y - galley.size().y / 2.0), egui::pos2(rect.center().x - galley.size().x / 2.0, rect.center().y - galley.size().y / 2.0),
galley, galley,
text_color, actual_text,
); );
if let Some(cursor) = ui.visuals().interact_cursor { if let Some(cursor) = ui.visuals().interact_cursor {
@@ -76,34 +74,48 @@ fn gradient_button(ui: &mut egui::Ui, text: &str, top_color: Color32, bottom_col
} }
pub fn primary_button(ui: &mut egui::Ui, text: &str) -> egui::Response { pub fn primary_button(ui: &mut egui::Ui, text: &str) -> egui::Response {
primary_button_enabled(ui, text, true)
}
pub fn primary_button_enabled(ui: &mut egui::Ui, text: &str, enabled: bool) -> egui::Response {
gradient_button(ui, text, gradient_button(ui, text,
Color32::from_rgb(50, 130, 255), Color32::from_rgb(50, 130, 255),
Color32::from_rgb(13, 110, 253), Color32::from_rgb(13, 110, 253),
Color32::WHITE, Color32::WHITE,
Color32::from_rgb(70, 150, 255), Color32::from_rgb(70, 150, 255),
Color32::from_rgb(30, 130, 255), Color32::from_rgb(30, 130, 255),
Color32::from_rgb(13, 110, 253)) Color32::from_rgb(13, 110, 253),
enabled)
} }
pub fn secondary_button(ui: &mut egui::Ui, text: &str) -> egui::Response { pub fn secondary_button(ui: &mut egui::Ui, text: &str) -> egui::Response {
secondary_button_enabled(ui, text, true)
}
pub fn secondary_button_enabled(ui: &mut egui::Ui, text: &str, enabled: bool) -> egui::Response {
gradient_button(ui, text, gradient_button(ui, text,
Color32::from_rgb(130, 140, 150), // top Color32::from_rgb(130, 140, 150), // top
Color32::from_rgb(100, 110, 120), // bottom Color32::from_rgb(100, 110, 120), // bottom
Color32::from_rgb(255, 255, 255), // text color32 Color32::from_rgb(255, 255, 255), // text color32
Color32::from_rgb(150, 160, 170), // hover top Color32::from_rgb(150, 160, 170), // hover top
Color32::from_rgb(120, 130, 140), // hover bottom Color32::from_rgb(120, 130, 140), // hover bottom
Color32::from_rgb(100, 110, 120) // border Color32::from_rgb(100, 110, 120), // border
) enabled)
} }
pub fn danger_button(ui: &mut egui::Ui, text: &str) -> egui::Response { pub fn danger_button(ui: &mut egui::Ui, text: &str) -> egui::Response {
danger_button_enabled(ui, text, true)
}
pub fn danger_button_enabled(ui: &mut egui::Ui, text: &str, enabled: bool) -> egui::Response {
gradient_button(ui, text, gradient_button(ui, text,
Color32::from_rgb(240, 83, 99), Color32::from_rgb(240, 83, 99),
Color32::from_rgb(200, 40, 60), Color32::from_rgb(200, 40, 60),
Color32::WHITE, Color32::WHITE,
Color32::from_rgb(255, 100, 120), Color32::from_rgb(255, 100, 120),
Color32::from_rgb(220, 60, 80), Color32::from_rgb(220, 60, 80),
Color32::from_rgb(200, 40, 60)) Color32::from_rgb(200, 40, 60),
enabled)
} }
#[allow(dead_code)] #[allow(dead_code)]
@@ -114,7 +126,8 @@ pub fn white_grd_btn(ui: &mut egui::Ui, text: &str) -> egui::Response {
Color32::from_rgb(102, 102, 102), Color32::from_rgb(102, 102, 102),
Color32::from_rgb(246, 246, 246), Color32::from_rgb(246, 246, 246),
Color32::from_rgb(255, 255, 255), Color32::from_rgb(255, 255, 255),
Color32::from_rgb(177, 177, 177)) Color32::from_rgb(177, 177, 177),
true)
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn btn_dark_blue(ui: &mut egui::Ui, text: &str) -> egui::Response { pub fn btn_dark_blue(ui: &mut egui::Ui, text: &str) -> egui::Response {
@@ -124,7 +137,8 @@ pub fn btn_dark_blue(ui: &mut egui::Ui, text: &str) -> egui::Response {
Color32::WHITE, Color32::WHITE,
Color32::from_rgb(70, 140, 207), Color32::from_rgb(70, 140, 207),
Color32::from_rgb(99, 184, 238), Color32::from_rgb(99, 184, 238),
Color32::from_rgb(56, 102, 163)) Color32::from_rgb(56, 102, 163),
true)
} }
#[allow(dead_code)] #[allow(dead_code)]
@@ -135,5 +149,6 @@ pub fn light_gray_btn(ui: &mut egui::Ui, text: &str) -> egui::Response {
Color32::from_rgb(102, 102, 102), // metin: #666666 Color32::from_rgb(102, 102, 102), // metin: #666666
Color32::from_rgb(233, 233, 233), // hover üst (ters) Color32::from_rgb(233, 233, 233), // hover üst (ters)
Color32::from_rgb(249, 249, 249), // hover alt (ters) Color32::from_rgb(249, 249, 249), // hover alt (ters)
Color32::from_rgb(227, 195, 227)) // border: #e3c7e3 Color32::from_rgb(227, 195, 227), // border: #e3c7e3
true)
} }