app: make cancel and done edit buttons call menu methods

This commit is contained in:
darkfi
2026-02-16 22:28:50 +01:00
parent 829bc9ed60
commit eecda86d09
3 changed files with 133 additions and 68 deletions

View File

@@ -711,5 +711,9 @@ pub fn create_menu(name: &str) -> SceneNode {
node.add_method("mark_alert", vec![("item_name", "Item name", CallArgType::Str)], None)
.unwrap();
node.add_method("cancel_edit", vec![], None).unwrap();
node.add_method("done_edit", vec![], None).unwrap();
node
}

View File

@@ -192,6 +192,72 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) {
let version_block_is_visible = PropertyBool::wrap(&node, Role::App, "is_visible", 0).unwrap();
layer_node.link(node);
// Make buttons for cancel and done
let node = create_layer("editbtn_layer");
let prop = node.get_property("rect").unwrap();
prop.set_f32(atom, Role::App, 0, 50.).unwrap();
let code = cc.compile("h - 100 - 50").unwrap();
prop.set_expr(atom, Role::App, 1, code).unwrap();
let code = cc.compile("w - 100").unwrap();
prop.set_expr(atom, Role::App, 2, code).unwrap();
prop.set_f32(atom, Role::App, 3, 100.).unwrap();
node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
node.set_property_u32(atom, Role::App, "priority", 1).unwrap();
let editlayer_node = node.setup(|me| Layer::new(me, app.renderer.clone())).await;
layer_node.link(editlayer_node.clone());
let editlayer_is_visible =
PropertyBool::wrap(&editlayer_node, Role::App, "is_visible", 0).unwrap();
let node = create_vector_art("btns_bg");
let prop = node.get_property("rect").unwrap();
prop.set_f32(atom, Role::App, 0, 0.).unwrap();
prop.set_f32(atom, Role::App, 1, 0.).unwrap();
prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
let mut shape = VectorShape::new();
shape.add_gradient_box(
expr::const_f32(0.),
expr::const_f32(0.),
expr::const_f32(200.),
expr::load_var("h"),
[[0., 0., 0., 1.], [0., 0., 0., 1.], [0.1, 0., 0., 1.], [0.1, 0., 0., 1.]],
);
shape.add_outline(
expr::const_f32(0.),
expr::const_f32(0.),
expr::const_f32(200.),
expr::load_var("h"),
1.,
[1., 0., 0., 1.],
);
shape.add_gradient_box(
cc.compile("w - 200").unwrap(),
expr::const_f32(0.),
expr::load_var("w"),
expr::load_var("h"),
[[0., 0.1, 0.15, 1.], [0., 0.1, 0.15, 1.], [0., 0., 0., 1.], [0., 0., 0., 1.]],
);
shape.add_outline(
cc.compile("w - 200").unwrap(),
expr::const_f32(0.),
expr::load_var("w"),
expr::load_var("h"),
1.,
[0., 0.94, 1., 1.],
);
let node = node.setup(|me| VectorArt::new(me, shape, app.renderer.clone())).await;
editlayer_node.link(node);
// Menu
let node = create_menu("main_menu");
let prop = node.get_property("rect").unwrap();
prop.set_f32(atom, Role::App, 0, 0.).unwrap();
@@ -200,6 +266,7 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) {
let code = cc.compile("h - CHANNEL_LABEL_LINESPACE").unwrap();
prop.set_expr(atom, Role::App, 3, code).unwrap();
node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
node.set_property_u32(atom, Role::App, "priority", 0).unwrap();
node.set_property_f32(atom, Role::App, "padding", CHANNEL_LABEL_LINESPACE).unwrap();
let prop = node.get_property("bg_color").unwrap();
@@ -273,9 +340,6 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) {
});
app.tasks.lock().unwrap().push(listen_click);
// Debug thing
version_block_is_visible.set(atom, false);
// Subscribe to edit_active signal to hide version block
let (edit_slot, edit_recvr) = Slot::new("edit_activated");
node.register("edit_active", edit_slot).unwrap();
@@ -285,72 +349,14 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) {
debug!(target: "app::menu", "menu edit active");
let atom = &mut renderer.make_guard(gfxtag!("edit_active"));
version_block_is_visible.set(atom, false);
editlayer_is_visible.set(atom, true);
}
});
app.tasks.lock().unwrap().push(edit_listen);
let node = node.setup(|me| Menu::new(me, window_scale.clone(), app.renderer.clone())).await;
layer_node.link(node);
// Make buttons for cancel and done
let editlayer_node = create_layer("editbtn_layer");
let prop = editlayer_node.get_property("rect").unwrap();
prop.set_f32(atom, Role::App, 0, 50.).unwrap();
let code = cc.compile("h - 100 - 50").unwrap();
prop.set_expr(atom, Role::App, 1, code).unwrap();
let code = cc.compile("w - 100").unwrap();
prop.set_expr(atom, Role::App, 2, code).unwrap();
prop.set_f32(atom, Role::App, 3, 100.).unwrap();
editlayer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
editlayer_node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
let editlayer_node = editlayer_node.setup(|me| Layer::new(me, app.renderer.clone())).await;
layer_node.link(editlayer_node.clone());
let node = create_vector_art("btns_bg");
let prop = node.get_property("rect").unwrap();
prop.set_f32(atom, Role::App, 0, 0.).unwrap();
prop.set_f32(atom, Role::App, 1, 0.).unwrap();
prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
let mut shape = VectorShape::new();
shape.add_gradient_box(
expr::const_f32(0.),
expr::const_f32(0.),
expr::const_f32(200.),
expr::load_var("h"),
[[0., 0., 0., 1.], [0., 0., 0., 1.], [0.1, 0., 0., 1.], [0.1, 0., 0., 1.]],
);
shape.add_outline(
expr::const_f32(0.),
expr::const_f32(0.),
expr::const_f32(200.),
expr::load_var("h"),
1.,
[1., 0., 0., 1.],
);
shape.add_gradient_box(
cc.compile("w - 200").unwrap(),
expr::const_f32(0.),
expr::load_var("w"),
expr::load_var("h"),
[[0., 0.1, 0.15, 1.], [0., 0.1, 0.15, 1.], [0., 0., 0., 1.], [0., 0., 0., 1.]],
);
shape.add_outline(
cc.compile("w - 200").unwrap(),
expr::const_f32(0.),
expr::load_var("w"),
expr::load_var("h"),
1.,
[0., 0.94, 1., 1.],
);
let node = node.setup(|me| VectorArt::new(me, shape, app.renderer.clone())).await;
editlayer_node.link(node);
let menu_node =
node.setup(|me| Menu::new(me, window_scale.clone(), app.renderer.clone())).await;
layer_node.link(menu_node.clone());
// Create the cancel button
let node = create_button("cancel_btn");
@@ -363,9 +369,10 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) {
let (slot, recvr) = Slot::new("cancel_clicked");
node.register("click", slot).unwrap();
let menu_node2 = menu_node.clone();
let listen_click = app.ex.spawn(async move {
while let Ok(_) = recvr.recv().await {
info!("cancel");
menu_node2.call_method("cancel_edit", vec![]).await.unwrap();
}
});
app.tasks.lock().unwrap().push(listen_click);
@@ -385,9 +392,10 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) {
let (slot, recvr) = Slot::new("done_clicked");
node.register("click", slot).unwrap();
let menu_node2 = menu_node.clone();
let listen_click = app.ex.spawn(async move {
while let Ok(_) = recvr.recv().await {
info!("done");
menu_node2.call_method("done_edit", vec![]).await.unwrap();
}
});
app.tasks.lock().unwrap().push(listen_click);

View File

@@ -612,6 +612,48 @@ impl Menu {
true
}
/// Cancels edit mode changes, reverting any modifications made during edit mode
async fn process_cancel_method(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
let Ok(method_call) = sub.receive().await else {
d!("Event relayer closed");
return false
};
d!("method called: cancel({method_call:?})");
assert!(method_call.send_res.is_none());
let Some(self_) = me.upgrade() else {
d!("Self destroyed");
return true
};
// TODO: Implement cancel logic - revert edit mode changes
d!("cancel: stub - will revert edit mode changes");
true
}
/// Accepts edit mode changes, finalizing any modifications made during edit mode
async fn process_done_method(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
let Ok(method_call) = sub.receive().await else {
d!("Event relayer closed");
return false
};
d!("method called: done({method_call:?})");
assert!(method_call.send_res.is_none());
let Some(self_) = me.upgrade() else {
d!("Self destroyed");
return true
};
// TODO: Implement done logic - accept edit mode changes
d!("done: stub - will accept edit mode changes");
true
}
}
#[async_trait]
@@ -653,6 +695,16 @@ impl UIObject for Menu {
async move { while Self::process_mark_alert_method(&me2, &method_sub).await {} },
);
let method_sub = node_ref.subscribe_method_call("cancel_edit").unwrap();
let me2 = me.clone();
let cancel_task =
ex.spawn(async move { while Self::process_cancel_method(&me2, &method_sub).await {} });
let method_sub = node_ref.subscribe_method_call("done_edit").unwrap();
let me2 = me.clone();
let done_task =
ex.spawn(async move { while Self::process_done_method(&me2, &method_sub).await {} });
let mut on_modify = OnModify::new(ex, self.node.clone(), me.clone());
async fn redraw(self_: Arc<Menu>, batch: BatchGuardPtr) {
@@ -669,7 +721,8 @@ impl UIObject for Menu {
on_modify.when_change(self.sep_size.prop(), redraw);
on_modify.when_change(self.sep_color.prop(), redraw);
let mut tasks = vec![motion_task, mark_active_task, mark_alert_task];
let mut tasks =
vec![motion_task, mark_active_task, mark_alert_task, cancel_task, done_task];
tasks.append(&mut on_modify.tasks);
*self.tasks.lock() = tasks;
}