From 3246f397b57d636893776cd71b2b1aa9ed1508aa Mon Sep 17 00:00:00 2001 From: iris <2+iris@noreply.localhost> Date: Fri, 11 Sep 2026 02:18:34 -0400 Subject: [PATCH] Return the tabs demo to one example --- Cargo.lock | 8 - Cargo.toml | 2 - {tabs-ui => examples/tabs}/assets/sungals.png | Bin examples/tabs/main.rs | 210 +++++++++++++++++- tabs-ui/Cargo.toml | 9 - tabs-ui/src/lib.rs | 207 ----------------- 6 files changed, 208 insertions(+), 228 deletions(-) rename {tabs-ui => examples/tabs}/assets/sungals.png (100%) delete mode 100644 tabs-ui/Cargo.toml delete mode 100644 tabs-ui/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 9a47f77..f22b561 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1550,7 +1550,6 @@ dependencies = [ "pollster", "send_wrapper", "swash", - "tabs-ui", "tokio", "wgpu", "winit", @@ -3316,13 +3315,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "tabs-ui" -version = "0.1.0" -dependencies = [ - "iris", -] - [[package]] name = "tempfile" version = "3.25.0" diff --git a/Cargo.toml b/Cargo.toml index 763ac68..6c63e9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,6 @@ force-gles = [] [dev-dependencies] tokio = { workspace = true, features = ["sync", "rt", "rt-multi-thread", "time"] } -tabs-ui = { path = "tabs-ui" } bytemuck = { workspace = true } [[bench]] @@ -47,7 +46,6 @@ harness = false members = [ "core", "macro", - "tabs-ui", "rig-input", ] diff --git a/tabs-ui/assets/sungals.png b/examples/tabs/assets/sungals.png similarity index 100% rename from tabs-ui/assets/sungals.png rename to examples/tabs/assets/sungals.png diff --git a/examples/tabs/main.rs b/examples/tabs/main.rs index 151168c..13ce661 100644 --- a/examples/tabs/main.rs +++ b/examples/tabs/main.rs @@ -1,4 +1,5 @@ use iris::prelude::*; +use std::{cell::RefCell, rc::Rc}; use winit::event::WindowEvent; fn main() { @@ -6,14 +7,14 @@ fn main() { } #[derive(DesktopUiState)] -pub struct Client { +struct Client { ui_state: DesktopUiState, info: WeakWidget, } impl DesktopAppState for Client { fn new(mut ui_state: DesktopUiState, rsc: &mut StdRsc, _: Proxy) -> Self { - let widgets = tabs_ui::build(rsc, &mut ui_state); + let widgets = build(rsc, &mut ui_state); Self { ui_state, info: widgets.info, @@ -33,3 +34,208 @@ impl DesktopAppState for Client { } } } + +struct ClientWidgets { + info: WeakWidget, +} + +fn build(rsc: &mut Rsc, ui_state: &mut impl HasRoot) -> ClientWidgets +where + Rsc::State: FocusHost, +{ + let rrect = rect(PaintId::WHITE).radius(20); + let pad_test = ( + rrect.clone().color(PaintId::BLUE), + ( + rrect + .clone() + .color(PaintId::RED) + .sized((100, 100)) + .center() + .width(rest(2)), + ( + rrect.clone().color(PaintId::ORANGE), + rrect.clone().color(PaintId::LIME).pad(10.0), + ) + .span(Dir::RIGHT) + .width(rest(2)), + rrect.clone().color(PaintId::YELLOW), + ) + .span(Dir::RIGHT) + .pad(10) + .width(rest(3)), + ) + .span(Dir::RIGHT) + .add(rsc); + + let span_test = ( + rrect.clone().color(PaintId::GREEN).width(100), + rrect.clone().color(PaintId::ORANGE), + rrect.clone().color(PaintId::CYAN), + rrect.clone().color(PaintId::BLUE).width(rel(0.5)), + rrect.clone().color(PaintId::MAGENTA).width(100), + rrect.color(PaintId::RED).width(100), + ) + .span(Dir::LEFT) + .add(rsc); + + let span_add = Span::empty(Dir::RIGHT).add(rsc); + + let add_button = rect(PaintId::LIME) + .radius(30) + .on(CursorSense::click(), move |_, rsc| { + let child = image(include_bytes!("assets/sungals.png")) + .center() + .add_strong(rsc); + span_add(rsc).push(child); + }) + .sized((150, 150)) + .align(Align::BOT_RIGHT); + + let del_button = rect(PaintId::RED) + .radius(30) + .on(CursorSense::click(), move |_, rsc| { + span_add(rsc).pop(); + }) + .sized((150, 150)) + .align(Align::BOT_LEFT); + + let span_add_test = (span_add, add_button, del_button).stack().add(rsc); + + let btext = |content| wtext(content).size(30); + + let text_test = ( + btext("this is a").align(Align::LEFT), + btext("teeeeeeeest").align(Align::RIGHT), + btext("okkk\nokkkkkk!").align(Align::LEFT), + btext("hmm"), + btext("a"), + ( + btext("'").family(Family::Monospace).align(Align::TOP), + btext("'").family(Family::Monospace), + btext(":gamer mode").family(Family::Monospace), + rect(PaintId::CYAN).sized((10, 10)).center(), + rect(PaintId::RED).sized((100, 100)).center(), + rect(PaintId::PURPLE).sized((50, 50)).align(Align::TOP), + ) + .span(Dir::RIGHT) + .center(), + wtext("pretty cool right?").size(50), + ) + .span(Dir::DOWN) + .add(rsc); + + let texts = Span::empty(Dir::DOWN).gap(10).add(rsc); + let msg_area = texts + .scrollable(Axis::Y, Pin::Start) + .masked() + .background(rect(PaintId::SKY)); + let add_text = wtext("add") + .editable(EditMode::MultiLine) + .text_align(Align::LEFT) + .size(30) + .attr::(()) + .on(Submit, move |ctx, rsc: &mut Rsc| { + let w = ctx.widget; + let content = w.edit(rsc).take(); + let text = wtext(content) + .editable(EditMode::MultiLine) + .size(30) + .text_align(Align::LEFT) + .wrap(true) + .attr::(()); + let fill = rsc + .ui_mut() + .paints + .add(Srgba8::WHITE.to_linear().darker(0.5)); + let msg_box = text.background(rect(fill)).add_strong(rsc); + texts(rsc).push(msg_box); + }) + .add(rsc); + + let text_edit_scroll = ( + msg_area.height(rest(1)), + ( + Rect::new( + rsc.ui_mut() + .paints + .add(Srgba8::WHITE.to_linear().darker(0.9)), + ), + ( + add_text.width(rest(1)), + Rect::new(PaintId::GREEN) + .on(CursorSense::click(), move |ctx, rsc: &mut Rsc| { + rsc.run_event::(add_text, (), ctx.state); + }) + .sized((40, 40)), + ) + .span(Dir::RIGHT) + .pad(10), + ) + .stack() + .size(StackSize::Child(1)) + .layer_offset(1) + .align(Align::BOT), + ) + .span(Dir::DOWN) + .add(rsc); + + let main = WidgetPtr::new().add(rsc); + + let vals = Rc::new(RefCell::new((0, Vec::new()))); + let mut switch_button = |solid: Srgba8, to: WeakWidget, label| { + let value = solid.to_linear(); + let paint = rsc.ui_mut().paints.add(value); + let to = to.upgrade(rsc); + let vec = &mut vals.borrow_mut().1; + let i = vec.len(); + if vec.is_empty() { + vec.push(None); + main(rsc).set(to); + } else { + vec.push(Some(to)); + } + let vals = vals.clone(); + let pressed = paint.clone(); + let hovered = paint.clone(); + let normal = paint.clone(); + let rect = rect(paint) + .on(CursorSense::click(), move |_ctx, rsc: &mut Rsc| { + let (prev, vec) = &mut *vals.borrow_mut(); + if let Some(h) = vec[i].take() { + vec[*prev] = main(rsc).replace(h); + *prev = i; + } + rsc.ui_mut().paints.set(&pressed, value.darker(0.3)); + }) + .on( + CursorSense::HoverStart | CursorSense::unclick(), + move |_ctx, rsc: &mut Rsc| { + rsc.ui_mut().paints.set(&hovered, value.brighter(0.2)); + }, + ) + .on(CursorSense::HoverEnd, move |_ctx, rsc: &mut Rsc| { + rsc.ui_mut().paints.set(&normal, value); + }) + .label(label); + (rect, wtext(label).size(30).text_align(Align::CENTER)).stack() + }; + + let tabs = ( + switch_button(Srgba8::RED, pad_test, "pad"), + switch_button(Srgba8::GREEN, span_test, "span"), + switch_button(Srgba8::BLUE, span_add_test, "image span"), + switch_button(Srgba8::MAGENTA, text_test, "text layout"), + switch_button(Srgba8::YELLOW, text_edit_scroll, "text edit scroll"), + ) + .span(Dir::RIGHT); + + let info = wtext("").add(rsc); + let info_sect = info.pad(10).align(Align::RIGHT); + + ((tabs.height(40), main.pad(10)).span(Dir::DOWN), info_sect) + .stack() + .set_root(rsc, ui_state); + + ClientWidgets { info } +} diff --git a/tabs-ui/Cargo.toml b/tabs-ui/Cargo.toml deleted file mode 100644 index a032c7b..0000000 --- a/tabs-ui/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "tabs-ui" -version.workspace = true -edition.workspace = true - -# Shared demo content for the desktop and Android example entry points. - -[dependencies] -iris = { path = ".." } diff --git a/tabs-ui/src/lib.rs b/tabs-ui/src/lib.rs deleted file mode 100644 index 0e92873..0000000 --- a/tabs-ui/src/lib.rs +++ /dev/null @@ -1,207 +0,0 @@ -use iris::prelude::*; -use std::{cell::RefCell, rc::Rc}; - -pub struct ClientWidgets { - pub info: WeakWidget, -} - -pub fn build(rsc: &mut Rsc, ui_state: &mut impl HasRoot) -> ClientWidgets -where - Rsc::State: FocusHost, -{ - let rrect = rect(PaintId::WHITE).radius(20); - let pad_test = ( - rrect.clone().color(PaintId::BLUE), - ( - rrect - .clone() - .color(PaintId::RED) - .sized((100, 100)) - .center() - .width(rest(2)), - ( - rrect.clone().color(PaintId::ORANGE), - rrect.clone().color(PaintId::LIME).pad(10.0), - ) - .span(Dir::RIGHT) - .width(rest(2)), - rrect.clone().color(PaintId::YELLOW), - ) - .span(Dir::RIGHT) - .pad(10) - .width(rest(3)), - ) - .span(Dir::RIGHT) - .add(rsc); - - let span_test = ( - rrect.clone().color(PaintId::GREEN).width(100), - rrect.clone().color(PaintId::ORANGE), - rrect.clone().color(PaintId::CYAN), - rrect.clone().color(PaintId::BLUE).width(rel(0.5)), - rrect.clone().color(PaintId::MAGENTA).width(100), - rrect.color(PaintId::RED).width(100), - ) - .span(Dir::LEFT) - .add(rsc); - - let span_add = Span::empty(Dir::RIGHT).add(rsc); - - let add_button = rect(PaintId::LIME) - .radius(30) - .on(CursorSense::click(), move |_, rsc| { - let child = image(include_bytes!("../assets/sungals.png")) - .center() - .add_strong(rsc); - span_add(rsc).push(child); - }) - .sized((150, 150)) - .align(Align::BOT_RIGHT); - - let del_button = rect(PaintId::RED) - .radius(30) - .on(CursorSense::click(), move |_, rsc| { - span_add(rsc).pop(); - }) - .sized((150, 150)) - .align(Align::BOT_LEFT); - - let span_add_test = (span_add, add_button, del_button).stack().add(rsc); - - let btext = |content| wtext(content).size(30); - - let text_test = ( - btext("this is a").align(Align::LEFT), - btext("teeeeeeeest").align(Align::RIGHT), - btext("okkk\nokkkkkk!").align(Align::LEFT), - btext("hmm"), - btext("a"), - ( - btext("'").family(Family::Monospace).align(Align::TOP), - btext("'").family(Family::Monospace), - btext(":gamer mode").family(Family::Monospace), - rect(PaintId::CYAN).sized((10, 10)).center(), - rect(PaintId::RED).sized((100, 100)).center(), - rect(PaintId::PURPLE).sized((50, 50)).align(Align::TOP), - ) - .span(Dir::RIGHT) - .center(), - wtext("pretty cool right?").size(50), - ) - .span(Dir::DOWN) - .add(rsc); - - let texts = Span::empty(Dir::DOWN).gap(10).add(rsc); - let msg_area = texts - .scrollable(Axis::Y, Pin::Start) - .masked() - .background(rect(PaintId::SKY)); - let add_text = wtext("add") - .editable(EditMode::MultiLine) - .text_align(Align::LEFT) - .size(30) - .attr::(()) - .on(Submit, move |ctx, rsc: &mut Rsc| { - let w = ctx.widget; - let content = w.edit(rsc).take(); - let text = wtext(content) - .editable(EditMode::MultiLine) - .size(30) - .text_align(Align::LEFT) - .wrap(true) - .attr::(()); - let fill = rsc - .ui_mut() - .paints - .add(Srgba8::WHITE.to_linear().darker(0.5)); - let msg_box = text.background(rect(fill)).add_strong(rsc); - texts(rsc).push(msg_box); - }) - .add(rsc); - - let text_edit_scroll = ( - msg_area.height(rest(1)), - ( - Rect::new( - rsc.ui_mut() - .paints - .add(Srgba8::WHITE.to_linear().darker(0.9)), - ), - ( - add_text.width(rest(1)), - Rect::new(PaintId::GREEN) - .on(CursorSense::click(), move |ctx, rsc: &mut Rsc| { - rsc.run_event::(add_text, (), ctx.state); - }) - .sized((40, 40)), - ) - .span(Dir::RIGHT) - .pad(10), - ) - .stack() - .size(StackSize::Child(1)) - .layer_offset(1) - .align(Align::BOT), - ) - .span(Dir::DOWN) - .add(rsc); - - let main = WidgetPtr::new().add(rsc); - - let vals = Rc::new(RefCell::new((0, Vec::new()))); - let mut switch_button = |solid: Srgba8, to: WeakWidget, label| { - let value = solid.to_linear(); - let paint = rsc.ui_mut().paints.add(value); - let to = to.upgrade(rsc); - let vec = &mut vals.borrow_mut().1; - let i = vec.len(); - if vec.is_empty() { - vec.push(None); - main(rsc).set(to); - } else { - vec.push(Some(to)); - } - let vals = vals.clone(); - let pressed = paint.clone(); - let hovered = paint.clone(); - let normal = paint.clone(); - let rect = rect(paint) - .on(CursorSense::click(), move |_ctx, rsc: &mut Rsc| { - let (prev, vec) = &mut *vals.borrow_mut(); - if let Some(h) = vec[i].take() { - vec[*prev] = main(rsc).replace(h); - *prev = i; - } - rsc.ui_mut().paints.set(&pressed, value.darker(0.3)); - }) - .on( - CursorSense::HoverStart | CursorSense::unclick(), - move |_ctx, rsc: &mut Rsc| { - rsc.ui_mut().paints.set(&hovered, value.brighter(0.2)); - }, - ) - .on(CursorSense::HoverEnd, move |_ctx, rsc: &mut Rsc| { - rsc.ui_mut().paints.set(&normal, value); - }) - .label(label); - (rect, wtext(label).size(30).text_align(Align::CENTER)).stack() - }; - - let tabs = ( - switch_button(Srgba8::RED, pad_test, "pad"), - switch_button(Srgba8::GREEN, span_test, "span"), - switch_button(Srgba8::BLUE, span_add_test, "image span"), - switch_button(Srgba8::MAGENTA, text_test, "text layout"), - switch_button(Srgba8::YELLOW, text_edit_scroll, "text edit scroll"), - ) - .span(Dir::RIGHT); - - let info = wtext("").add(rsc); - let info_sect = info.pad(10).align(Align::RIGHT); - - ((tabs.height(40), main.pad(10)).span(Dir::DOWN), info_sect) - .stack() - .set_root(rsc, ui_state); - - ClientWidgets { info } -}