first commit

This commit is contained in:
aOK 2025-02-03 09:30:39 +03:00
commit e4e2eb5cc0
9 changed files with 1427 additions and 0 deletions

38
src/app.rs Normal file
View file

@ -0,0 +1,38 @@
use makepad_widgets::*;
live_design!(
use link::theme::*;
use link::shaders::*;
use link::widgets::*;
use crate::ui::*;
App = {{App}} {
ui:<Root>{
<Window>{
body = <Ui> {}
}
}
}
);
#[derive(Live, LiveHook)]
struct App {
#[live]
ui: WidgetRef,
}
impl AppMain for App {
fn handle_event(&mut self, cx: &mut Cx, event: &Event) {
self.ui.handle_event(cx, event, &mut Scope::empty());
}
}
impl LiveRegister for App {
fn live_register(cx: &mut Cx) {
makepad_widgets::live_design(cx);
crate::ui::live_design(cx);
crate::indicators::live_design(cx);
}
}
app_main!(App);

258
src/indicators.rs Normal file
View file

@ -0,0 +1,258 @@
use makepad_widgets::*;
use crate::ui::NextBackAction;
const SELECTED: bool = false;
live_design! {
use link::theme::*;
use link::shaders::*;
use link::widgets::*;
IndicatorCheckBox = <CheckBox> {
width: Fill,
height: 35,
margin: {left: 1},
label_walk: {margin: {top: 15, bottom: 10}}
draw_check: {
uniform size: 3.5;
instance open: 0.0
uniform length: 3.0
uniform width: 1.0
fn pixel(self) -> vec4 {
let sdf = Sdf2d::viewport(self.pos * self.rect_size)
match self.check_type {
CheckType::Check => {
let sz = self.size;
let left = sz + 1.;
let up = sz + 7;
let c = self.rect_size * vec2(0.5, 0.5);
sdf.box(
left,
c.y - up,
25. * sz + 5,
1.8 * sz,
1.8
);
sdf.fill(#232323);
sdf.stroke(#000, 0.5 + 0.5 * self.dpi_dilate);
let isz = sz * 0.5;
let ileft = isz + 3;
let iup = sz + 7;
sdf.box(
ileft,
c.y - iup,
25. * sz + 5,
1.8 * sz,
1.8
);
sdf.fill(mix(#000, #016def, self.selected));
sdf.stroke(mix(
#000, #016def,
self.selected), 1.25
);
}
}
return sdf.result
}
}
draw_text: {text_style: <THEME_FONT_LABEL> {}}
}
pub Indicators = {{Indicators}} {
width: Fit,
height: Fit,
flow: Right,
spacing: 5,
indicator_titles: []
template: <IndicatorCheckBox> {
width: 100, height: 20,
margin: 0, padding: 0
align: {x: 0.5, y: 0.5},
text: "Here",
draw_text: {
fn get_color(self) -> vec4 {
return #f60;
}
}
draw_check: {
check_type: Check,
}
animator: {
selected = {
default: on
}
}
}
}
}
#[derive(Live, Widget)]
pub struct Indicators {
#[redraw]
#[rust]
area: Area,
#[walk]
walk: Walk,
#[layout]
layout: Layout,
#[live]
indicator_titles: Vec<String>,
#[live]
template: Option<LivePtr>,
#[rust]
items: ComponentMap<LiveId, WidgetRef>,
#[rust(0)]
page_no: u8,
}
impl LiveHook for Indicators {
fn after_new_from_doc(&mut self, cx: &mut Cx) {
// let tags = ["test1", "test2", "test3"];
// log!("Indicators: after_apply");
self.items.clear();
self.page_no = 0; // Assign initial page
if self.page_no < self.indicator_titles.len() as u8 {
for (i, title_text) in self.indicator_titles.iter().enumerate() {
let item_id = LiveId::from_str(&format!("items{}", i));
let item_widget = WidgetRef::new_from_ptr(cx, self.template);
item_widget.apply_over(cx, live! {text: (title_text)});
let indicator = item_widget.check_box(&[item_id]);
if usize::from(self.page_no) == i {
if indicator.selected(cx) != SELECTED {
indicator.set_selected(cx, SELECTED);
}
}
self.items.insert(item_id, item_widget);
}
}
}
}
impl WidgetMatchEvent for Indicators {
fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions, _scope: &mut Scope) {
// if (self.page_no as usize) < arr.len() {
// // Iterate over the selected page's choices
let mut arr: Vec<WidgetRef> = Vec::new();
for (_idx, inner_vec) in self.items.iter_mut() {
// Append the inner vector to the new variable
arr.push(inner_vec.clone());
}
if (self.page_no as usize) < arr.len() {
for (inneridx, indicator_arr) in arr.iter().enumerate() {
let index: u8 = inneridx as u8;
let widget_id = LiveId::from_str(&format!("items{}", index));
let item = self.items.get_or_insert(cx, widget_id, |cx| {
WidgetRef::new_from_ptr(cx, self.template)
});
let indicator = item.check_box(&[widget_id]);
// if usize::from(self.page_no) == inneridx {
if indicator.selected(cx) != SELECTED {
indicator.set_selected(cx, SELECTED);
}
// }
// item.check_box(&[widget_id]).set_selected(cx, SELECTED);
// let _ = item.draw_all(cx, scope);
}
}
// } else {
// log!("Invalid page_no: {}", self.page_no);
// }
for action in actions {
if let NextBackAction::NextButton { clicked, page_no } =
action.as_widget_action().cast()
{
if clicked {
self.increment_page_no(cx); // Increment the page number
}
}
if let NextBackAction::BackButton { clicked, page_no } =
action.as_widget_action().cast()
{
if clicked {
self.decrement_page_no(cx); // Increment the page number
}
}
}
}
}
impl Widget for Indicators {
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
for (_id, item) in self.items.iter_mut() {
item.handle_event(cx, event, scope);
}
self.widget_match_event(cx, event, scope);
}
fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
// let state = scope.data.get_mut::<State>().unwrap();
// state.select_choices_values.len();
self.draw_walkd(cx, scope, walk);
DrawStep::done()
}
}
impl Indicators {
fn draw_walkd(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) {
cx.begin_turtle(walk, Layout::default());
let mut arr: Vec<WidgetRef> = Vec::new();
for (_idx, inner_vec) in self.items.iter_mut() {
// Append the inner vector to the new variable
arr.push(inner_vec.clone());
}
if (self.page_no as usize) < arr.len() {
for (inneridx, indicator_arr) in arr.iter().enumerate() {
let index: u8 = inneridx as u8;
let widget_id = LiveId::from_str(&format!("items{}", index));
let item = self.items.get_or_insert(cx, widget_id, |cx| {
WidgetRef::new_from_ptr(cx, self.template)
});
let indicator = item.check_box(&[widget_id]);
// if usize::from(self.page_no) == inneridx {
if indicator.selected(cx) != SELECTED {
indicator.set_selected(cx, SELECTED);
}
// }
let _ = item.draw_all(cx, scope);
}
}
cx.end_turtle_with_area(&mut self.area);
// cx.end_turtle_with_area(&mut self.custom_button.area());
}
pub fn increment_page_no(&mut self, cx: &mut Cx) {
self.page_no = (self.page_no + 1).min(2); // Ensure page_no doesn't exceed max value
log!("SelectOption - Navigated to page: {}", self.page_no);
self.update_view(cx);
}
pub fn decrement_page_no(&mut self, cx: &mut Cx) {
if self.page_no > 0 {
self.page_no -= 1;
log!("SelectOption - Navigated to page: {}", self.page_no);
self.update_view(cx);
}
}
fn update_view(&mut self, cx: &mut Cx) {
match self.page_no {
0 => log!("SelectOption - Showing Step One"),
1 => log!("SelectOption - Showing Step Two"),
2 => log!("SelectOption - Showing Step Three"),
_ => log!("SelectOption - Unknown Page"),
}
}
}

3
src/lib.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod app;
mod indicators;
mod ui;

3
src/main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
gropu::app::app_main()
}

