Changed the file structure
This commit is contained in:
parent
bd9b3bff25
commit
e3bc7e1545
22 changed files with 409 additions and 395 deletions
|
|
@ -7,6 +7,6 @@ pub fn main() -> cosmic::iced::Result {
|
||||||
let mut settings = settings();
|
let mut settings = settings();
|
||||||
settings.window.min_size = Some((600, 300));
|
settings.window.min_size = Some((600, 300));
|
||||||
// TODO: Window resize handles not functioning yet
|
// TODO: Window resize handles not functioning yet
|
||||||
// settings.window.decorations = false;
|
settings.window.decorations = false;
|
||||||
Window::run(settings)
|
Window::run(settings)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use cosmic::widget::{expander, expander_row, list_section_style, ListBox};
|
use cosmic::widget::{expander, ListBox};
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced::widget::{
|
iced::widget::{
|
||||||
checkbox, column, container, horizontal_space, pick_list, progress_bar, radio, row, slider,
|
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::{self, theme, Alignment, Application, Color, Command, Element, Length, Theme},
|
||||||
iced_lazy::responsive,
|
iced_lazy::responsive,
|
||||||
iced_winit::window::{drag, maximize, minimize},
|
iced_winit::window::{drag, maximize, minimize},
|
||||||
scrollable,
|
list_item, list_row, list_section, list_view, nav_button, scrollable,
|
||||||
widget::{
|
widget::{button, header_bar, list_row, list_view::*, nav_bar::nav_bar_style, toggler},
|
||||||
button, header_bar, list_item, list_row, list_section, list_view, nav_bar_style,
|
|
||||||
nav_button, toggler,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -77,6 +74,7 @@ impl Application for Window {
|
||||||
.show_maximize(true)
|
.show_maximize(true)
|
||||||
.show_minimize(true);
|
.show_minimize(true);
|
||||||
window.slider_value = 50.0;
|
window.slider_value = 50.0;
|
||||||
|
// window.theme = Theme::Light;
|
||||||
window.pick_list_selected = Some("Option 1");
|
window.pick_list_selected = Some("Option 1");
|
||||||
(window, Command::none())
|
(window, Command::none())
|
||||||
}
|
}
|
||||||
|
|
@ -109,6 +107,7 @@ impl Application for Window {
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
let mut header: Element<Message, _> = header_bar()
|
let mut header: Element<Message, _> = header_bar()
|
||||||
.title(self.title())
|
.title(self.title())
|
||||||
|
.nav_title(String::from("Settings"))
|
||||||
.sidebar_active(self.sidebar_toggled)
|
.sidebar_active(self.sidebar_toggled)
|
||||||
.show_minimize(self.show_minimize)
|
.show_minimize(self.show_minimize)
|
||||||
.show_maximize(self.show_maximize)
|
.show_maximize(self.show_maximize)
|
||||||
|
|
@ -240,12 +239,12 @@ impl Application for Window {
|
||||||
.icon(String::from("edit-paste"))
|
.icon(String::from("edit-paste"))
|
||||||
.on_row_selected(Box::new(Message::RowSelected))
|
.on_row_selected(Box::new(Message::RowSelected))
|
||||||
.rows(vec![
|
.rows(vec![
|
||||||
expander_row()
|
list_row()
|
||||||
.title("Label")
|
.title("Label")
|
||||||
.subtitle("Caption")
|
.subtitle("Caption")
|
||||||
.icon(String::from("help-about")),
|
.icon(String::from("help-about")),
|
||||||
expander_row().subtitle("Caption").title("Label"),
|
list_row().subtitle("Caption").title("Label"),
|
||||||
expander_row().title("Label")
|
list_row().title("Label")
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
list_section!(
|
list_section!(
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ impl<'a> TextBuffer<'a> {
|
||||||
|
|
||||||
let mut reshaped = 0;
|
let mut reshaped = 0;
|
||||||
while self.shape_lines.len() < self.text_lines.len()
|
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());
|
let line_i = FontLineIndex::new(self.shape_lines.len());
|
||||||
self.reshape_line(line_i);
|
self.reshape_line(line_i);
|
||||||
|
|
@ -74,7 +74,9 @@ impl<'a> TextBuffer<'a> {
|
||||||
pub fn reshape_line(&mut self, line_i: FontLineIndex) {
|
pub fn reshape_line(&mut self, line_i: FontLineIndex) {
|
||||||
let instant = Instant::now();
|
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() {
|
if line_i.get() < self.shape_lines.len() {
|
||||||
self.shape_lines[line_i.get()] = shape_line;
|
self.shape_lines[line_i.get()] = shape_line;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -131,7 +133,7 @@ impl<'a> TextBuffer<'a> {
|
||||||
self.font_size,
|
self.font_size,
|
||||||
self.line_width,
|
self.line_width,
|
||||||
&mut self.layout_lines,
|
&mut self.layout_lines,
|
||||||
insert_i
|
insert_i,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.redraw = true;
|
self.redraw = true;
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ impl<'a> FontLayoutLine<'a> {
|
||||||
|
|
||||||
// Compute the fractional offset-- you'll likely want to quantize this
|
// Compute the fractional offset-- you'll likely want to quantize this
|
||||||
// in a real renderer
|
// 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
|
// Select our source order
|
||||||
Render::new(&[
|
Render::new(&[
|
||||||
|
|
@ -77,12 +78,12 @@ impl<'a> FontLayoutLine<'a> {
|
||||||
// Standard scalable outline
|
// Standard scalable outline
|
||||||
Source::Outline,
|
Source::Outline,
|
||||||
])
|
])
|
||||||
// Select a subpixel format
|
// Select a subpixel format
|
||||||
.format(Format::Alpha)
|
.format(Format::Alpha)
|
||||||
// Apply the fractional offset
|
// Apply the fractional offset
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
// Render the image
|
// Render the image
|
||||||
.render(&mut scaler, cache_key.glyph_id)
|
.render(&mut scaler, cache_key.glyph_id)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ref image) = image_opt {
|
if let Some(ref image) = image_opt {
|
||||||
|
|
@ -96,28 +97,25 @@ impl<'a> FontLayoutLine<'a> {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for off_y in 0..image.placement.height as i32 {
|
for off_y in 0..image.placement.height as i32 {
|
||||||
for off_x in 0..image.placement.width as i32 {
|
for off_x in 0..image.placement.width as i32 {
|
||||||
let color =
|
let color = (image.data[i] as u32) << 24 | base & 0xFFFFFF;
|
||||||
(image.data[i] as u32) << 24 |
|
|
||||||
base & 0xFFFFFF;
|
|
||||||
f(x + off_x, y + off_y, color);
|
f(x + off_x, y + off_y, color);
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Content::Color => {
|
Content::Color => {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for off_y in 0..image.placement.height as i32 {
|
for off_y in 0..image.placement.height as i32 {
|
||||||
for off_x in 0..image.placement.width as i32 {
|
for off_x in 0..image.placement.width as i32 {
|
||||||
let color =
|
let color = (image.data[i + 3] as u32) << 24
|
||||||
(image.data[i + 3] as u32) << 24 |
|
| (image.data[i] as u32) << 16
|
||||||
(image.data[i] as u32) << 16 |
|
| (image.data[i + 1] as u32) << 8
|
||||||
(image.data[i + 1] as u32) << 8 |
|
| (image.data[i + 2] as u32);
|
||||||
(image.data[i + 2] as u32);
|
|
||||||
f(x + off_x, y + off_y, color);
|
f(x + off_x, y + off_y, color);
|
||||||
i += 4;
|
i += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Content::SubpixelMask => {
|
Content::SubpixelMask => {
|
||||||
println!("TODO: SubpixelMask");
|
println!("TODO: SubpixelMask");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,15 @@ pub struct FontMatches<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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 word = &line[start_word..end_word];
|
||||||
|
|
||||||
let font_scale = self.fonts[font_i].rustybuzz.units_per_em() as f32;
|
let font_scale = self.fonts[font_i].rustybuzz.units_per_em() as f32;
|
||||||
|
|
@ -101,15 +109,24 @@ impl<'a> FontMatches<'a> {
|
||||||
(glyphs, missing)
|
(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 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!
|
//TODO: improve performance!
|
||||||
font_i += 1;
|
font_i += 1;
|
||||||
while !missing.is_empty() && font_i < self.fonts.len() {
|
while !missing.is_empty() && font_i < self.fonts.len() {
|
||||||
// println!("Evaluating fallback with font {}", font_i);
|
// 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
|
// Insert all matching glyphs
|
||||||
let mut fb_i = 0;
|
let mut fb_i = 0;
|
||||||
|
|
@ -187,7 +204,11 @@ impl<'a> FontMatches<'a> {
|
||||||
) -> FontShapeSpan {
|
) -> FontShapeSpan {
|
||||||
let span = &line[start_span..end_span];
|
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();
|
let mut words = Vec::new();
|
||||||
|
|
||||||
|
|
@ -202,10 +223,22 @@ impl<'a> FontMatches<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if start_word < start_lb {
|
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 {
|
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;
|
start_word = end_lb;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
use std::{
|
use std::{collections::HashMap, sync::Mutex};
|
||||||
collections::HashMap,
|
|
||||||
sync::Mutex,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use self::cache::*;
|
pub use self::cache::*;
|
||||||
mod cache;
|
mod cache;
|
||||||
|
|
@ -21,7 +18,6 @@ mod system;
|
||||||
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct FontCacheKey {
|
pub struct FontCacheKey {
|
||||||
glyph_id: u16,
|
glyph_id: u16,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
|
|
|
||||||
|
|
@ -26,27 +26,24 @@ impl<'a> FontShapeGlyph<'a> {
|
||||||
let x_advance = font_size as f32 * self.x_advance;
|
let x_advance = font_size as f32 * self.x_advance;
|
||||||
|
|
||||||
#[cfg(feature = "ab_glyph")]
|
#[cfg(feature = "ab_glyph")]
|
||||||
let inner = self.font.ab_glyph.outline_glyph(
|
let inner = self
|
||||||
self.inner.with_scale_and_position(
|
.font
|
||||||
|
.ab_glyph
|
||||||
|
.outline_glyph(self.inner.with_scale_and_position(
|
||||||
font_size as f32,
|
font_size as f32,
|
||||||
ab_glyph::point(
|
ab_glyph::point(x + x_offset, y - y_offset),
|
||||||
x + x_offset,
|
));
|
||||||
y - y_offset,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(feature = "rusttype")]
|
#[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))
|
.scaled(rusttype::Scale::uniform(font_size as f32))
|
||||||
.positioned(rusttype::point(x + x_offset, y - y_offset));
|
.positioned(rusttype::point(x + x_offset, y - y_offset));
|
||||||
|
|
||||||
#[cfg(feature = "swash")]
|
#[cfg(feature = "swash")]
|
||||||
let inner = CacheKey::new(
|
let inner = CacheKey::new(self.inner, font_size, (x + x_offset, y - y_offset));
|
||||||
self.inner,
|
|
||||||
font_size,
|
|
||||||
(x + x_offset, y - y_offset),
|
|
||||||
);
|
|
||||||
|
|
||||||
FontLayoutGlyph {
|
FontLayoutGlyph {
|
||||||
start: self.start,
|
start: self.start,
|
||||||
|
|
|
||||||
|
|
@ -30,31 +30,28 @@ impl FontSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self { db }
|
||||||
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();
|
let mut fonts = Vec::new();
|
||||||
for face in self.db.faces() {
|
for face in self.db.faces() {
|
||||||
if ! f(face) {
|
if !f(face) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let font_opt = Font::new(
|
let font_opt = Font::new(
|
||||||
&face.post_script_name,
|
&face.post_script_name,
|
||||||
match &face.source {
|
match &face.source {
|
||||||
fontdb::Source::Binary(data) => {
|
fontdb::Source::Binary(data) => data.deref().as_ref(),
|
||||||
data.deref().as_ref()
|
|
||||||
},
|
|
||||||
fontdb::Source::File(path) => {
|
fontdb::Source::File(path) => {
|
||||||
println!("Unsupported fontdb Source::File('{}')", path.display());
|
println!("Unsupported fontdb Source::File('{}')", path.display());
|
||||||
continue;
|
continue;
|
||||||
},
|
}
|
||||||
fontdb::Source::SharedFile(_path, data) => {
|
fontdb::Source::SharedFile(_path, data) => data.deref().as_ref(),
|
||||||
data.deref().as_ref()
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
face.index,
|
face.index,
|
||||||
);
|
);
|
||||||
|
|
@ -67,10 +64,8 @@ impl FontSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ! fonts.is_empty() {
|
if !fonts.is_empty() {
|
||||||
Some(FontMatches {
|
Some(FontMatches { fonts })
|
||||||
fonts
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,6 @@
|
||||||
use orbclient::{Color, EventOption, Renderer, Window, WindowFlag};
|
use orbclient::{Color, EventOption, Renderer, Window, WindowFlag};
|
||||||
use std::{
|
use std::{cmp, env, fs, time::Instant};
|
||||||
cmp,
|
use text::{FontLineIndex, FontSystem, TextAction, TextBuffer, TextCursor};
|
||||||
env,
|
|
||||||
fs,
|
|
||||||
time::Instant,
|
|
||||||
};
|
|
||||||
use text::{
|
|
||||||
FontLineIndex,
|
|
||||||
FontSystem,
|
|
||||||
TextAction,
|
|
||||||
TextCursor,
|
|
||||||
TextBuffer,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let display_scale = match orbclient::get_display_size() {
|
let display_scale = match orbclient::get_display_size() {
|
||||||
|
|
@ -112,10 +101,13 @@ fn main() {
|
||||||
|
|
||||||
buffer.shape_until(scroll + window_lines);
|
buffer.shape_until(scroll + window_lines);
|
||||||
|
|
||||||
scroll = cmp::max(0, cmp::min(
|
scroll = cmp::max(
|
||||||
buffer.layout_lines().len() as i32 - (window_lines - 1),
|
0,
|
||||||
scroll
|
cmp::min(
|
||||||
));
|
buffer.layout_lines().len() as i32 - (window_lines - 1),
|
||||||
|
scroll,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if rehit {
|
if rehit {
|
||||||
let instant = Instant::now();
|
let instant = Instant::now();
|
||||||
|
|
@ -173,7 +165,12 @@ fn main() {
|
||||||
let mut line_y = line_height;
|
let mut line_y = line_height;
|
||||||
let mut start_line_opt = None;
|
let mut start_line_opt = None;
|
||||||
let mut end_line = FontLineIndex::new(0);
|
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 {
|
if line_y >= window.height() as i32 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +233,7 @@ fn main() {
|
||||||
start_y as i32,
|
start_y as i32,
|
||||||
line_x as u32,
|
line_x as u32,
|
||||||
(end_y - start_y) 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() {
|
for event in window.events() {
|
||||||
match event.to_option() {
|
match event.to_option() {
|
||||||
EventOption::Key(event) => {
|
EventOption::Key(event) => match event.scancode {
|
||||||
match event.scancode {
|
orbclient::K_CTRL => ctrl_pressed = event.pressed,
|
||||||
orbclient::K_CTRL => ctrl_pressed = event.pressed,
|
orbclient::K_LEFT if event.pressed => buffer.action(TextAction::Left),
|
||||||
orbclient::K_LEFT if event.pressed => buffer.action(TextAction::Left),
|
orbclient::K_RIGHT if event.pressed => buffer.action(TextAction::Right),
|
||||||
orbclient::K_RIGHT if event.pressed => buffer.action(TextAction::Right),
|
orbclient::K_UP if event.pressed => buffer.action(TextAction::Up),
|
||||||
orbclient::K_UP if event.pressed => buffer.action(TextAction::Up),
|
orbclient::K_DOWN if event.pressed => buffer.action(TextAction::Down),
|
||||||
orbclient::K_DOWN if event.pressed => buffer.action(TextAction::Down),
|
orbclient::K_BKSP if event.pressed => buffer.action(TextAction::Backspace),
|
||||||
orbclient::K_BKSP if event.pressed => buffer.action(TextAction::Backspace),
|
orbclient::K_DEL if event.pressed => buffer.action(TextAction::Delete),
|
||||||
orbclient::K_DEL if event.pressed => buffer.action(TextAction::Delete),
|
orbclient::K_PGUP if event.pressed => {
|
||||||
orbclient::K_PGUP if event.pressed => {
|
scroll -= window_lines;
|
||||||
scroll -= window_lines;
|
buffer.redraw = true;
|
||||||
buffer.redraw = true;
|
}
|
||||||
},
|
orbclient::K_PGDN if event.pressed => {
|
||||||
orbclient::K_PGDN if event.pressed => {
|
scroll += window_lines;
|
||||||
scroll += window_lines;
|
buffer.redraw = true;
|
||||||
buffer.redraw = true;
|
}
|
||||||
},
|
orbclient::K_0 if event.pressed && ctrl_pressed => {
|
||||||
orbclient::K_0 if event.pressed && ctrl_pressed => {
|
font_size_i = font_size_default;
|
||||||
font_size_i = font_size_default;
|
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
||||||
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
}
|
||||||
},
|
orbclient::K_MINUS if event.pressed && ctrl_pressed => {
|
||||||
orbclient::K_MINUS if event.pressed && ctrl_pressed => if font_size_i > 0 {
|
if font_size_i > 0 {
|
||||||
font_size_i -= 1;
|
font_size_i -= 1;
|
||||||
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
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 => {
|
EventOption::TextInput(event) if !ctrl_pressed => {
|
||||||
buffer.action(TextAction::Insert(event.character));
|
buffer.action(TextAction::Insert(event.character));
|
||||||
|
|
|
||||||
|
|
@ -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]
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fn main() {
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
use crate::list_box_row;
|
use crate::{list_box_row, widget::ListRow};
|
||||||
use apply::Apply;
|
use apply::Apply;
|
||||||
use derive_setters::Setters;
|
use derive_setters::Setters;
|
||||||
use iced::{
|
use iced::{
|
||||||
|
|
@ -20,7 +20,7 @@ pub struct Expander<'a, Message> {
|
||||||
icon: Option<String>,
|
icon: Option<String>,
|
||||||
expansible: bool,
|
expansible: bool,
|
||||||
#[setters(skip)]
|
#[setters(skip)]
|
||||||
rows: Option<Vec<ExpanderRow<'a>>>,
|
rows: Option<Vec<ListRow<'a>>>,
|
||||||
#[setters(strip_option)]
|
#[setters(strip_option)]
|
||||||
on_row_selected: Option<Box<dyn Fn(usize) -> Message + 'a>>,
|
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 struct ExpanderState {
|
||||||
pub expanded: bool,
|
pub expanded: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -70,13 +53,13 @@ pub enum ExpanderEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message> Expander<'a, Message> {
|
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.rows = Some(rows);
|
||||||
self.expansible = true;
|
self.expansible = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, row: ExpanderRow<'a>) {
|
pub fn push(&mut self, row: ListRow<'a>) {
|
||||||
if self.rows.is_none() {
|
if self.rows.is_none() {
|
||||||
self.rows = Some(vec![])
|
self.rows = Some(vec![])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
|
|
@ -7,17 +7,19 @@ use iced_native::layout::{Limits, Node};
|
||||||
use iced_native::overlay::from_children;
|
use iced_native::overlay::from_children;
|
||||||
use iced_native::renderer::Style;
|
use iced_native::renderer::Style;
|
||||||
use iced_native::widget::{column, horizontal_rule, Operation, Tree};
|
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::container::{Appearance, StyleSheet};
|
||||||
use iced_style::theme;
|
use iced_style::theme;
|
||||||
use iced_style::theme::Container;
|
use iced_style::theme::Container;
|
||||||
|
|
||||||
#[derive(Setters)]
|
#[derive(Setters)]
|
||||||
pub struct ListBox<'a, Message, Renderer>
|
pub struct ListBox<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: iced_native::Renderer,
|
Renderer: iced_native::Renderer,
|
||||||
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
|
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
|
||||||
<Renderer as iced_native::Renderer>::Theme: iced_style::rule::StyleSheet
|
<Renderer as iced_native::Renderer>::Theme: iced_style::rule::StyleSheet,
|
||||||
{
|
{
|
||||||
spacing: u16,
|
spacing: u16,
|
||||||
padding: Padding,
|
padding: Padding,
|
||||||
|
|
@ -32,11 +34,23 @@ pub struct ListBox<'a, Message, Renderer>
|
||||||
on_item_selected: Option<Box<dyn Fn(usize) -> Message + 'a>>,
|
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>
|
impl<'a, Message: 'a, Renderer: iced_native::Renderer + 'a> ListBox<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
|
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 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.
|
/// The default padding of a [`ListBox`] drawn by this renderer.
|
||||||
pub const DEFAULT_PADDING: u16 = 0;
|
pub const DEFAULT_PADDING: u16 = 0;
|
||||||
|
|
@ -53,24 +67,20 @@ where
|
||||||
children: Vec<Element<'a, Message, Renderer>>,
|
children: Vec<Element<'a, Message, Renderer>>,
|
||||||
show_separators: bool,
|
show_separators: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let end = children.len() - 1;
|
let children_size = children.len();
|
||||||
let children: Vec<Element<Message, Renderer>> = children
|
let children: Vec<Element<Message, Renderer>> = children
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, child)| {
|
.map(|(index, child)| {
|
||||||
let row_items = if show_separators && index != end {
|
let row_items = if show_separators && index != children_size - 1 {
|
||||||
vec![
|
vec![
|
||||||
row![child]
|
row![child].align_items(Alignment::Center).into(),
|
||||||
.align_items(Alignment::Center)
|
horizontal_rule(1)
|
||||||
|
.style(theme::Rule::Custom(separator_style))
|
||||||
.into(),
|
.into(),
|
||||||
horizontal_rule(1).style(theme::Rule::Custom(separator_style)).into(),
|
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
vec![
|
vec![row![child].align_items(Alignment::Center).into()]
|
||||||
row![child]
|
|
||||||
.align_items(Alignment::Center)
|
|
||||||
.into()
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
column(row_items).into()
|
column(row_items).into()
|
||||||
})
|
})
|
||||||
|
|
@ -101,7 +111,8 @@ impl<'a, Message: 'a, Renderer: iced_native::Renderer + 'a> std::default::Defaul
|
||||||
where
|
where
|
||||||
Renderer::Theme: StyleSheet + iced_style::rule::StyleSheet,
|
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 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 {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
|
|
@ -111,7 +122,7 @@ where
|
||||||
impl<'a, Message, Renderer> Widget<Message, Renderer> for ListBox<'a, Message, Renderer>
|
impl<'a, Message, Renderer> Widget<Message, Renderer> for ListBox<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: iced_native::Renderer,
|
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 {
|
fn width(&self) -> Length {
|
||||||
self.width
|
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>>
|
impl<'a, Message: 'a, Renderer: iced_native::Renderer + 'a> From<ListBox<'a, Message, Renderer>>
|
||||||
for Element<'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 {
|
fn from(list_box: ListBox<'a, Message, Renderer>) -> Self {
|
||||||
Self::new(list_box)
|
Self::new(list_box)
|
||||||
|
|
@ -375,7 +387,7 @@ pub use list_box_item;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! list_box_heading {
|
macro_rules! list_box_heading {
|
||||||
($title:expr) => (
|
($title:expr) => {
|
||||||
$crate::iced::widget::container(
|
$crate::iced::widget::container(
|
||||||
$crate::iced::widget::row![
|
$crate::iced::widget::row![
|
||||||
text($title).size(18),
|
text($title).size(18),
|
||||||
|
|
@ -383,106 +395,54 @@ macro_rules! list_box_heading {
|
||||||
$crate::iced::widget::horizontal_space(Length::Fill)
|
$crate::iced::widget::horizontal_space(Length::Fill)
|
||||||
]
|
]
|
||||||
.height(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)
|
.max_height(60)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
);
|
};
|
||||||
($title:expr, $subtitle:expr) => (
|
($title:expr, $subtitle:expr) => {
|
||||||
$crate::iced::widget::container(
|
$crate::iced::widget::container(
|
||||||
$crate::iced::widget::row![
|
$crate::iced::widget::row![
|
||||||
column(
|
column(vec![
|
||||||
vec![
|
text($title).size(18).into(),
|
||||||
text($title).size(18).into(),
|
text($subtitle).size(16).into(),
|
||||||
text($subtitle).size(16).into(),
|
]),
|
||||||
]
|
|
||||||
),
|
|
||||||
$crate::iced::widget::vertical_space(Length::Fill),
|
$crate::iced::widget::vertical_space(Length::Fill),
|
||||||
$crate::iced::widget::horizontal_space(Length::Fill)
|
$crate::iced::widget::horizontal_space(Length::Fill)
|
||||||
]
|
]
|
||||||
.height(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)
|
.max_height(60)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
);
|
};
|
||||||
($title:expr, $subtitle:expr, $icon:expr) => (
|
($title:expr, $subtitle:expr, $icon:expr) => {
|
||||||
$crate::iced::widget::container(
|
$crate::iced::widget::container(
|
||||||
$crate::iced::widget::row![
|
$crate::iced::widget::row![
|
||||||
container($crate::widget::icon($icon, 20)).padding(10),
|
container($crate::widget::icon($icon, 20)).padding(10),
|
||||||
column(
|
column(vec![
|
||||||
vec![
|
text($title).size(18).into(),
|
||||||
text($title).size(18).into(),
|
text($subtitle).size(16).into(),
|
||||||
text($subtitle).size(16).into(),
|
]),
|
||||||
]
|
|
||||||
),
|
|
||||||
$crate::iced::widget::vertical_space(Length::Fill),
|
$crate::iced::widget::vertical_space(Length::Fill),
|
||||||
$crate::iced::widget::horizontal_space(Length::Fill)
|
$crate::iced::widget::horizontal_space(Length::Fill)
|
||||||
]
|
]
|
||||||
.height(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)
|
.max_height(60)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
);
|
};
|
||||||
}
|
}
|
||||||
pub use list_box_heading;
|
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;
|
use crate::widget::separator_style;
|
||||||
18
src/widget/list/list_row.rs
Normal file
18
src/widget/list/list_row.rs
Normal 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
145
src/widget/list/macros.rs
Normal 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
8
src/widget/list/mod.rs
Normal 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::*;
|
||||||
|
|
@ -7,14 +7,8 @@ pub use header_bar::*;
|
||||||
mod icon;
|
mod icon;
|
||||||
pub use self::icon::*;
|
pub use self::icon::*;
|
||||||
|
|
||||||
mod list;
|
pub mod navigation;
|
||||||
pub use list::*;
|
pub use navigation::*;
|
||||||
|
|
||||||
mod nav;
|
|
||||||
pub use nav::*;
|
|
||||||
|
|
||||||
mod navbar;
|
|
||||||
pub use navbar::*;
|
|
||||||
|
|
||||||
mod toggler;
|
mod toggler;
|
||||||
pub use toggler::*;
|
pub use toggler::*;
|
||||||
|
|
@ -25,5 +19,5 @@ pub use scrollable::*;
|
||||||
mod expander;
|
mod expander;
|
||||||
pub use expander::*;
|
pub use expander::*;
|
||||||
|
|
||||||
pub mod list_box;
|
pub mod list;
|
||||||
pub use list_box::*;
|
pub use list::*;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
31
src/widget/navigation/macros.rs
Normal file
31
src/widget/navigation/macros.rs
Normal 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;
|
||||||
|
}
|
||||||
5
src/widget/navigation/mod.rs
Normal file
5
src/widget/navigation/mod.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod navbar;
|
||||||
|
pub use navbar::*;
|
||||||
|
|
||||||
|
pub mod macros;
|
||||||
|
pub use macros::*;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue