This commit is contained in:
Jeremy Soller 2023-02-10 07:34:43 -07:00
parent 0a077856b2
commit 5258bf4811
No known key found for this signature in database
GPG key ID: DCFCA852D3906975
2 changed files with 41 additions and 77 deletions

View file

@ -158,15 +158,15 @@ impl Application for Window {
type Theme = Theme; type Theme = Theme;
fn new(_flags: ()) -> (Self, Command<Self::Message>) { fn new(_flags: ()) -> (Self, Command<Self::Message>) {
let mut tab_model = segmented_button::Model::builder() let mut tab_model = segmented_button::Model::builder().build();
.build();
let mut tab = Tab::new(); let mut tab = Tab::new();
if let Some(arg) = env::args().nth(1) { if let Some(arg) = env::args().nth(1) {
tab.open(PathBuf::from(arg)); tab.open(PathBuf::from(arg));
} }
tab_model.insert() tab_model
.insert()
.text(tab.title()) .text(tab.title())
.icon("text-x-generic") .icon("text-x-generic")
.data(tab) .data(tab)
@ -177,7 +177,7 @@ impl Application for Window {
theme: Theme::Dark, theme: Theme::Dark,
tab_model, tab_model,
}, },
Command::none() Command::none(),
) )
} }
@ -199,13 +199,14 @@ impl Application for Window {
let mut tab = Tab::new(); let mut tab = Tab::new();
tab.open(path); tab.open(path);
self.tab_model.insert() self.tab_model
.insert()
.text(tab.title()) .text(tab.title())
.icon("text-x-generic") .icon("text-x-generic")
.data(tab) .data(tab)
.activate(); .activate();
} }
}, }
Message::Save => { Message::Save => {
let mut title_opt = None; let mut title_opt = None;
@ -216,20 +217,20 @@ impl Application for Window {
title_opt = Some(tab.title()); title_opt = Some(tab.title());
} }
tab.save(); tab.save();
}, }
None => { None => {
log::info!("TODO: NO TAB OPEN"); log::info!("TODO: NO TAB OPEN");
}, }
} }
if let Some(title) = title_opt { if let Some(title) = title_opt {
self.tab_model.text_set(self.tab_model.active(), title); self.tab_model.text_set(self.tab_model.active(), title);
} }
}, }
Message::Tab(entity) => self.tab_model.activate(entity), Message::Tab(entity) => self.tab_model.activate(entity),
Message::Todo => { Message::Todo => {
log::info!("TODO"); log::info!("TODO");
}, }
} }
Command::none() Command::none()
@ -241,24 +242,20 @@ impl Application for Window {
match item { match item {
"Open" => Message::Open, "Open" => Message::Open,
"Save" => Message::Save, "Save" => Message::Save,
_ => Message::Todo _ => Message::Todo,
} }
}) })
.padding(8) .padding(8)
.placeholder("File") .placeholder("File"),
,
MenuList::new(vec!["Todo"], None, |_| Message::Todo) MenuList::new(vec!["Todo"], None, |_| Message::Todo)
.padding(8) .padding(8)
.placeholder("Edit") .placeholder("Edit"),
,
MenuList::new(vec!["Todo"], None, |_| Message::Todo) MenuList::new(vec!["Todo"], None, |_| Message::Todo)
.padding(8) .padding(8)
.placeholder("View") .placeholder("View"),
,
MenuList::new(vec!["Todo"], None, |_| Message::Todo) MenuList::new(vec!["Todo"], None, |_| Message::Todo)
.padding(8) .padding(8)
.placeholder("Help") .placeholder("Help"),
,
] ]
.align_items(Alignment::Start) .align_items(Alignment::Start)
.padding(4) .padding(4)
@ -274,15 +271,16 @@ impl Application for Window {
tab_bar, tab_bar,
match self.active_tab() { match self.active_tab() {
Some(tab) => { Some(tab) => {
text_box(&tab.editor) text_box(&tab.editor).padding(8)
.padding(8) }
},
None => { None => {
panic!("TODO: No tab open"); panic!("TODO: No tab open");
}, }
} }
].padding([0, 16]) ]
].into(); .padding([0, 16])
]
.into();
// Uncomment to debug layout: // Uncomment to debug layout:
//content.explain(Color::WHITE) //content.explain(Color::WHITE)