151
src/ui.rs Normal file
View file

@ -0,0 +1,151 @@
use makepad_widgets::*;
const SELECTED: bool = false;
live_design!(
use link::theme::*;
use link::shaders::*;
use link::widgets::*;
use crate::indicators::Indicators;
pub Ui = {{Ui}} {
<View>{
align: {x: 0.5, y: 0.5}
width: Fit,
height: Fit,
flow: Down
padding: 100
indicators = <View>{
height: Fit,
width: Fit,
margin: {bottom: 20.0}
ind = <Indicators>{
indicator_titles: [
"Step One",
"Step Two",
"Step Three"
]
}
}
back = <View> {
// debug: A
align: {x: 1, y: 0.}
width: Fit, height: Fit,
back_left_button = <Button> {
width: Fit, height: Fit,
icon_walk: {width: 10, height: Fit}
text: "Back"
draw_text: {
fn get_color(self) -> vec4 {
return #016def
return mix(mix(#000, #000, self.hover), #000, self.pressed)
}
}
draw_bg: {
fn pixel(self) -> vec4 {
let sdf = Sdf2d::viewport(self.pos * self.rect_size);
return sdf.result
}
}
draw_icon: {
svg_file: dep("crate://self/resources/back.svg"),
color: #016def;
brightness: 0.8;
}
}
}
next_button = <View> {
// debug: A
height: Fit
align: {x: 0.5, y: 0.5}
next = <Button> {
width: 300, height: 50,
text: "Next"
draw_text: {
fn get_color(self) -> vec4 {
return mix(mix(#f0, #016def, self.hover), #f0, self.pressed)
}
}
}
}
}
}
);
#[derive(Live, Widget)]
pub struct Ui {
#[deref]
deref: View,
#[rust(0)]
page_no: u8,
}
#[derive(Clone, DefaultNone, Debug)]
pub enum NextBackAction {
/// The user clicked the "react" button on a message
/// and wants to send the given `reaction` to that message.
NextButton {
clicked: bool,
page_no: u8,
},
BackButton {
clicked: bool,
page_no: u8,
},
SetIndicator {
set: bool,
page_no: u8,
},
None,
}
impl LiveHook for Ui {
fn after_new_from_doc(&mut self, cx: &mut Cx) {}
}
impl WidgetMatchEvent for Ui {
fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions, scope: &mut Scope) {
if self.deref.button(id!(next)).clicked(&actions) {
// log!("Hero - Next Button Clicked");
let widget_uid = self.deref.widget_uid();
// Navigate to the main content view
cx.widget_action(
widget_uid,
&scope.path,
NextBackAction::NextButton {
clicked: true,
page_no: 0, // You can pass the current page number if needed
},
);
// log!("Hero - Action dispatched: {:?}", widget_uid);
self.redraw(cx);
}
if self.deref.button(id!(back_left_button)).clicked(&actions) {
let widget_uid = self.deref.widget_uid();
// Navigate to the main content view
cx.widget_action(
widget_uid,
&scope.path,
NextBackAction::BackButton {
clicked: true,
page_no: 0, // You can pass the current page number if needed
},
);
// log!("Hero - Action dispatched: {:?}", widget_uid);
self.redraw(cx);
}
}
}
impl Widget for Ui {
fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
self.deref.draw_walk_all(cx, scope, walk);
DrawStep::done()
}
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
self.deref.handle_event(cx, event, scope);
}
}