Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal custom themes implementation #330

Merged
merged 22 commits into from Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2d00141
Define palette extension structs.
joshuamegnauth54 Jul 31, 2023
54b4abf
Draft out skeleton for minimal custom themes.
joshuamegnauth54 Jul 31, 2023
3efdceb
Add `Dracula` as an example theme to test.
joshuamegnauth54 Aug 1, 2023
5e333e3
Automatically append custom styles to settings.
joshuamegnauth54 Aug 2, 2023
2044602
Add gruvbox.
joshuamegnauth54 Aug 3, 2023
5722964
Fix deserializing `StyleType::Custom`.
joshuamegnauth54 Aug 3, 2023
474aaeb
Merge remote-tracking branch 'upstream/main' into custom_themes_minimal
joshuamegnauth54 Aug 4, 2023
e1a1c7f
Add style Solarized light.
joshuamegnauth54 Aug 4, 2023
5386d87
improvements to style settings page layout
GyulyVGC Aug 4, 2023
dd3f5ac
format files and fix lints
GyulyVGC Aug 4, 2023
85a6596
use StyleType::is_nightly to determine font weights
GyulyVGC Aug 4, 2023
b165fcd
fix tests
GyulyVGC Aug 4, 2023
306c46d
Add style Solarized dark.
joshuamegnauth54 Aug 5, 2023
d677171
Add Nord and update solarized.
joshuamegnauth54 Aug 5, 2023
2a4ca7f
improvements to overall palettes structure and colors
GyulyVGC Aug 5, 2023
09deb57
Add Nord (Day) as a light theme.
joshuamegnauth54 Aug 6, 2023
5004407
Add Gruvbox light.
joshuamegnauth54 Aug 6, 2023
a344376
fixed highlighted text and minor palettes improvements
GyulyVGC Aug 6, 2023
ff0c702
Add a light variation of Dracula.
joshuamegnauth54 Aug 7, 2023
32ec19f
fix Dracula Light palette
GyulyVGC Aug 7, 2023
66f1b8d
refactoring
GyulyVGC Aug 7, 2023
0b56a2a
some more refactoring
GyulyVGC Aug 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/chart/manage_chart_data.rs
Expand Up @@ -84,7 +84,7 @@ mod tests {
use std::collections::VecDeque;

use crate::chart::manage_chart_data::{get_max, get_min, update_charts_data};
use crate::{ChartType, RunTimeData, TrafficChart};
use crate::{ChartType, Language, RunTimeData, StyleType, TrafficChart};

#[test]
fn test_chart_data_updates() {
Expand Down Expand Up @@ -162,12 +162,9 @@ mod tests {
max_received_bytes: 21000,
min_sent_packets: -1000,
max_received_packets: 21000,
color_mix: 0.0,
color_incoming: Default::default(),
color_outgoing: Default::default(),
color_font: Default::default(),
language: Language::default(),
chart_type: ChartType::Packets,
language: Default::default(),
style: StyleType::default(),
};
let mut runtime_data = RunTimeData {
all_bytes: 0,
Expand Down
57 changes: 27 additions & 30 deletions src/chart/types/traffic_chart.rs
Expand Up @@ -5,10 +5,9 @@ use std::collections::VecDeque;
use iced::alignment::{Horizontal, Vertical};
use iced::widget::{Column, Container};
use iced::Element;
use plotters::style::RGBColor;
use plotters_iced::{Chart, ChartBuilder, ChartWidget, DrawingBackend};

use crate::gui::styles::style_constants::{get_color_mix_chart, CHARTS_LINE_BORDER};
use crate::gui::styles::style_constants::{get_alpha_chart_badge, CHARTS_LINE_BORDER};
use crate::gui::styles::types::palette::to_rgb_color;
use crate::gui::types::message::Message;
use crate::translations::translations::{incoming_translation, outgoing_translation};
Expand All @@ -35,12 +34,12 @@ pub struct TrafficChart {
pub min_sent_packets: i64,
/// Minimum number of received packets per time interval (computed on last 30 intervals)
pub max_received_packets: i64,
pub color_mix: f64,
pub color_incoming: RGBColor,
pub color_outgoing: RGBColor,
pub color_font: RGBColor,
pub chart_type: ChartType,
/// Language used for the chart legend
pub language: Language,
/// Packets or bytes
pub chart_type: ChartType,
/// Style of the chart
pub style: StyleType,
}

impl TrafficChart {
Expand All @@ -55,12 +54,9 @@ impl TrafficChart {
max_received_bytes: 0,
min_sent_packets: 0,
max_received_packets: 0,
color_mix: get_color_mix_chart(style),
color_incoming: to_rgb_color(get_colors(style).secondary),
color_outgoing: to_rgb_color(get_colors(style).outgoing),
color_font: to_rgb_color(get_colors(style).text_body),
chart_type: ChartType::Bytes,
language,
chart_type: ChartType::Bytes,
style,
}
}

Expand All @@ -79,11 +75,8 @@ impl TrafficChart {
self.language = language;
}

pub fn change_colors(&mut self, style: StyleType) {
self.color_font = to_rgb_color(get_colors(style).text_body);
self.color_incoming = to_rgb_color(get_colors(style).secondary);
self.color_outgoing = to_rgb_color(get_colors(style).outgoing);
self.color_mix = get_color_mix_chart(style);
pub fn change_style(&mut self, style: StyleType) {
self.style = style;
}
}

Expand All @@ -97,9 +90,10 @@ impl Chart<Message> for TrafficChart {
) {
use plotters::prelude::*;

let font_weight = match self.color_font {
RGBColor(255, 255, 255) => FontStyle::Normal, // if white non-bold
_ => FontStyle::Bold,
let font_weight = if self.style.is_nightly() {
FontStyle::Normal
} else {
FontStyle::Bold
};

if self.ticks == 0 {
Expand All @@ -108,8 +102,11 @@ impl Chart<Message> for TrafficChart {
let tot_seconds = self.ticks - 1;
let first_time_displayed = if self.ticks > 30 { self.ticks - 30 } else { 0 };

let color_incoming = self.color_incoming;
let color_outgoing = self.color_outgoing;
let colors = get_colors(self.style);
let color_incoming = to_rgb_color(colors.secondary);
let color_outgoing = to_rgb_color(colors.outgoing);
let color_font = to_rgb_color(colors.text_body);
let color_mix = get_alpha_chart_badge(self.style);

chart_builder
.margin_right(30)
Expand All @@ -133,7 +130,7 @@ impl Chart<Message> for TrafficChart {
("Sarasa Mono SC", 12)
.into_font()
.style(font_weight)
.color(&self.color_font),
.color(&color_font),
)
.y_labels(7)
.y_label_formatter(&|bytes| {
Expand All @@ -146,7 +143,7 @@ impl Chart<Message> for TrafficChart {
AreaSeries::new(
self.received_bytes.iter().copied(),
0,
color_incoming.mix(self.color_mix),
color_incoming.mix(color_mix.into()),
)
.border_style(
ShapeStyle::from(&color_incoming).stroke_width(CHARTS_LINE_BORDER),
Expand All @@ -162,7 +159,7 @@ impl Chart<Message> for TrafficChart {
AreaSeries::new(
self.sent_bytes.iter().copied(),
0,
color_outgoing.mix(self.color_mix),
color_outgoing.mix(color_mix.into()),
)
.border_style(
ShapeStyle::from(&color_outgoing).stroke_width(CHARTS_LINE_BORDER),
Expand All @@ -182,7 +179,7 @@ impl Chart<Message> for TrafficChart {
("Sarasa Mono SC", 13.5)
.into_font()
.style(font_weight)
.color(&self.color_font),
.color(&color_font),
)
.draw()
.expect("Error drawing graph");
Expand All @@ -203,7 +200,7 @@ impl Chart<Message> for TrafficChart {
("Sarasa Mono SC", 12)
.into_font()
.style(font_weight)
.color(&self.color_font),
.color(&color_font),
)
.y_labels(7)
.y_label_formatter(&|packets| packets.abs().to_string())
Expand All @@ -214,7 +211,7 @@ impl Chart<Message> for TrafficChart {
AreaSeries::new(
self.received_packets.iter().copied(),
0,
color_incoming.mix(self.color_mix),
color_incoming.mix(color_mix.into()),
)
.border_style(
ShapeStyle::from(&color_incoming).stroke_width(CHARTS_LINE_BORDER),
Expand All @@ -230,7 +227,7 @@ impl Chart<Message> for TrafficChart {
AreaSeries::new(
self.sent_packets.iter().copied(),
0,
color_outgoing.mix(self.color_mix),
color_outgoing.mix(color_mix.into()),
)
.border_style(
ShapeStyle::from(&color_outgoing).stroke_width(CHARTS_LINE_BORDER),
Expand All @@ -250,7 +247,7 @@ impl Chart<Message> for TrafficChart {
("Sarasa Mono SC", 13.5)
.into_font()
.style(font_weight)
.color(&self.color_font),
.color(&color_font),
)
.draw()
.expect("Error drawing graph");
Expand Down
3 changes: 2 additions & 1 deletion src/configs/types/config_settings.rs
Expand Up @@ -9,8 +9,9 @@ use crate::{Language, StyleType};

#[derive(Serialize, Deserialize, Default)]
pub struct ConfigSettings {
pub style: StyleType,
pub color_gradient: GradientType,
pub language: Language,
pub notifications: Notifications,
// StyleType should be last in order to deserialize as a table properly
pub style: StyleType,
}
98 changes: 82 additions & 16 deletions src/gui/pages/settings_style_page.rs
@@ -1,17 +1,20 @@
use iced::alignment::{Horizontal, Vertical};
use iced::widget::scrollable::Direction;
use iced::widget::{button, horizontal_space, vertical_space, Rule};
use iced::widget::{Button, Column, Container, Row, Text};
use iced::widget::{Button, Column, Container, Row, Scrollable, Space, Text};
use iced::Length::Fixed;
use iced::{Alignment, Length};
use iced::{Alignment, Element, Length};

use crate::gui::components::tab::get_settings_tabs;
use crate::gui::pages::settings_notifications_page::settings_header;
use crate::gui::pages::types::settings_page::SettingsPage;
use crate::gui::styles::button::{ButtonStyleTuple, ButtonType};
use crate::gui::styles::container::{ContainerStyleTuple, ContainerType};
use crate::gui::styles::rule::{RuleStyleTuple, RuleType};
use crate::gui::styles::scrollbar::{ScrollbarStyleTuple, ScrollbarType};
use crate::gui::styles::style_constants::{get_font, BORDER_WIDTH, FONT_SIZE_SUBTITLE, ICONS};
use crate::gui::styles::text::{TextStyleTuple, TextType};
use crate::gui::styles::types::custom_palette::ExtraStyles;
use crate::gui::styles::types::gradient_type::GradientType;
use crate::gui::types::message::Message;
use crate::translations::translations::{
Expand All @@ -24,7 +27,7 @@ use crate::{Language, Sniffer, StyleType};

pub fn settings_style_page(sniffer: &Sniffer) -> Container<Message> {
let font = get_font(sniffer.style);
let content = Column::new()
let mut content = Column::new()
.align_items(Alignment::Center)
.width(Length::Fill)
.push(settings_header(
Expand Down Expand Up @@ -55,13 +58,17 @@ pub fn settings_style_page(sniffer: &Sniffer) -> Container<Message> {
.font(font)
.size(FONT_SIZE_SUBTITLE),
)
.push(vertical_space(Length::Fixed(10.0)))
.push(vertical_space(Length::Fixed(15.0)))
.push(gradients_row(
sniffer.style,
sniffer.color_gradient,
sniffer.language,
))
.push(vertical_space(Length::Fixed(10.0)))
.push(vertical_space(Length::Fixed(15.0)));

let mut styles_col = Column::new()
.align_items(Alignment::Center)
.width(Length::Fill)
.push(
Row::new()
.push(get_palette_container(
Expand Down Expand Up @@ -94,7 +101,17 @@ pub fn settings_style_page(sniffer: &Sniffer) -> Container<Message> {
mon_amour_translation(sniffer.language).to_string(),
MonAmour,
)),
);
)
.push(vertical_space(Length::Fixed(10.0)));
for children in get_extra_palettes(ExtraStyles::all_styles(), sniffer.style) {
styles_col = styles_col.push(children);
}

let styles_scroll = Scrollable::new(styles_col)
.direction(Direction::Vertical(ScrollbarType::properties()))
.style(ScrollbarStyleTuple(sniffer.style, ScrollbarType::Standard));

content = content.push(styles_scroll);

Container::new(content)
.height(Length::Fixed(400.0))
Expand Down Expand Up @@ -177,16 +194,22 @@ fn get_palette_container(
on_press: StyleType,
) -> Button<'static, Message> {
let font = get_font(style);
let content = Column::new()

let is_custom = matches!(on_press, StyleType::Custom(_));

let mut content = Column::new()
.width(Length::Fill)
.align_items(Alignment::Center)
.spacing(5)
.push(Text::new(name).font(font))
.push(get_palette(on_press))
.push(Text::new(description).font(font));
.push(get_palette(on_press, is_custom));

if !is_custom {
content = content.push(Text::new(description).font(font));
}

Button::new(content)
.height(Length::Fixed(110.0))
.height(Length::Fixed(if is_custom { 75.0 } else { 110.0 }))
.width(Length::Fixed(380.0))
.padding(5)
.style(
Expand All @@ -203,36 +226,79 @@ fn get_palette_container(
.on_press(Message::Style(on_press))
}

fn get_palette(style: StyleType) -> Container<'static, Message> {
fn get_palette(style: StyleType, is_custom: bool) -> Container<'static, Message> {
let height = if is_custom { 25.0 } else { 40.0 };

Container::new(
Row::new()
.padding(0)
.push(Row::new().padding(0).width(Length::Fixed(120.0)).push(
Rule::horizontal(40).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
Rule::horizontal(height).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
RuleStyleTuple(style, RuleType::PalettePrimary),
)),
))
.push(Row::new().padding(0).width(Length::Fixed(80.0)).push(
Rule::horizontal(40).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
Rule::horizontal(height).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
RuleStyleTuple(style, RuleType::PaletteSecondary),
)),
))
.push(Row::new().padding(0).width(Length::Fixed(60.0)).push(
Rule::horizontal(40).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
Rule::horizontal(height).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
RuleStyleTuple(style, RuleType::PaletteOutgoing),
)),
))
.push(Row::new().padding(0).width(Length::Fixed(40.0)).push(
Rule::horizontal(40).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
Rule::horizontal(height).style(<RuleStyleTuple as Into<iced::theme::Rule>>::into(
RuleStyleTuple(style, RuleType::PaletteButtons),
)),
)),
)
.align_x(Horizontal::Center)
.align_y(Vertical::Center)
.width(300.0 + 2.0 * BORDER_WIDTH)
.height(40.0 + 1.7 * BORDER_WIDTH)
.height(height + 1.7 * BORDER_WIDTH)
.style(<ContainerStyleTuple as Into<iced::theme::Container>>::into(
ContainerStyleTuple(style, ContainerType::Palette),
))
}

// Buttons for each extra style arranged in rows of two
fn get_extra_palettes(
styles: &[ExtraStyles],
current_style: StyleType,
) -> Vec<Element<'static, Message>> {
// Map each extra style into a palette container
let mut styles = styles.iter().map(|&style| {
let name = style.to_string();
let description = String::new();
let style = StyleType::Custom(style);
get_palette_container(current_style, name, description, style)
});

// The best way to do this would be with itertools, but that would introduce another dependency.
let mut children = Vec::with_capacity(styles.len());

// This handles the case where there aren't an even number of styles.
// [Iterator::zip] drops remainders. Itertools' `zip_longest` and the unstable array chunks API
// are both better solutions.
while let (Some(first), second) = (styles.next(), styles.next()) {
// Add both styles and the vertical space if there are two styles.
if let Some(second) = second {
children.extend([
Row::new()
.push(first)
.push(horizontal_space(Length::Fixed(15.0)))
.push(second)
.into(),
<Space as Into<Element<Message>>>::into(vertical_space(Length::Fixed(10.0))),
]);
} else {
children.extend([
Row::new().push(first).into(),
<Space as Into<Element<Message>>>::into(vertical_space(Length::Fixed(10.0))),
]);
}
}

children
}