View file

@ -14,8 +14,7 @@ use cosmic::iced_native::widget::container;
use cosmic::iced_native::widget::scrollable; use cosmic::iced_native::widget::scrollable;
use cosmic::iced_native::widget::tree::{self, Tree}; use cosmic::iced_native::widget::tree::{self, Tree};
use cosmic::iced_native::{ use cosmic::iced_native::{
Clipboard, Element, Layout, Length, Padding, Point, Rectangle, Shell, Size, Clipboard, Element, Layout, Length, Padding, Point, Rectangle, Shell, Size, Widget,
Widget,
}; };
use std::borrow::Cow; use std::borrow::Cow;
@ -98,12 +97,8 @@ where
T: ToString + Eq, T: ToString + Eq,
[T]: ToOwned<Owned = Vec<T>>, [T]: ToOwned<Owned = Vec<T>>,
Renderer: text::Renderer, Renderer: text::Renderer,
Renderer::Theme: StyleSheet Renderer::Theme: StyleSheet + scrollable::StyleSheet + menu::StyleSheet + container::StyleSheet,
+ scrollable::StyleSheet <Renderer::Theme as menu::StyleSheet>::Style: From<<Renderer::Theme as StyleSheet>::Style>,
+ menu::StyleSheet
+ container::StyleSheet,
<Renderer::Theme as menu::StyleSheet>::Style:
From<<Renderer::Theme as StyleSheet>::Style>,
{ {
/// The default padding of a [`MenuList`]. /// The default padding of a [`MenuList`].
pub const DEFAULT_PADDING: Padding = Padding::new(5); pub const DEFAULT_PADDING: Padding = Padding::new(5);
@ -159,28 +154,20 @@ where
} }
/// Sets the style of the [`MenuList`]. /// Sets the style of the [`MenuList`].
pub fn style( pub fn style(mut self, style: impl Into<<Renderer::Theme as StyleSheet>::Style>) -> Self {
mut self,
style: impl Into<<Renderer::Theme as StyleSheet>::Style>,
) -> Self {
self.style = style.into(); self.style = style.into();
self self
} }
} }
impl<'a, T: 'a, Message, Renderer> Widget<Message, Renderer> impl<'a, T: 'a, Message, Renderer> Widget<Message, Renderer> for MenuList<'a, T, Message, Renderer>
for MenuList<'a, T, Message, Renderer>
where where
T: Clone + ToString + Eq + 'static, T: Clone + ToString + Eq + 'static,
[T]: ToOwned<Owned = Vec<T>>, [T]: ToOwned<Owned = Vec<T>>,
Message: 'a, Message: 'a,
Renderer: text::Renderer + 'a, Renderer: text::Renderer + 'a,
Renderer::Theme: StyleSheet Renderer::Theme: StyleSheet + scrollable::StyleSheet + menu::StyleSheet + container::StyleSheet,
+ scrollable::StyleSheet <Renderer::Theme as menu::StyleSheet>::Style: From<<Renderer::Theme as StyleSheet>::Style>,
+ menu::StyleSheet
+ container::StyleSheet,
<Renderer::Theme as menu::StyleSheet>::Style:
From<<Renderer::Theme as StyleSheet>::Style>,
{ {
fn tag(&self) -> tree::Tag { fn tag(&self) -> tree::Tag {
tree::Tag::of::<State<T>>() tree::Tag::of::<State<T>>()
@ -198,11 +185,7 @@ where
Length::Shrink Length::Shrink
} }
fn layout( fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node {
&self,
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
layout( layout(
renderer, renderer,
limits, limits,
@ -300,12 +283,8 @@ where
[T]: ToOwned<Owned = Vec<T>>, [T]: ToOwned<Owned = Vec<T>>,
Message: 'a, Message: 'a,
Renderer: text::Renderer + 'a, Renderer: text::Renderer + 'a,
Renderer::Theme: StyleSheet Renderer::Theme: StyleSheet + scrollable::StyleSheet + menu::StyleSheet + container::StyleSheet,
+ scrollable::StyleSheet <Renderer::Theme as menu::StyleSheet>::Style: From<<Renderer::Theme as StyleSheet>::Style>,
+ menu::StyleSheet
+ container::StyleSheet,
<Renderer::Theme as menu::StyleSheet>::Style:
From<<Renderer::Theme as StyleSheet>::Style>,
{ {
fn from(menu_list: MenuList<'a, T, Message, Renderer>) -> Self { fn from(menu_list: MenuList<'a, T, Message, Renderer>) -> Self {
Self::new(menu_list) Self::new(menu_list)
@ -381,10 +360,7 @@ where
}; };
let size = { let size = {
let intrinsic = Size::new( let intrinsic = Size::new(max_width as f32, f32::from(text_size));
max_width as f32,
f32::from(text_size),
);
limits.resolve(intrinsic).pad(padding) limits.resolve(intrinsic).pad(padding)
}; };
@ -420,8 +396,7 @@ where
event::Status::Captured event::Status::Captured
} else if layout.bounds().contains(cursor_position) { } else if layout.bounds().contains(cursor_position) {
state.is_open = true; state.is_open = true;
state.hovered_option = state.hovered_option = options.iter().position(|option| Some(option) == selected);
options.iter().position(|option| Some(option) == selected);
event::Status::Captured event::Status::Captured
} else { } else {
@ -493,10 +468,7 @@ where
} }
/// Returns the current [`mouse::Interaction`] of a [`MenuList`]. /// Returns the current [`mouse::Interaction`] of a [`MenuList`].
pub fn mouse_interaction( pub fn mouse_interaction(layout: Layout<'_>, cursor_position: Point) -> mouse::Interaction {
layout: Layout<'_>,
cursor_position: Point,
) -> mouse::Interaction {
let bounds = layout.bounds(); let bounds = layout.bounds();
let is_mouse_over = bounds.contains(cursor_position); let is_mouse_over = bounds.contains(cursor_position);
@ -522,12 +494,8 @@ where
T: Clone + ToString, T: Clone + ToString,
Message: 'a, Message: 'a,
Renderer: text::Renderer + 'a, Renderer: text::Renderer + 'a,
Renderer::Theme: StyleSheet Renderer::Theme: StyleSheet + scrollable::StyleSheet + menu::StyleSheet + container::StyleSheet,
+ scrollable::StyleSheet <Renderer::Theme as menu::StyleSheet>::Style: From<<Renderer::Theme as StyleSheet>::Style>,
+ menu::StyleSheet
+ container::StyleSheet,
<Renderer::Theme as menu::StyleSheet>::Style:
From<<Renderer::Theme as StyleSheet>::Style>,
{ {
if state.is_open { if state.is_open {
let bounds = layout.bounds(); let bounds = layout.bounds();
@ -548,8 +516,7 @@ where
let labels = options.iter().map(ToString::to_string); let labels = options.iter().map(ToString::to_string);
let labels_width = let labels_width = labels.map(|label| measure(&label)).max().unwrap_or(100);
labels.map(|label| measure(&label)).max().unwrap_or(100);
labels_width as u16 + padding.left + padding.right labels_width as u16 + padding.left + padding.right
}; };
@ -612,8 +579,7 @@ pub fn draw<T, Renderer>(
let label = selected.map(ToString::to_string); let label = selected.map(ToString::to_string);
if let Some(label) = label.as_deref().or(placeholder) { if let Some(label) = label.as_deref().or(placeholder) {
let text_size = let text_size = f32::from(text_size.unwrap_or_else(|| renderer.default_size()));
f32::from(text_size.unwrap_or_else(|| renderer.default_size()));
renderer.fill_text(Text { renderer.fill_text(Text {
content: label, content: label,