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",
|
"element_bridge",
|
||||||
"futures",
|
"futures",
|
||||||
"glam",
|
"glam",
|
||||||
|
"indexmap",
|
||||||
"log",
|
"log",
|
||||||
"makepad-widgets",
|
"makepad-widgets",
|
||||||
"mp_core",
|
"mp_core",
|
||||||
|
|||||||
@ -20,3 +20,4 @@ element_bridge = { path = "../element_bridge", version = "*" }
|
|||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
async-trait = "0.1.83"
|
async-trait = "0.1.83"
|
||||||
thiserror = "2.0.3"
|
thiserror = "2.0.3"
|
||||||
|
indexmap = "2.6.0"
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
use crate::file::*;
|
use crate::file::*;
|
||||||
use crate::menu::{handle_menu, spawn_background};
|
use crate::menu::{handle_menu, spawn_background};
|
||||||
use crate::widgets::area::TAreaWidgetRefExt;
|
use crate::widgets::area::TAreaWidgetRefExt;
|
||||||
|
use crate::widgets::selector::{
|
||||||
|
ItemKey, ItemValue, SelectorListWidgetRefExt, SelectorWidgetRefExt,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::windows_manager::WM;
|
use crate::windows_manager::WM;
|
||||||
use crate::{render_task::RenderTasks, PLUGIN_MANAGER, RUNTIME};
|
use crate::{render_task::RenderTasks, PLUGIN_MANAGER, RUNTIME};
|
||||||
use ::log::info;
|
use ::log::info;
|
||||||
@ -16,7 +20,6 @@ live_design! {
|
|||||||
import makepad_widgets::base::*;
|
import makepad_widgets::base::*;
|
||||||
import makepad_widgets::theme_desktop_dark::*;
|
import makepad_widgets::theme_desktop_dark::*;
|
||||||
import crate::app_ui::MainView;
|
import crate::app_ui::MainView;
|
||||||
import crate::widgets::selector_modal::SelectorModal;
|
|
||||||
|
|
||||||
HELLO = "Hello, World!";
|
HELLO = "Hello, World!";
|
||||||
|
|
||||||
@ -87,8 +90,6 @@ live_design! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selector = <SelectorModal>{}
|
|
||||||
|
|
||||||
<MainView>{}
|
<MainView>{}
|
||||||
}
|
}
|
||||||
window_menu = {
|
window_menu = {
|
||||||
@ -177,8 +178,8 @@ impl LiveRegister for App {
|
|||||||
crate::app_ui::live_design(_cx);
|
crate::app_ui::live_design(_cx);
|
||||||
crate::widgets::area::live_design(_cx);
|
crate::widgets::area::live_design(_cx);
|
||||||
crate::widgets::renderer::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::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;
|
let render_task = render_tasks.lock().await;
|
||||||
render_task.render().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) {
|
fn handle_signal(&mut self, cx: &mut Cx) {
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
use makepad_widgets::Dock;
|
|
||||||
use makepad_widgets::*;
|
use makepad_widgets::*;
|
||||||
live_design! {
|
live_design! {
|
||||||
import makepad_widgets::base::*;
|
import makepad_widgets::base::*;
|
||||||
@ -7,8 +6,9 @@ live_design! {
|
|||||||
import crate::widgets::renderer::IRenderer;
|
import crate::widgets::renderer::IRenderer;
|
||||||
|
|
||||||
import makepad_draw::shader::std::*;
|
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::background_text::BackgroundLabel;
|
||||||
|
import crate::widgets::selector::*;
|
||||||
|
|
||||||
HELLO = "Hello, World!";
|
HELLO = "Hello, World!";
|
||||||
|
|
||||||
@ -62,8 +62,16 @@ live_design! {
|
|||||||
x: 0.5,
|
x: 0.5,
|
||||||
y: 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"}
|
<H4>{ text: "Input"}
|
||||||
|
|
||||||
|
|
||||||
<View>{
|
<View>{
|
||||||
flow: Right
|
flow: Right
|
||||||
width: Fill
|
width: Fill
|
||||||
@ -146,10 +155,9 @@ live_design! {
|
|||||||
<BackgroundLabel>{
|
<BackgroundLabel>{
|
||||||
text: "Holy Shit",
|
text: "Holy Shit",
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Group> {
|
<Group> {
|
||||||
|
|
||||||
<ButtonGroup> {
|
<ButtonGroup> {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
pub mod area;
|
pub mod area;
|
||||||
pub mod background_text;
|
pub mod background_text;
|
||||||
pub mod renderer;
|
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 crate::elements::{Element, ElementAttach, Elements};
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
|
||||||
|
|
||||||
use crate::elements::{Element, ElementAttach, Elements, ElementsRef};
|
|
||||||
use crate::elementvec::ElementVec;
|
use crate::elementvec::ElementVec;
|
||||||
use encase;
|
use encase;
|
||||||
use quick_cache::sync::Cache;
|
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)]
|
#[derive(Debug, Clone, Copy, encase::ShaderType, Default)]
|
||||||
pub struct CommonUniform {
|
pub struct CommonUniform {
|
||||||
pub model_matrix: glam::Mat4,
|
pub model_matrix: glam::Mat4,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user