Changed the file structure

This commit is contained in:
Eduardo Flores 2022-10-12 19:44:44 -07:00 committed by Michael Murphy
parent 7743d0d084
commit 420d3c3dfc
22 changed files with 409 additions and 395 deletions

View file

@ -7,6 +7,6 @@ pub fn main() -> cosmic::iced::Result {
let mut settings = settings();
settings.window.min_size = Some((600, 300));
// TODO: Window resize handles not functioning yet
// settings.window.decorations = false;
settings.window.decorations = false;
Window::run(settings)
}

View file

@ -1,4 +1,4 @@
use cosmic::widget::{expander, expander_row, list_section_style, ListBox};
use cosmic::widget::{expander, ListBox};
use cosmic::{
iced::widget::{
checkbox, column, container, horizontal_space, pick_list, progress_bar, radio, row, slider,
@ -7,11 +7,8 @@ use cosmic::{
iced::{self, theme, Alignment, Application, Color, Command, Element, Length, Theme},
iced_lazy::responsive,
iced_winit::window::{drag, maximize, minimize},
scrollable,
widget::{
button, header_bar, list_item, list_row, list_section, list_view, nav_bar_style,
nav_button, toggler,
},
list_item, list_row, list_section, list_view, nav_button, scrollable,
widget::{button, header_bar, list_row, list_view::*, nav_bar::nav_bar_style, toggler},
};
#[derive(Default)]
@ -77,6 +74,7 @@ impl Application for Window {
.show_maximize(true)
.show_minimize(true);
window.slider_value = 50.0;
// window.theme = Theme::Light;
window.pick_list_selected = Some("Option 1");
(window, Command::none())
}
@ -109,6 +107,7 @@ impl Application for Window {
fn view(&self) -> Element<Message> {
let mut header: Element<Message, _> = header_bar()
.title(self.title())
.nav_title(String::from("Settings"))
.sidebar_active(self.sidebar_toggled)
.show_minimize(self.show_minimize)
.show_maximize(self.show_maximize)
@ -240,12 +239,12 @@ impl Application for Window {
.icon(String::from("edit-paste"))
.on_row_selected(Box::new(Message::RowSelected))
.rows(vec![
expander_row()
list_row()
.title("Label")
.subtitle("Caption")
.icon(String::from("help-about")),
expander_row().subtitle("Caption").title("Label"),
expander_row().title("Label")
list_row().subtitle("Caption").title("Label"),
list_row().title("Label")
])
),
list_section!(

View file

@ -58,7 +58,7 @@ impl<'a> TextBuffer<'a> {
let mut reshaped = 0;
while self.shape_lines.len() < self.text_lines.len()
&& (self.layout_lines.len() as i32) < lines
&& (self.layout_lines.len() as i32) < lines
{
let line_i = FontLineIndex::new(self.shape_lines.len());
self.reshape_line(line_i);
@ -74,7 +74,9 @@ impl<'a> TextBuffer<'a> {
pub fn reshape_line(&mut self, line_i: FontLineIndex) {
let instant = Instant::now();
let shape_line = self.font_matches.shape_line(line_i, &self.text_lines[line_i.get()]);
let shape_line = self
.font_matches
.shape_line(line_i, &self.text_lines[line_i.get()]);
if line_i.get() < self.shape_lines.len() {
self.shape_lines[line_i.get()] = shape_line;
} else {
@ -131,7 +133,7 @@ impl<'a> TextBuffer<'a> {
self.font_size,
self.line_width,
&mut self.layout_lines,
insert_i
insert_i,
);
self.redraw = true;

View file

@ -66,7 +66,8 @@ impl<'a> FontLayoutLine<'a> {
// Compute the fractional offset-- you'll likely want to quantize this
// in a real renderer
let offset = Vector::new(cache_key.x_bin.as_float(), cache_key.y_bin.as_float());
let offset =
Vector::new(cache_key.x_bin.as_float(), cache_key.y_bin.as_float());
// Select our source order
Render::new(&[
@ -77,12 +78,12 @@ impl<'a> FontLayoutLine<'a> {
// Standard scalable outline
Source::Outline,
])
// Select a subpixel format
.format(Format::Alpha)
// Apply the fractional offset
.offset(offset)
// Render the image
.render(&mut scaler, cache_key.glyph_id)
// Select a subpixel format
.format(Format::Alpha)
// Apply the fractional offset
.offset(offset)
// Render the image
.render(&mut scaler, cache_key.glyph_id)
});
if let Some(ref image) = image_opt {
@ -96,28 +97,25 @@ impl<'a> FontLayoutLine<'a> {
let mut i = 0;
for off_y in 0..image.placement.height as i32 {
for off_x in 0..image.placement.width as i32 {
let color =
(image.data[i] as u32) << 24 |
base & 0xFFFFFF;
let color = (image.data[i] as u32) << 24 | base & 0xFFFFFF;
f(x + off_x, y + off_y, color);
i += 1;
}
}
},
}
Content::Color => {
let mut i = 0;
for off_y in 0..image.placement.height as i32 {
for off_x in 0..image.placement.width as i32 {
let color =
(image.data[i + 3] as u32) << 24 |
(image.data[i] as u32) << 16 |
(image.data[i + 1] as u32) << 8 |
(image.data[i + 2] as u32);
let color = (image.data[i + 3] as u32) << 24
| (image.data[i] as u32) << 16
| (image.data[i + 1] as u32) << 8
| (image.data[i + 2] as u32);
f(x + off_x, y + off_y, color);
i += 4;
}
}
},
}
Content::SubpixelMask => {
println!("TODO: SubpixelMask");
}

View file

@ -5,7 +5,15 @@ pub struct FontMatches<'a> {
}
impl<'a> FontMatches<'a> {
fn shape_fallback(&self, font_i: usize, line: &str, start_word: usize, end_word: usize, span_rtl: bool, blank: bool) -> (Vec<FontShapeGlyph>, Vec<usize>) {
fn shape_fallback(
&self,
font_i: usize,
line: &str,
start_word: usize,
end_word: usize,
span_rtl: bool,
blank: bool,
) -> (Vec<FontShapeGlyph>, Vec<usize>) {
let word = &line[start_word..end_word];
let font_scale = self.fonts[font_i].rustybuzz.units_per_em() as f32;
@ -101,15 +109,24 @@ impl<'a> FontMatches<'a> {
(glyphs, missing)
}
fn shape_word(&self, line: &str, start_word: usize, end_word: usize, span_rtl: bool, blank: bool) -> FontShapeWord {
fn shape_word(
&self,
line: &str,
start_word: usize,
end_word: usize,
span_rtl: bool,
blank: bool,
) -> FontShapeWord {
let mut font_i = 0;
let (mut glyphs, mut missing) = self.shape_fallback(font_i, line, start_word, end_word, span_rtl, blank);
let (mut glyphs, mut missing) =
self.shape_fallback(font_i, line, start_word, end_word, span_rtl, blank);
//TODO: improve performance!
font_i += 1;
while !missing.is_empty() && font_i < self.fonts.len() {
// println!("Evaluating fallback with font {}", font_i);
let (mut fb_glyphs, fb_missing) = self.shape_fallback(font_i, line, start_word, end_word, span_rtl, blank);
let (mut fb_glyphs, fb_missing) =
self.shape_fallback(font_i, line, start_word, end_word, span_rtl, blank);
// Insert all matching glyphs
let mut fb_i = 0;
@ -187,7 +204,11 @@ impl<'a> FontMatches<'a> {
) -> FontShapeSpan {
let span = &line[start_span..end_span];
log::debug!(" Span {}: '{}'", if span_rtl { "RTL" } else { "LTR" }, span);
log::debug!(
" Span {}: '{}'",
if span_rtl { "RTL" } else { "LTR" },
span
);
let mut words = Vec::new();
@ -202,10 +223,22 @@ impl<'a> FontMatches<'a> {
}
}
if start_word < start_lb {
words.push(self.shape_word(line, start_span + start_word, start_span + start_lb, span_rtl, false));
words.push(self.shape_word(
line,
start_span + start_word,
start_span + start_lb,
span_rtl,
false,
));
}
if start_lb < end_lb {
words.push(self.shape_word(line, start_span + start_lb, start_span + end_lb, span_rtl, true));
words.push(self.shape_word(
line,
start_span + start_lb,
start_span + end_lb,
span_rtl,
true,
));
}
start_word = end_lb;
}

View file

@ -1,7 +1,4 @@
use std::{
collections::HashMap,
sync::Mutex,
};
use std::{collections::HashMap, sync::Mutex};
pub use self::cache::*;
mod cache;
@ -21,7 +18,6 @@ mod system;
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct FontCacheKey {
glyph_id: u16,
}
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]

View file

@ -26,27 +26,24 @@ impl<'a> FontShapeGlyph<'a> {
let x_advance = font_size as f32 * self.x_advance;
#[cfg(feature = "ab_glyph")]
let inner = self.font.ab_glyph.outline_glyph(
self.inner.with_scale_and_position(
let inner = self
.font
.ab_glyph
.outline_glyph(self.inner.with_scale_and_position(
font_size as f32,
ab_glyph::point(
x + x_offset,
y - y_offset,
)
)
);
ab_glyph::point(x + x_offset, y - y_offset),
));
#[cfg(feature = "rusttype")]
let inner = self.font.rusttype.glyph(self.inner)
let inner = self
.font
.rusttype
.glyph(self.inner)
.scaled(rusttype::Scale::uniform(font_size as f32))
.positioned(rusttype::point(x + x_offset, y - y_offset));
#[cfg(feature = "swash")]
let inner = CacheKey::new(
self.inner,
font_size,
(x + x_offset, y - y_offset),
);
let inner = CacheKey::new(self.inner, font_size, (x + x_offset, y - y_offset));
FontLayoutGlyph {
start: self.start,

View file

@ -30,31 +30,28 @@ impl FontSystem {
}
}
Self {
db,
}
Self { db }
}
pub fn matches<'a, F: Fn(&fontdb::FaceInfo) -> bool>(&'a self, f: F) -> Option<FontMatches<'a>> {
pub fn matches<'a, F: Fn(&fontdb::FaceInfo) -> bool>(
&'a self,
f: F,
) -> Option<FontMatches<'a>> {
let mut fonts = Vec::new();
for face in self.db.faces() {
if ! f(face) {
if !f(face) {
continue;
}
let font_opt = Font::new(
&face.post_script_name,
match &face.source {
fontdb::Source::Binary(data) => {
data.deref().as_ref()
},
fontdb::Source::Binary(data) => data.deref().as_ref(),
fontdb::Source::File(path) => {
println!("Unsupported fontdb Source::File('{}')", path.display());
continue;
},
fontdb::Source::SharedFile(_path, data) => {
data.deref().as_ref()
},
}
fontdb::Source::SharedFile(_path, data) => data.deref().as_ref(),
},
face.index,
);
@ -67,10 +64,8 @@ impl FontSystem {
}
}
if ! fonts.is_empty() {
Some(FontMatches {
fonts
})
if !fonts.is_empty() {
Some(FontMatches { fonts })
} else {
None
}

View file

@ -1,17 +1,6 @@
use orbclient::{Color, EventOption, Renderer, Window, WindowFlag};
use std::{
cmp,
env,
fs,
time::Instant,
};
use text::{
FontLineIndex,
FontSystem,
TextAction,
TextCursor,
TextBuffer,
};
use std::{cmp, env, fs, time::Instant};
use text::{FontLineIndex, FontSystem, TextAction, TextBuffer, TextCursor};
fn main() {
let display_scale = match orbclient::get_display_size() {
@ -112,10 +101,13 @@ fn main() {
buffer.shape_until(scroll + window_lines);
scroll = cmp::max(0, cmp::min(
buffer.layout_lines().len() as i32 - (window_lines - 1),
scroll
));
scroll = cmp::max(
0,
cmp::min(
buffer.layout_lines().len() as i32 - (window_lines - 1),
scroll,
),
);
if rehit {
let instant = Instant::now();
@ -173,7 +165,12 @@ fn main() {
let mut line_y = line_height;
let mut start_line_opt = None;
let mut end_line = FontLineIndex::new(0);
for (line_i, line) in buffer.layout_lines().iter().skip(scroll as usize).enumerate() {
for (line_i, line) in buffer
.layout_lines()
.iter()
.skip(scroll as usize)
.enumerate()
{
if line_y >= window.height() as i32 {
break;
}
@ -236,7 +233,7 @@ fn main() {
start_y as i32,
line_x as u32,
(end_y - start_y) as u32,
Color::rgba(0xFF, 0xFF, 0xFF, 0x40)
Color::rgba(0xFF, 0xFF, 0xFF, 0x40),
);
}
}
@ -251,39 +248,39 @@ fn main() {
for event in window.events() {
match event.to_option() {
EventOption::Key(event) => {
match event.scancode {
orbclient::K_CTRL => ctrl_pressed = event.pressed,
orbclient::K_LEFT if event.pressed => buffer.action(TextAction::Left),
orbclient::K_RIGHT if event.pressed => buffer.action(TextAction::Right),
orbclient::K_UP if event.pressed => buffer.action(TextAction::Up),
orbclient::K_DOWN if event.pressed => buffer.action(TextAction::Down),
orbclient::K_BKSP if event.pressed => buffer.action(TextAction::Backspace),
orbclient::K_DEL if event.pressed => buffer.action(TextAction::Delete),
orbclient::K_PGUP if event.pressed => {
scroll -= window_lines;
buffer.redraw = true;
},
orbclient::K_PGDN if event.pressed => {
scroll += window_lines;
buffer.redraw = true;
},
orbclient::K_0 if event.pressed && ctrl_pressed => {
font_size_i = font_size_default;
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
},
orbclient::K_MINUS if event.pressed && ctrl_pressed => if font_size_i > 0 {
EventOption::Key(event) => match event.scancode {
orbclient::K_CTRL => ctrl_pressed = event.pressed,
orbclient::K_LEFT if event.pressed => buffer.action(TextAction::Left),
orbclient::K_RIGHT if event.pressed => buffer.action(TextAction::Right),
orbclient::K_UP if event.pressed => buffer.action(TextAction::Up),
orbclient::K_DOWN if event.pressed => buffer.action(TextAction::Down),
orbclient::K_BKSP if event.pressed => buffer.action(TextAction::Backspace),
orbclient::K_DEL if event.pressed => buffer.action(TextAction::Delete),
orbclient::K_PGUP if event.pressed => {
scroll -= window_lines;
buffer.redraw = true;
}
orbclient::K_PGDN if event.pressed => {
scroll += window_lines;
buffer.redraw = true;
}
orbclient::K_0 if event.pressed && ctrl_pressed => {
font_size_i = font_size_default;
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
}
orbclient::K_MINUS if event.pressed && ctrl_pressed => {
if font_size_i > 0 {
font_size_i -= 1;
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
}
orbclient::K_EQUALS if event.pressed && ctrl_pressed => {
if font_size_i + 1 < font_sizes.len() {
font_size_i += 1;
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
}
}
_ => (),
}
orbclient::K_EQUALS if event.pressed && ctrl_pressed => {
if font_size_i + 1 < font_sizes.len() {
font_size_i += 1;
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
}
}
_ => (),
},
EventOption::TextInput(event) if !ctrl_pressed => {
buffer.action(TextAction::Insert(event.character));

View file

@ -1,8 +0,0 @@
[package]
name = "settings"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View file

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}

View file

@ -1,6 +1,6 @@
use std::vec;
use crate::list_box_row;
use crate::{list_box_row, widget::ListRow};
use apply::Apply;
use derive_setters::Setters;
use iced::{
@ -20,7 +20,7 @@ pub struct Expander<'a, Message> {
icon: Option<String>,
expansible: bool,
#[setters(skip)]
rows: Option<Vec<ExpanderRow<'a>>>,
rows: Option<Vec<ListRow<'a>>>,
#[setters(strip_option)]
on_row_selected: Option<Box<dyn Fn(usize) -> Message + 'a>>,
}
@ -36,23 +36,6 @@ pub fn expander<'a, Message>() -> Expander<'a, Message> {
}
}
#[derive(Setters, Default, Debug, Clone)]
pub struct ExpanderRow<'a> {
pub(crate) title: &'a str,
#[setters(strip_option)]
pub subtitle: Option<&'a str>,
#[setters(strip_option)]
pub icon: Option<String>,
}
pub fn expander_row<'a>() -> ExpanderRow<'a> {
ExpanderRow {
title: "",
subtitle: None,
icon: None,
}
}
pub struct ExpanderState {
pub expanded: bool,
}
@ -70,13 +53,13 @@ pub enum ExpanderEvent {
}
impl<'a, Message> Expander<'a, Message> {
pub fn rows(mut self, rows: Vec<ExpanderRow<'a>>) -> Self {
pub fn rows(mut self, rows: Vec<ListRow<'a>>) -> Self {
self.rows = Some(rows);
self.expansible = true;
self
}
pub fn push(&mut self, row: ExpanderRow<'a>) {
pub fn push(&mut self, row: ListRow<'a>) {
if self.rows.is_none() {
self.rows = Some(vec![])
}

View file

@ -1,84 +0,0 @@
use iced::{widget, Background, Color, Theme};
#[macro_export]
macro_rules! list_item {
($title:expr, $($x:expr),+ $(,)?) => (
$crate::widget::list_row!(
$crate::iced::widget::Text::new($title),
$crate::iced::widget::horizontal_space(
$crate::iced::Length::Fill
),
$($x),+
)
);
}
pub use list_item;
#[macro_export]
macro_rules! list_row {
($($x:expr),+ $(,)?) => (
$crate::iced::widget::Row::with_children(vec![
$($crate::iced::Element::from($x)),+
])
.align_items(Alignment::Center)
.padding([0, 8])
.spacing(12)
);
}
pub use list_row;
#[macro_export]
macro_rules! list_section {
($title:expr, $($x:expr),+ $(,)?) => (
$crate::iced::widget::Column::with_children(vec![
$crate::iced::widget::Text::new($title)
.font($crate::font::FONT_SEMIBOLD)
.into()
,
$crate::iced::widget::Container::new({
let mut children = vec![$($crate::iced::Element::from($x)),+];
//TODO: more efficient method for adding separators
let mut i = 1;
while i < children.len() {
children.insert(i, $crate::iced::widget::horizontal_rule(12).into());
i += 2;
}
$crate::iced::widget::Column::with_children(children)
.spacing(12)
})
.padding([12, 16])
.style(theme::Container::Custom(
$crate::widget::list_section_style
))
.into()
])
.spacing(8)
);
}
pub use list_section;
pub fn list_section_style(theme: &Theme) -> widget::container::Appearance {
let cosmic = &theme.cosmic().primary;
widget::container::Appearance {
text_color: Some(cosmic.on.into()),
background: Some(Background::Color(cosmic.base.into())),
border_radius: 8.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
}
#[macro_export]
macro_rules! list_view {
($($x:expr),+ $(,)?) => (
$crate::iced::widget::Column::with_children(
vec![$($crate::iced::Element::from($x)),+]
)
.spacing(24)
.padding(24)
.max_width(600)
);
}
pub use list_view;

View file

@ -7,17 +7,19 @@ use iced_native::layout::{Limits, Node};
use iced_native::overlay::from_children;
use iced_native::renderer::Style;
use iced_native::widget::{column, horizontal_rule, Operation, Tree};
use iced_native::{row, Clipboard, Element, Event, Layout, Shell, Widget, renderer, Background, Color};
use iced_native::{
renderer, row, Background, Clipboard, Color, Element, Event, Layout, Shell, Widget,
};
use iced_style::container::{Appearance, StyleSheet};
use iced_style::theme;
use iced_style::theme::Container;
#[derive(Setters)]
pub struct ListBox<'a, Message, Renderer>
where
Renderer: iced_native::Renderer,
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
<Renderer as iced_native::Renderer>::Theme: iced_style::rule::StyleSheet
where
Renderer: iced_native::Renderer,
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
<Renderer as iced_native::Renderer>::Theme: iced_style::rule::StyleSheet,
{
spacing: u16,
padding: Padding,
@ -32,11 +34,23 @@ pub struct ListBox<'a, Message, Renderer>
on_item_selected: Option<Box<dyn Fn(usize) -> Message + 'a>>,
}
pub fn list_box<'a, Message: 'a, Renderer>() -> ListBox<'a, Message, Renderer>
where
Renderer: iced_native::Renderer + 'a,
<<Renderer as iced_native::Renderer>::Theme as StyleSheet>::Style: From<Container>,
<Renderer as iced_native::Renderer>::Theme: StyleSheet + iced_style::rule::StyleSheet,
<<Renderer as iced_native::Renderer>::Theme as iced_style::rule::StyleSheet>::Style:
From<theme::Rule>,
{
ListBox::new()
}
impl<'a, Message: 'a, Renderer: iced_native::Renderer + 'a> ListBox<'a, Message, Renderer>
where
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
<<Renderer as iced_native::Renderer>::Theme as StyleSheet>::Style: From<Container>,
<<Renderer as iced_native::Renderer>::Theme as iced_style::rule::StyleSheet>::Style: From<theme::Rule>
<<Renderer as iced_native::Renderer>::Theme as iced_style::rule::StyleSheet>::Style:
From<theme::Rule>,
{
/// The default padding of a [`ListBox`] drawn by this renderer.
pub const DEFAULT_PADDING: u16 = 0;
@ -53,24 +67,20 @@ where
children: Vec<Element<'a, Message, Renderer>>,
show_separators: bool,
) -> Self {
let end = children.len() - 1;
let children_size = children.len();
let children: Vec<Element<Message, Renderer>> = children
.into_iter()
.enumerate()
.map(|(index, child)| {
let row_items = if show_separators && index != end {
let row_items = if show_separators && index != children_size - 1 {
vec![
row![child]
.align_items(Alignment::Center)
row![child].align_items(Alignment::Center).into(),
horizontal_rule(1)
.style(theme::Rule::Custom(separator_style))
.into(),
horizontal_rule(1).style(theme::Rule::Custom(separator_style)).into(),
]
} else {
vec![
row![child]
.align_items(Alignment::Center)
.into()
]
vec![row![child].align_items(Alignment::Center).into()]
};
column(row_items).into()
})
@ -101,7 +111,8 @@ impl<'a, Message: 'a, Renderer: iced_native::Renderer + 'a> std::default::Defaul
where
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
<<Renderer as iced_native::Renderer>::Theme as StyleSheet>::Style: From<Container>,
<<Renderer as iced_native::Renderer>::Theme as iced_style::rule::StyleSheet>::Style: From<theme::Rule>
<<Renderer as iced_native::Renderer>::Theme as iced_style::rule::StyleSheet>::Style:
From<theme::Rule>,
{
fn default() -> Self {
Self::new()
@ -111,7 +122,7 @@ where
impl<'a, Message, Renderer> Widget<Message, Renderer> for ListBox<'a, Message, Renderer>
where
Renderer: iced_native::Renderer,
<Renderer as iced_native::Renderer>::Theme: StyleSheet + iced_style::rule::StyleSheet
<Renderer as iced_native::Renderer>::Theme: StyleSheet + iced_style::rule::StyleSheet,
{
fn width(&self) -> Length {
self.width
@ -354,7 +365,8 @@ pub fn draw_background<Renderer>(
impl<'a, Message: 'a, Renderer: iced_native::Renderer + 'a> From<ListBox<'a, Message, Renderer>>
for Element<'a, Message, Renderer>
where <Renderer as iced_native::Renderer>::Theme: StyleSheet + iced_style::rule::StyleSheet
where
<Renderer as iced_native::Renderer>::Theme: StyleSheet + iced_style::rule::StyleSheet,
{
fn from(list_box: ListBox<'a, Message, Renderer>) -> Self {
Self::new(list_box)
@ -375,7 +387,7 @@ pub use list_box_item;
#[macro_export]
macro_rules! list_box_heading {
($title:expr) => (
($title:expr) => {
$crate::iced::widget::container(
$crate::iced::widget::row![
text($title).size(18),
@ -383,106 +395,54 @@ macro_rules! list_box_heading {
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center)
.align_items($crate::iced::alignment::Alignment::Center),
)
.style($crate::iced::theme::Container::Custom($crate::widget::expander_heading_style))
.style($crate::iced::theme::Container::Custom(
$crate::widget::expander_heading_style,
))
.max_height(60)
.padding(10)
);
($title:expr, $subtitle:expr) => (
};
($title:expr, $subtitle:expr) => {
$crate::iced::widget::container(
$crate::iced::widget::row![
column(
vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]
),
column(vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center)
.align_items($crate::iced::alignment::Alignment::Center),
)
.style($crate::iced::theme::Container::Custom($crate::widget::expander_heading_style))
.style($crate::iced::theme::Container::Custom(
$crate::widget::expander_heading_style,
))
.max_height(60)
.padding(10)
);
($title:expr, $subtitle:expr, $icon:expr) => (
};
($title:expr, $subtitle:expr, $icon:expr) => {
$crate::iced::widget::container(
$crate::iced::widget::row![
container($crate::widget::icon($icon, 20)).padding(10),
column(
vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]
),
column(vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center)
.align_items($crate::iced::alignment::Alignment::Center),
)
.style($crate::iced::theme::Container::Custom($crate::widget::expander_heading_style))
.style($crate::iced::theme::Container::Custom(
$crate::widget::expander_heading_style,
))
.max_height(60)
.padding(10)
);
};
}
pub use list_box_heading;
#[macro_export]
macro_rules! list_box_row {
($title:expr) => (
$crate::iced::widget::container(
$crate::iced::widget::row![
text($title).size(18),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center)
)
.max_height(60)
.padding(10)
);
($title:expr, $subtitle:expr) => (
$crate::iced::widget::container(
$crate::iced::widget::row![
column(
vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]
),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center)
)
.max_height(60)
.padding(10)
);
($title:expr, $subtitle:expr, $icon:expr) => (
$crate::iced::widget::container(
$crate::iced::widget::row![
container($crate::widget::icon($icon, 20)).padding(10),
column(
vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]
),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center)
)
.max_height(60)
.padding(10)
);
}
pub use list_box_row;
use crate::widget::separator_style;

View file

@ -0,0 +1,18 @@
use derive_setters::Setters;
#[derive(Setters, Default, Debug, Clone)]
pub struct ListRow<'a> {
pub(crate) title: &'a str,
#[setters(strip_option)]
pub subtitle: Option<&'a str>,
#[setters(strip_option)]
pub icon: Option<String>,
}
pub fn list_row<'a>() -> ListRow<'a> {
ListRow {
title: "",
subtitle: None,
icon: None,
}
}

145
src/widget/list/macros.rs Normal file
View file

@ -0,0 +1,145 @@
pub use iced::{widget, Background, Color, Theme};
pub mod list_view {
#[macro_export]
macro_rules! list_view {
($($x:expr),+ $(,)?) => (
$crate::iced::widget::Column::with_children(
vec![$($crate::iced::Element::from($x)),+]
)
.spacing(24)
.padding(24)
.max_width(600)
);
}
#[macro_export]
macro_rules! list_row {
($($x:expr),+ $(,)?) => (
$crate::iced::widget::Row::with_children(vec![
$($crate::iced::Element::from($x)),+
])
.align_items(Alignment::Center)
.padding([0, 8])
.spacing(12)
);
}
#[macro_export]
macro_rules! list_section {
($title:expr, $($x:expr),+ $(,)?) => (
$crate::iced::widget::Column::with_children(vec![
$crate::iced::widget::Text::new($title)
.font($crate::font::FONT_SEMIBOLD)
.into()
,
$crate::iced::widget::Container::new({
let mut children = vec![$($crate::iced::Element::from($x)),+];
//TODO: more efficient method for adding separators
let mut i = 1;
while i < children.len() {
children.insert(i, $crate::iced::widget::horizontal_rule(12).into());
i += 2;
}
$crate::iced::widget::Column::with_children(children)
.spacing(12)
})
.padding([12, 16])
.style(theme::Container::Custom(
list_section_style
))
.into()
])
.spacing(8)
);
}
#[macro_export]
macro_rules! list_item {
($title:expr, $($x:expr),+ $(,)?) => (
$crate::list_row!(
$crate::iced::widget::Text::new($title),
$crate::iced::widget::horizontal_space(
$crate::iced::Length::Fill
),
$($x),+
)
);
}
pub fn list_section_style(theme: &Theme) -> widget::container::Appearance {
let cosmic = &theme.cosmic().primary;
widget::container::Appearance {
text_color: Some(cosmic.on.into()),
background: Some(Background::Color(cosmic.base.into())),
border_radius: 8.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
}
use crate::widget::{Background, Color};
use iced::widget;
use iced_style::Theme;
pub use list_item;
pub use list_row;
pub use list_section;
pub use list_view;
}
pub mod list_box {
#[macro_export]
macro_rules! list_box_row {
($title:expr) => {
$crate::iced::widget::container(
$crate::iced::widget::row![
text($title).size(18),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center),
)
.max_height(60)
.padding(10)
};
($title:expr, $subtitle:expr) => {
$crate::iced::widget::container(
$crate::iced::widget::row![
column(vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center),
)
.max_height(60)
.padding(10)
};
($title:expr, $subtitle:expr, $icon:expr) => {
$crate::iced::widget::container(
$crate::iced::widget::row![
container($crate::widget::icon($icon, 20)).padding(10),
column(vec![
text($title).size(18).into(),
text($subtitle).size(16).into(),
]),
$crate::iced::widget::vertical_space(Length::Fill),
$crate::iced::widget::horizontal_space(Length::Fill)
]
.height(Length::Fill)
.align_items($crate::iced::alignment::Alignment::Center),
)
.max_height(60)
.padding(10)
};
}
pub use list_box_row;
}

8
src/widget/list/mod.rs Normal file
View file

@ -0,0 +1,8 @@
pub mod macros;
pub use macros::*;
pub mod list_row;
pub use list_row::*;
pub mod list_box;
pub use list_box::*;

View file

@ -7,14 +7,8 @@ pub use header_bar::*;
mod icon;
pub use self::icon::*;
mod list;
pub use list::*;
mod nav;
pub use nav::*;
mod navbar;
pub use navbar::*;
pub mod navigation;
pub use navigation::*;
mod toggler;
pub use toggler::*;
@ -25,5 +19,5 @@ pub use scrollable::*;
mod expander;
pub use expander::*;
pub mod list_box;
pub use list_box::*;
pub mod list;
pub use list::*;

View file

@ -1,52 +0,0 @@
use iced::{widget, Background, Color, Theme};
#[macro_export]
macro_rules! nav_bar {
($($x:expr),+ $(,)?) => (
$crate::iced::widget::Container::new(
$crate::scrollable!(
$crate::iced::widget::row![
$crate::iced::widget::Column::with_children(
vec![$($crate::iced::Element::from($x)),+]
)
.spacing(12)
.padding(12),
]
)
)
.max_width(300)
.padding(12)
.height(Length::Fill)
.style(theme::Container::Custom(
$crate::widget::nav_bar_style
))
);
}
pub use nav_bar;
pub fn nav_bar_style(theme: &Theme) -> widget::container::Appearance {
let cosmic = &theme.cosmic().primary;
widget::container::Appearance {
text_color: Some(cosmic.on.into()),
background: Some(Background::Color(cosmic.base.into())),
border_radius: 8.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
}
#[macro_export]
macro_rules! nav_button {
($icon: expr, $title:expr, $condensed:expr) => {{
if $condensed {
$crate::iced::widget::Button::new($crate::widget::icon($icon, 22)).padding(8)
} else {
$crate::widget::button!(
$crate::widget::icon($icon, 22),
$crate::iced::widget::Text::new($title),
$crate::iced::widget::horizontal_space($crate::iced::Length::Fill),
)
}
}};
}
pub use nav_button;

View file

@ -0,0 +1,31 @@
pub mod nav_bar {
use iced::{widget, Background, Color, Theme};
#[macro_export]
macro_rules! nav_button {
($icon: expr, $title:expr, $condensed:expr) => {{
if $condensed {
$crate::iced::widget::Button::new($crate::widget::icon($icon, 22)).padding(8)
} else {
$crate::widget::button!(
$crate::widget::icon($icon, 22),
$crate::iced::widget::Text::new($title),
$crate::iced::widget::horizontal_space($crate::iced::Length::Fill),
)
}
}};
}
pub fn nav_bar_style(theme: &Theme) -> widget::container::Appearance {
let cosmic = &theme.cosmic().primary;
widget::container::Appearance {
text_color: Some(cosmic.on.into()),
background: Some(Background::Color(cosmic.base.into())),
border_radius: 8.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
}
pub use nav_button;
}

View file

@ -0,0 +1,5 @@
pub mod navbar;
pub use navbar::*;
pub mod macros;
pub use macros::*;