sync
This commit is contained in:
parent
e022e2b8a8
commit
8cbcc869d3
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1715,6 +1715,7 @@ dependencies = [
|
||||
"element_bridge",
|
||||
"futures",
|
||||
"glam",
|
||||
"indexmap",
|
||||
"log",
|
||||
"makepad-widgets",
|
||||
"mp_core",
|
||||
|
||||
@ -20,3 +20,4 @@ element_bridge = { path = "../element_bridge", version = "*" }
|
||||
futures = "0.3.31"
|
||||
async-trait = "0.1.83"
|
||||
thiserror = "2.0.3"
|
||||
indexmap = "2.6.0"
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
use crate::file::*;
|
||||
use crate::menu::{handle_menu, spawn_background};
|
||||
use crate::widgets::area::TAreaWidgetRefExt;
|
||||
use crate::widgets::selector::{
|
||||
ItemKey, ItemValue, SelectorListWidgetRefExt, SelectorWidgetRefExt,
|
||||
};
|
||||
|
||||
use crate::windows_manager::WM;
|
||||
use crate::{render_task::RenderTasks, PLUGIN_MANAGER, RUNTIME};
|
||||
use ::log::info;
|
||||
@ -16,7 +20,6 @@ live_design! {
|
||||
import makepad_widgets::base::*;
|
||||
import makepad_widgets::theme_desktop_dark::*;
|
||||
import crate::app_ui::MainView;
|
||||
import crate::widgets::selector_modal::SelectorModal;
|
||||
|
||||
HELLO = "Hello, World!";
|
||||
|
||||
@ -87,8 +90,6 @@ live_design! {
|
||||
}
|
||||
}
|
||||
|
||||
selector = <SelectorModal>{}
|
||||
|
||||
<MainView>{}
|
||||
}
|
||||
window_menu = {
|
||||
@ -177,8 +178,8 @@ impl LiveRegister for App {
|
||||
crate::app_ui::live_design(_cx);
|
||||
crate::widgets::area::live_design(_cx);
|
||||
crate::widgets::renderer::live_design(_cx);
|
||||
crate::widgets::selector_modal::live_design(_cx);
|
||||
crate::widgets::background_text::live_design(_cx);
|
||||
crate::widgets::selector::live_design(_cx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,6 +201,71 @@ impl MatchEvent for App {
|
||||
let render_task = render_tasks.lock().await;
|
||||
render_task.render().await;
|
||||
});
|
||||
|
||||
let items = vec![
|
||||
(
|
||||
ItemKey {
|
||||
path: "path".to_string(),
|
||||
category: "category".to_string(),
|
||||
description: "description_1".to_string(),
|
||||
},
|
||||
vec![
|
||||
ItemValue {
|
||||
name: "Item 1".to_string(),
|
||||
},
|
||||
ItemValue {
|
||||
name: "Item 2".to_string(),
|
||||
},
|
||||
],
|
||||
),
|
||||
(
|
||||
ItemKey {
|
||||
path: "path".to_string(),
|
||||
category: "category".to_string(),
|
||||
description: "description_1".to_string(),
|
||||
},
|
||||
vec![
|
||||
ItemValue {
|
||||
name: "Item 1".to_string(),
|
||||
},
|
||||
ItemValue {
|
||||
name: "Item 2".to_string(),
|
||||
},
|
||||
],
|
||||
),
|
||||
(
|
||||
ItemKey {
|
||||
path: "path".to_string(),
|
||||
category: "category".to_string(),
|
||||
description: "description_2".to_string(),
|
||||
},
|
||||
vec![
|
||||
ItemValue {
|
||||
name: "Item 1".to_string(),
|
||||
},
|
||||
ItemValue {
|
||||
name: "Item 2".to_string(),
|
||||
},
|
||||
],
|
||||
),
|
||||
(
|
||||
ItemKey {
|
||||
path: "path".to_string(),
|
||||
category: "category".to_string(),
|
||||
description: "description_1".to_string(),
|
||||
},
|
||||
vec![
|
||||
ItemValue {
|
||||
name: "Item 1".to_string(),
|
||||
},
|
||||
ItemValue {
|
||||
name: "Item 3".to_string(),
|
||||
},
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
ui.selector(id!(a)).set_items(cx, items);
|
||||
}
|
||||
|
||||
fn handle_signal(&mut self, cx: &mut Cx) {
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
use makepad_widgets::Dock;
|
||||
use makepad_widgets::*;
|
||||
live_design! {
|
||||
import makepad_widgets::base::*;
|
||||
@ -7,8 +6,9 @@ live_design! {
|
||||
import crate::widgets::renderer::IRenderer;
|
||||
|
||||
import makepad_draw::shader::std::*;
|
||||
import crate::widgets::selector_modal::SelectorItem;
|
||||
import crate::widgets::selector_modal::*;
|
||||
import crate::widgets::background_text::BackgroundLabel;
|
||||
import crate::widgets::selector::*;
|
||||
|
||||
HELLO = "Hello, World!";
|
||||
|
||||
@ -62,8 +62,16 @@ live_design! {
|
||||
x: 0.5,
|
||||
y: 0.5
|
||||
},
|
||||
quad = <Area> {
|
||||
id: "Primary"
|
||||
|
||||
<View> {
|
||||
width: 600
|
||||
height: 500
|
||||
align: {
|
||||
x: 0.5,
|
||||
y: 0.5
|
||||
}
|
||||
|
||||
a = <Selector> {}
|
||||
}
|
||||
|
||||
}
|
||||
@ -130,6 +138,7 @@ live_design! {
|
||||
|
||||
<H4>{ text: "Input"}
|
||||
|
||||
|
||||
<View>{
|
||||
flow: Right
|
||||
width: Fill
|
||||
@ -146,10 +155,9 @@ live_design! {
|
||||
<BackgroundLabel>{
|
||||
text: "Holy Shit",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
<Group> {
|
||||
|
||||
<ButtonGroup> {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pub mod area;
|
||||
pub mod background_text;
|
||||
pub mod renderer;
|
||||
pub mod selector_modal;
|
||||
pub mod selector;
|
||||
|
||||
550
mp/src/widgets/selector.rs
Normal file
550
mp/src/widgets/selector.rs
Normal file
@ -0,0 +1,550 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use makepad_widgets::*;
|
||||
|
||||
live_design! {
|
||||
import makepad_widgets::base::*;
|
||||
import makepad_widgets::theme_desktop_dark::*;
|
||||
import makepad_draw::shader::std::*;
|
||||
|
||||
ICO_SEARCH = dep("crate://self/resources/icons/Icon_Search.svg")
|
||||
|
||||
RView = <ViewBase> {
|
||||
show_bg: true,
|
||||
draw_bg: {
|
||||
instance border_width: 0.0
|
||||
instance border_color: #0000
|
||||
instance inset: vec4(0.0, 0.0, 0.0, 0.0)
|
||||
|
||||
fn get_color(self) -> vec4 {
|
||||
return self.color
|
||||
}
|
||||
|
||||
fn get_border_color(self) -> vec4 {
|
||||
return self.border_color
|
||||
}
|
||||
|
||||
fn pixel(self) -> vec4 {
|
||||
let sdf = Sdf2d::viewport(self.pos * self.rect_size);
|
||||
sdf.rect(
|
||||
self.inset.x + self.border_width,
|
||||
self.inset.y + self.border_width,
|
||||
self.rect_size.x - (self.inset.x + self.inset.z + self.border_width * 2.0),
|
||||
self.rect_size.y - (self.inset.y + self.inset.w + self.border_width * 2.0)
|
||||
)
|
||||
sdf.fill_keep(self.get_color())
|
||||
if self.border_width > 0.0 {
|
||||
sdf.stroke(self.get_border_color(), self.border_width)
|
||||
}
|
||||
return sdf.result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TitleBar = <RView>{
|
||||
height: 24
|
||||
width: Fill
|
||||
align: {
|
||||
y:0.5
|
||||
}
|
||||
|
||||
padding: {
|
||||
left:10
|
||||
}
|
||||
|
||||
draw_bg: {
|
||||
color: #3c3c3c
|
||||
border_color: #fff
|
||||
border_width: 0.5
|
||||
}
|
||||
|
||||
class_title = <Label> {
|
||||
|
||||
draw_text: {
|
||||
color: #fff
|
||||
text_style: <THEME_FONT_BOLD>{
|
||||
font_size: 8.0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SelectorItem = {{SelectorItem}}{
|
||||
flow: Down
|
||||
draw_title: {
|
||||
color: #fff
|
||||
text_style: <THEME_FONT_BOLD>{
|
||||
font_size: 8.0
|
||||
}
|
||||
}
|
||||
|
||||
draw_icon_bg: {
|
||||
|
||||
instance color: #3c3c3c
|
||||
instance radius: 3.0
|
||||
|
||||
fn get_color(self) -> vec4 {
|
||||
return self.color;
|
||||
}
|
||||
|
||||
fn pixel(self) -> vec4 {
|
||||
let sdf = Sdf2d::viewport(self.pos * self.rect_size)
|
||||
sdf.box(
|
||||
0.0,0.0,
|
||||
self.rect_size.x,
|
||||
self.rect_size.y,
|
||||
max(1.0, self.radius)
|
||||
)
|
||||
sdf.fill_keep(self.get_color())
|
||||
return sdf.result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
draw_title_bg: {
|
||||
instance color: #0078D7
|
||||
instance radius: 3.0
|
||||
|
||||
fn get_color(self) -> vec4 {
|
||||
return self.color;
|
||||
}
|
||||
|
||||
fn pixel(self) -> vec4 {
|
||||
let sdf = Sdf2d::viewport(self.pos * self.rect_size)
|
||||
sdf.box(
|
||||
0.0,0.0,
|
||||
self.rect_size.x,
|
||||
self.rect_size.y,
|
||||
max(1.0, self.radius)
|
||||
)
|
||||
sdf.fill_keep(self.get_color())
|
||||
return sdf.result;
|
||||
}
|
||||
}
|
||||
|
||||
draw_icon: {
|
||||
|
||||
svg_file: dep("crate://self/resources/logo_makepad.svg")
|
||||
|
||||
fn get_color(self) -> vec4 {
|
||||
return #0A60FE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SelectorList = {{SelectorList}} {
|
||||
width: 250
|
||||
height: Fit
|
||||
flow: RightWrap
|
||||
padding: {
|
||||
top: 15
|
||||
bottom: 15
|
||||
}
|
||||
align: {x:0.0, y:0.0}
|
||||
item_ref: <SelectorItem>{}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Selector = {{Selector}} {
|
||||
|
||||
<RoundedShadowView> {
|
||||
height: Fill
|
||||
width: Fill
|
||||
flow: Down
|
||||
padding: 15.0
|
||||
|
||||
align: {y:0.0}
|
||||
|
||||
draw_bg: {
|
||||
color: #3c3c3c
|
||||
shadow_radius: 30.0
|
||||
radius: 5.0
|
||||
}
|
||||
<H3> {
|
||||
text: "Selector"
|
||||
}
|
||||
|
||||
<View> {
|
||||
height: Fill
|
||||
width: Fill
|
||||
flow: Down
|
||||
|
||||
<RView> {
|
||||
height: Fill
|
||||
width: Fill
|
||||
flow: Down
|
||||
|
||||
draw_bg: {
|
||||
color: #3c3c3c
|
||||
border_color: #fff
|
||||
border_width: 0.5
|
||||
}
|
||||
|
||||
list = <PortalList> {
|
||||
|
||||
keep_invisible: true
|
||||
auto_tail: false
|
||||
width: Fill, height: Fill
|
||||
flow: Down,
|
||||
|
||||
title_bar = <TitleBar> {}
|
||||
list_item = <SelectorList> {}
|
||||
}
|
||||
}
|
||||
|
||||
<View> {
|
||||
width: Fill
|
||||
height:Fit
|
||||
|
||||
padding: {
|
||||
top: 30
|
||||
}
|
||||
|
||||
align: {
|
||||
x: 1.0
|
||||
}
|
||||
|
||||
<View> {
|
||||
|
||||
width: Fit
|
||||
height: Fit
|
||||
|
||||
flow: Right
|
||||
spacing:10.0
|
||||
|
||||
<Button> {
|
||||
text: "Previous"
|
||||
}
|
||||
|
||||
<Button> {
|
||||
text: "Next"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ItemKey {
|
||||
pub path: String,
|
||||
pub category: String,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ItemValue {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Live, LiveHook, Widget)]
|
||||
pub struct SelectorList {
|
||||
#[redraw]
|
||||
#[live]
|
||||
draw_bg: DrawColor,
|
||||
#[layout]
|
||||
layout: Layout,
|
||||
#[walk]
|
||||
walk: Walk,
|
||||
#[rust]
|
||||
// items: Vec<ItemValue>,
|
||||
items: IndexSet<ItemValue>,
|
||||
#[rust]
|
||||
item_refs: Vec<WidgetRef>,
|
||||
#[live]
|
||||
item_ref: Option<LivePtr>,
|
||||
|
||||
#[rust]
|
||||
selected: Option<usize>,
|
||||
}
|
||||
|
||||
impl Widget for SelectorList {
|
||||
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
|
||||
let mut selected = None;
|
||||
self.item_refs
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.for_each(|(idx, item)| {
|
||||
// item.handle_event(_cx, _event, _scope);
|
||||
let item = item.as_selector_item();
|
||||
if item.handle_event_with_a(cx, event, scope) {
|
||||
selected = Some(idx);
|
||||
}
|
||||
});
|
||||
|
||||
self.selected = selected;
|
||||
|
||||
if let Some(selected) = self.selected {
|
||||
let item = &self.item_refs[selected];
|
||||
|
||||
for item in self.item_refs.iter() {
|
||||
item.as_selector_item().set_selected(false);
|
||||
}
|
||||
|
||||
item.as_selector_item().set_selected(true);
|
||||
item.redraw(cx);
|
||||
}
|
||||
}
|
||||
fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
|
||||
self.draw_bg.begin(cx, Walk::fill(), self.layout);
|
||||
|
||||
for item in self.item_refs.iter() {
|
||||
item.draw_walk(cx, scope, walk).step();
|
||||
}
|
||||
|
||||
self.draw_bg.end(cx);
|
||||
DrawStep::done()
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectorList {
|
||||
pub fn set_items(&mut self, cx: &mut Cx, items: &Vec<ItemValue>) {
|
||||
for item in items.iter() {
|
||||
self.items.insert(item.clone());
|
||||
}
|
||||
|
||||
for item in self.items.iter() {
|
||||
let new_ref = WidgetRef::new_from_ptr(cx, self.item_ref);
|
||||
new_ref.as_selector_item().set_text(&item.name);
|
||||
// self.item_refs.insert(k.clone(), new_ref);
|
||||
self.item_refs.push(new_ref);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_if_not_exists(&mut self, cx: &mut Cx, item: &ItemValue) {
|
||||
if !self.items.contains(item) {
|
||||
self.items.insert(item.clone());
|
||||
let new_ref = WidgetRef::new_from_ptr(cx, self.item_ref);
|
||||
new_ref.as_selector_item().set_text(&item.name);
|
||||
self.item_refs.push(new_ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectorListRef {
|
||||
pub fn set_items(&self, cx: &mut Cx, items: &Vec<ItemValue>) {
|
||||
if let Some(mut item) = self.borrow_mut() {
|
||||
item.set_items(cx, items);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_if_not_exists(&self, cx: &mut Cx, item: &ItemValue) {
|
||||
if let Some(mut _item) = self.borrow_mut() {
|
||||
_item.insert_if_not_exists(cx, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Live, LiveHook, Widget)]
|
||||
pub struct SelectorItem {
|
||||
#[redraw]
|
||||
area: Area,
|
||||
#[live]
|
||||
draw_icon: DrawIcon,
|
||||
#[live]
|
||||
draw_icon_bg: DrawQuad,
|
||||
#[live]
|
||||
draw_title: DrawText,
|
||||
#[live]
|
||||
draw_title_bg: DrawQuad,
|
||||
#[layout]
|
||||
layout: Layout,
|
||||
#[walk]
|
||||
walk: Walk,
|
||||
|
||||
#[live]
|
||||
text: ArcStringMut,
|
||||
#[rust]
|
||||
selected: bool,
|
||||
}
|
||||
|
||||
impl Widget for SelectorItem {
|
||||
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {}
|
||||
|
||||
fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
|
||||
let walk = Walk::fit().with_margin_left(10.0).with_margin_right(10.0);
|
||||
|
||||
let icon_bg_color = if self.selected {
|
||||
vec4(0.0392, 0.3764, 0.9960, 0.1)
|
||||
} else {
|
||||
vec4(0.0, 0.0, 0.0, 0.0)
|
||||
};
|
||||
|
||||
let title_bg_color = if self.selected {
|
||||
vec4(0.0, 0.4706, 0.8431, 1.0)
|
||||
} else {
|
||||
vec4(0.0, 0.0, 0.0, 0.0)
|
||||
};
|
||||
|
||||
self.apply_over(
|
||||
cx,
|
||||
live! {
|
||||
draw_icon_bg: {
|
||||
color: (icon_bg_color)
|
||||
}
|
||||
draw_title_bg: {
|
||||
color: (title_bg_color)
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
cx.begin_turtle(walk, Layout::flow_down().with_align_x(0.5));
|
||||
|
||||
self.draw_icon_bg.begin(
|
||||
cx,
|
||||
Walk::fixed(64.0, 64.0),
|
||||
Layout::default().with_align_x(0.5).with_align_y(0.5),
|
||||
);
|
||||
|
||||
let icon_walk = Walk {
|
||||
width: Size::Fixed(54.0),
|
||||
height: Size::Fit,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
self.draw_icon.draw_walk(cx, icon_walk);
|
||||
self.draw_icon_bg.end(cx);
|
||||
|
||||
self.draw_title_bg.begin(
|
||||
cx,
|
||||
Walk::fit().with_margin_top(5.0),
|
||||
Layout::default().with_align_x(0.5).with_align_y(0.5),
|
||||
);
|
||||
|
||||
self.draw_title.draw_walk(
|
||||
cx,
|
||||
Walk::fit().with_margin_all(5.0),
|
||||
Align { x: 0.5, y: 0.5 },
|
||||
self.text.as_ref(),
|
||||
);
|
||||
|
||||
self.draw_title_bg.end(cx);
|
||||
|
||||
cx.end_turtle_with_area(&mut self.area);
|
||||
|
||||
DrawStep::done()
|
||||
}
|
||||
|
||||
fn set_text(&mut self, _v: &str) {
|
||||
self.text.as_mut_empty().push_str(_v);
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectorItem {
|
||||
fn handle_event_with(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) -> bool {
|
||||
match event.hits_with_sweep_area(cx, self.draw_icon_bg.area(), self.draw_title_bg.area()) {
|
||||
Hit::FingerDown(_fe) => true,
|
||||
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_selected(&mut self, selected: bool) {
|
||||
self.selected = selected;
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectorItemRef {
|
||||
pub fn handle_event_with_a(&self, cx: &mut Cx, event: &Event, scope: &mut Scope) -> bool {
|
||||
if let Some(mut item) = self.borrow_mut() {
|
||||
item.handle_event_with(cx, event, scope)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn set_selected(&self, selected: bool) {
|
||||
if let Some(mut item) = self.borrow_mut() {
|
||||
item.set_selected(selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Live, LiveHook, Widget)]
|
||||
pub struct Selector {
|
||||
#[deref]
|
||||
view: View,
|
||||
|
||||
#[rust]
|
||||
class: Vec<(ItemKey, Vec<ItemValue>)>,
|
||||
}
|
||||
|
||||
impl Widget for Selector {
|
||||
fn handle_event(&mut self, _cx: &mut Cx, _event: &Event, _scope: &mut Scope) {
|
||||
self.view.handle_event(_cx, _event, _scope);
|
||||
}
|
||||
|
||||
fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
|
||||
while let Some(widget) = self.view.draw_walk(cx, scope, walk).step() {
|
||||
let list = widget.as_portal_list();
|
||||
let Some(mut list) = list.borrow_mut() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let count = self.class.len() * 2;
|
||||
// TitleBar and List
|
||||
list.set_item_range(cx, 0, count);
|
||||
|
||||
while let Some(item_id) = list.next_visible_item(cx) {
|
||||
let prepared = self.class.get(item_id / 2);
|
||||
if let Some(prepared) = prepared {
|
||||
let item = if item_id % 2 == 0 {
|
||||
let title_bar = list.item(cx, item_id, live_id!(title_bar));
|
||||
let title = &prepared.0.category;
|
||||
title_bar.as_view().apply_over(
|
||||
cx,
|
||||
live! {
|
||||
class_title = {
|
||||
text: (title)
|
||||
}
|
||||
},
|
||||
);
|
||||
title_bar
|
||||
} else {
|
||||
let list_item = list.item(cx, item_id, live_id!(list_item));
|
||||
let list = list_item.as_selector_list();
|
||||
|
||||
for item in prepared.1.iter() {
|
||||
list.insert_if_not_exists(cx, item);
|
||||
}
|
||||
list_item
|
||||
};
|
||||
|
||||
item.draw_all(cx, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawStep::done()
|
||||
}
|
||||
}
|
||||
|
||||
impl Selector {
|
||||
fn set_items(&mut self, cx: &mut Cx, items: Vec<(ItemKey, Vec<ItemValue>)>) {
|
||||
self.class = items;
|
||||
self.view.redraw(cx);
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectorRef {
|
||||
pub fn set_items(&self, cx: &mut Cx, items: Vec<(ItemKey, Vec<ItemValue>)>) {
|
||||
if let Some(mut item) = self.borrow_mut() {
|
||||
item.set_items(cx, items);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,193 +0,0 @@
|
||||
use makepad_derive_widget::*;
|
||||
use makepad_micro_serde::*;
|
||||
use makepad_micro_serde::{DeRon, SerRon};
|
||||
use makepad_widgets::Dock;
|
||||
use makepad_widgets::*;
|
||||
|
||||
live_design! {
|
||||
import makepad_draw::shader::std::*;
|
||||
import makepad_widgets::base::*;
|
||||
import makepad_widgets::theme_desktop_dark::*;
|
||||
ICO_SEARCH = dep("crate://self/resources/icons/Icon_Search.svg")
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Eq, Hash, Copy, PartialEq, FromLiveId)]
|
||||
pub struct SelectorModalItemId(pub LiveId);
|
||||
|
||||
#[derive(Live, LiveHook, Widget)]
|
||||
pub struct SelectorModalItem {
|
||||
#[redraw]
|
||||
#[live]
|
||||
draw_bg: DrawQuad,
|
||||
#[live]
|
||||
draw_icon_bg: DrawQuad,
|
||||
#[live]
|
||||
draw_icon: DrawIcon,
|
||||
|
||||
#[live]
|
||||
draw_label_bg: DrawQuad,
|
||||
#[live]
|
||||
draw_label: DrawText,
|
||||
#[layout]
|
||||
layout: Layout,
|
||||
#[walk]
|
||||
walk: Walk,
|
||||
#[live]
|
||||
icon_walk: Walk,
|
||||
#[rust]
|
||||
area: Area,
|
||||
|
||||
#[rust]
|
||||
text: ArcStringMut,
|
||||
|
||||
#[live]
|
||||
selected: f32,
|
||||
#[live]
|
||||
hover: f32,
|
||||
}
|
||||
|
||||
pub enum SelectorModalItemAction {
|
||||
WasSweeped,
|
||||
WasSelected,
|
||||
MightBeSelected,
|
||||
None,
|
||||
}
|
||||
|
||||
impl SelectorModalItem {
|
||||
pub fn handle_event_with(
|
||||
&mut self,
|
||||
cx: &mut Cx,
|
||||
event: &Event,
|
||||
sweep_area: Area,
|
||||
dispatch_action: &mut dyn FnMut(&mut Cx, SelectorModalItemAction),
|
||||
) {
|
||||
match event.hits_with_options(cx, self.area, HitOptions::new().with_sweep_area(sweep_area))
|
||||
{
|
||||
Hit::FingerHoverIn(_) => {}
|
||||
|
||||
Hit::FingerHoverOut(_) => {}
|
||||
|
||||
Hit::FingerDown(_) => {
|
||||
dispatch_action(cx, SelectorModalItemAction::WasSweeped);
|
||||
}
|
||||
|
||||
Hit::FingerUp(se) => {
|
||||
if !se.is_sweep {
|
||||
dispatch_action(cx, SelectorModalItemAction::WasSelected);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for SelectorModalItem {
|
||||
fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
|
||||
let walk = Walk::fit().with_margin_all(5.0);
|
||||
|
||||
cx.begin_turtle(walk, Layout::default().with_align_x(0.5));
|
||||
|
||||
let icon_walk = Walk::fixed(64.0, 64.0).with_add_padding(Padding {
|
||||
left: 10.0,
|
||||
right: 10.0,
|
||||
top: 10.0,
|
||||
bottom: 10.0,
|
||||
});
|
||||
|
||||
self.draw_icon_bg.begin(
|
||||
cx,
|
||||
icon_walk,
|
||||
Layout::default().with_align_x(0.5).with_align_y(0.5),
|
||||
);
|
||||
|
||||
self.draw_icon.draw_walk(
|
||||
cx,
|
||||
Walk {
|
||||
width: Size::Fixed(54.0),
|
||||
height: Size::Fit,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
self.draw_icon_bg.end(cx);
|
||||
|
||||
self.draw_label_bg.begin(
|
||||
cx,
|
||||
Walk::fit().with_margin_all(5.0),
|
||||
Layout::default().with_align_x(0.5).with_align_y(0.5),
|
||||
);
|
||||
|
||||
self.draw_label.draw_walk(
|
||||
cx,
|
||||
Walk::fit(),
|
||||
Align { x: 0.5, y: 0.5 },
|
||||
self.text.as_ref(),
|
||||
);
|
||||
self.draw_label_bg.end(cx);
|
||||
|
||||
cx.end_turtle_with_area(&mut self.area);
|
||||
|
||||
DrawStep::done()
|
||||
}
|
||||
|
||||
fn text(&self) -> String {
|
||||
self.text.as_ref().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Live, LiveHook, Widget)]
|
||||
pub struct SelectorModalItemList {
|
||||
#[redraw]
|
||||
#[live]
|
||||
draw_bg: DrawQuad,
|
||||
#[rust]
|
||||
items: ComponentMap<SelectorModalItemId, SelectorModalItem>,
|
||||
#[rust]
|
||||
count: usize,
|
||||
|
||||
#[live]
|
||||
draw_title: DrawText,
|
||||
|
||||
#[rust]
|
||||
title: String,
|
||||
}
|
||||
|
||||
impl Widget for SelectorModalItemList {
|
||||
fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
|
||||
let walk = Walk {
|
||||
width: Size::Fill,
|
||||
height: Size::Fit,
|
||||
..Default::default()
|
||||
};
|
||||
let mut layout = Layout::default();
|
||||
layout.flow = Flow::RightWrap;
|
||||
|
||||
let items = self.items.iter_mut();
|
||||
cx.begin_turtle(walk, layout);
|
||||
|
||||
for (_, item) in items {
|
||||
item.draw_walk(cx, scope, Walk::default());
|
||||
}
|
||||
|
||||
cx.end_turtle();
|
||||
DrawStep::done()
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectorModalItemList {
|
||||
pub fn set_items(&mut self, cx: &mut Cx, items: Vec<(String, String, String)>) {
|
||||
self.items.insert(
|
||||
SelectorModalItemId(LiveId::new(cx)),
|
||||
SelectorModalItem::new(cx),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Live, LiveHook, SerRon, DeRon)]
|
||||
pub struct SelectorItem {
|
||||
#[live("icon")]
|
||||
icon: String,
|
||||
#[live("label")]
|
||||
label: String,
|
||||
}
|
||||
@ -1,7 +1,4 @@
|
||||
use std::cell::RefCell;
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
|
||||
use crate::elements::{Element, ElementAttach, Elements, ElementsRef};
|
||||
use crate::elements::{Element, ElementAttach, Elements};
|
||||
use crate::elementvec::ElementVec;
|
||||
use encase;
|
||||
use quick_cache::sync::Cache;
|
||||
@ -277,8 +274,6 @@ impl DrawList {
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable, Default)]
|
||||
// #[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, encase::ShaderType, Default)]
|
||||
pub struct CommonUniform {
|
||||
pub model_matrix: glam::Mat4,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user