mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 10:08:33 +02:00
feat(bar): allow right side widget ordering
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use eframe::egui::Label;
|
||||||
|
use eframe::egui::Sense;
|
||||||
|
use eframe::egui::Ui;
|
||||||
use starship_battery::units::ratio::percent;
|
use starship_battery::units::ratio::percent;
|
||||||
use starship_battery::Manager;
|
use starship_battery::Manager;
|
||||||
use starship_battery::State;
|
use starship_battery::State;
|
||||||
@@ -78,4 +81,26 @@ impl BarWidget for Battery {
|
|||||||
|
|
||||||
outputs
|
outputs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, ui: &mut Ui) {
|
||||||
|
if self.enable {
|
||||||
|
let output = self.output();
|
||||||
|
if !output.is_empty() {
|
||||||
|
for battery in output {
|
||||||
|
let emoji = match self.state {
|
||||||
|
BatteryState::Charging => "⚡️",
|
||||||
|
BatteryState::Discharging => "🔋",
|
||||||
|
};
|
||||||
|
|
||||||
|
ui.add(
|
||||||
|
Label::new(format!("{emoji} {battery}"))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,22 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use eframe::egui::Label;
|
||||||
|
use eframe::egui::Sense;
|
||||||
|
use eframe::egui::Ui;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct DateConfig {
|
||||||
|
pub enable: bool,
|
||||||
|
pub format: DateFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DateConfig> for Date {
|
||||||
|
fn from(value: DateConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
enable: value.enable,
|
||||||
|
format: value.format,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum DateFormat {
|
pub enum DateFormat {
|
||||||
@@ -34,16 +52,30 @@ pub struct Date {
|
|||||||
pub format: DateFormat,
|
pub format: DateFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Date {
|
|
||||||
pub fn new(enable: bool, format: DateFormat) -> Self {
|
|
||||||
Self { enable, format }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BarWidget for Date {
|
impl BarWidget for Date {
|
||||||
fn output(&mut self) -> Vec<String> {
|
fn output(&mut self) -> Vec<String> {
|
||||||
vec![chrono::Local::now()
|
vec![chrono::Local::now()
|
||||||
.format(&self.format.fmt_string())
|
.format(&self.format.fmt_string())
|
||||||
.to_string()]
|
.to_string()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, ui: &mut Ui) {
|
||||||
|
if self.enable {
|
||||||
|
for output in self.output() {
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
Label::new(format!("📅 {}", output))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
self.format.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make spacing configurable
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ mod widget;
|
|||||||
|
|
||||||
use crate::battery::Battery;
|
use crate::battery::Battery;
|
||||||
use crate::battery::BatteryConfig;
|
use crate::battery::BatteryConfig;
|
||||||
use crate::battery::BatteryState;
|
|
||||||
use crate::date::Date;
|
use crate::date::Date;
|
||||||
|
use crate::date::DateConfig;
|
||||||
use crate::date::DateFormat;
|
use crate::date::DateFormat;
|
||||||
use crate::media::Media;
|
use crate::media::Media;
|
||||||
use crate::media::MediaConfig;
|
use crate::media::MediaConfig;
|
||||||
@@ -20,6 +20,7 @@ use crate::network::Network;
|
|||||||
use crate::network::NetworkConfig;
|
use crate::network::NetworkConfig;
|
||||||
use crate::storage::Storage;
|
use crate::storage::Storage;
|
||||||
use crate::storage::StorageConfig;
|
use crate::storage::StorageConfig;
|
||||||
|
use crate::time::TimeConfig;
|
||||||
use crate::time::TimeFormat;
|
use crate::time::TimeFormat;
|
||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
use crossbeam_channel::Receiver;
|
use crossbeam_channel::Receiver;
|
||||||
@@ -39,7 +40,6 @@ use komorebi_client::SocketMessage;
|
|||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::process::Command;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use time::Time;
|
use time::Time;
|
||||||
@@ -77,8 +77,8 @@ pub struct Config {
|
|||||||
monitor_index: usize,
|
monitor_index: usize,
|
||||||
monitor_work_area_offset: Option<komorebi_client::Rect>,
|
monitor_work_area_offset: Option<komorebi_client::Rect>,
|
||||||
font_family: Option<String>,
|
font_family: Option<String>,
|
||||||
time: Time,
|
time: TimeConfig,
|
||||||
date: Date,
|
date: DateConfig,
|
||||||
storage: StorageConfig,
|
storage: StorageConfig,
|
||||||
memory: MemoryConfig,
|
memory: MemoryConfig,
|
||||||
media: MediaConfig,
|
media: MediaConfig,
|
||||||
@@ -100,8 +100,14 @@ fn main() -> eframe::Result<()> {
|
|||||||
right: 0,
|
right: 0,
|
||||||
bottom: 40,
|
bottom: 40,
|
||||||
}),
|
}),
|
||||||
time: Time::new(true, TimeFormat::TwentyFourHour),
|
time: TimeConfig {
|
||||||
date: Date::new(true, DateFormat::DayDateMonthYear),
|
enable: true,
|
||||||
|
format: TimeFormat::TwentyFourHour,
|
||||||
|
},
|
||||||
|
date: DateConfig {
|
||||||
|
enable: true,
|
||||||
|
format: DateFormat::DayDateMonthYear,
|
||||||
|
},
|
||||||
storage: StorageConfig { enable: true },
|
storage: StorageConfig { enable: true },
|
||||||
memory: MemoryConfig { enable: true },
|
memory: MemoryConfig { enable: true },
|
||||||
media: MediaConfig { enable: true },
|
media: MediaConfig { enable: true },
|
||||||
@@ -213,13 +219,7 @@ struct Komobar {
|
|||||||
focused_window_title: String,
|
focused_window_title: String,
|
||||||
layout: String,
|
layout: String,
|
||||||
workspaces: Vec<String>,
|
workspaces: Vec<String>,
|
||||||
time: Time,
|
right_widgets: Vec<Box<dyn BarWidget>>,
|
||||||
date: Date,
|
|
||||||
memory: Memory,
|
|
||||||
storage: Storage,
|
|
||||||
media: Media,
|
|
||||||
battery: Battery,
|
|
||||||
network: Network,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_custom_font(ctx: &egui::Context, name: &str) {
|
fn add_custom_font(ctx: &egui::Context, name: &str) {
|
||||||
@@ -267,6 +267,18 @@ impl Komobar {
|
|||||||
// Use the cc.gl (a glow::Context) to create graphics shaders and buffers that you can use
|
// Use the cc.gl (a glow::Context) to create graphics shaders and buffers that you can use
|
||||||
// for e.g. egui::PaintCallback.
|
// for e.g. egui::PaintCallback.
|
||||||
|
|
||||||
|
let mut right_widgets: Vec<Box<dyn BarWidget>> = vec![
|
||||||
|
Box::new(Media::from(config.media)),
|
||||||
|
Box::new(Storage::from(config.storage)),
|
||||||
|
Box::new(Memory::from(config.memory)),
|
||||||
|
Box::new(Network::from(config.network)),
|
||||||
|
Box::new(Date::from(config.date)),
|
||||||
|
Box::new(Time::from(config.time)),
|
||||||
|
Box::new(Battery::from(config.battery)),
|
||||||
|
];
|
||||||
|
|
||||||
|
right_widgets.reverse();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
config: config.deref().clone(),
|
config: config.deref().clone(),
|
||||||
state_receiver: rx,
|
state_receiver: rx,
|
||||||
@@ -274,13 +286,7 @@ impl Komobar {
|
|||||||
focused_window_title: String::new(),
|
focused_window_title: String::new(),
|
||||||
layout: String::new(),
|
layout: String::new(),
|
||||||
workspaces: vec![],
|
workspaces: vec![],
|
||||||
time: config.time,
|
right_widgets,
|
||||||
date: config.date,
|
|
||||||
memory: Memory::from(config.memory),
|
|
||||||
storage: Storage::from(config.storage),
|
|
||||||
media: Media::from(config.media),
|
|
||||||
battery: Battery::from(config.battery),
|
|
||||||
network: Network::from(config.network),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -409,171 +415,8 @@ impl eframe::App for Komobar {
|
|||||||
|
|
||||||
// TODO: make the order configurable
|
// TODO: make the order configurable
|
||||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||||
if self.battery.enable {
|
for w in &mut self.right_widgets {
|
||||||
let battery_output = self.battery.output();
|
w.render(ui);
|
||||||
if !battery_output.is_empty() {
|
|
||||||
for battery in battery_output {
|
|
||||||
let emoji = match self.battery.state {
|
|
||||||
BatteryState::Charging => "⚡️",
|
|
||||||
BatteryState::Discharging => "🔋",
|
|
||||||
};
|
|
||||||
|
|
||||||
ui.add(
|
|
||||||
Label::new(format!("{emoji} {battery}"))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.time.enable {
|
|
||||||
for time in self.time.output() {
|
|
||||||
if ui
|
|
||||||
.add(
|
|
||||||
Label::new(format!("🕐 {}", time))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
self.time.format.toggle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: make spacing configurable
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.date.enable {
|
|
||||||
for date in self.date.output() {
|
|
||||||
if ui
|
|
||||||
.add(
|
|
||||||
Label::new(format!("📅 {}", date))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
self.date.format.next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: make spacing configurable
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.network.enable {
|
|
||||||
let network_output = self.network.output();
|
|
||||||
|
|
||||||
if !network_output.is_empty() {
|
|
||||||
match network_output.len() {
|
|
||||||
1 => {
|
|
||||||
if ui
|
|
||||||
.add(
|
|
||||||
Label::new(format!("📶 {}", network_output[0]))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
if let Err(error) =
|
|
||||||
Command::new("cmd.exe").args(["/C", "ncpa"]).spawn()
|
|
||||||
{
|
|
||||||
eprintln!("{}", error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2 => {
|
|
||||||
if ui
|
|
||||||
.add(
|
|
||||||
Label::new(format!(
|
|
||||||
"📶 {} - {}",
|
|
||||||
network_output[0], network_output[1]
|
|
||||||
))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
if let Err(error) =
|
|
||||||
Command::new("cmd.exe").args(["/C", "ncpa"]).spawn()
|
|
||||||
{
|
|
||||||
eprintln!("{}", error)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.memory.enable {
|
|
||||||
for ram in self.memory.output() {
|
|
||||||
if ui
|
|
||||||
.add(
|
|
||||||
Label::new(format!("🐏 {}", ram))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
if let Err(error) =
|
|
||||||
Command::new("cmd.exe").args(["/C", "taskmgr.exe"]).spawn()
|
|
||||||
{
|
|
||||||
eprintln!("{}", error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.storage.enable {
|
|
||||||
for disk in self.storage.output() {
|
|
||||||
if ui
|
|
||||||
.add(
|
|
||||||
Label::new(format!("🖴 {}", disk))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
if let Err(error) = Command::new("cmd.exe")
|
|
||||||
.args([
|
|
||||||
"/C",
|
|
||||||
"explorer.exe",
|
|
||||||
disk.split(' ').collect::<Vec<&str>>()[0],
|
|
||||||
])
|
|
||||||
.spawn()
|
|
||||||
{
|
|
||||||
eprintln!("{}", error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.media.enable {
|
|
||||||
for media in self.media.output() {
|
|
||||||
if ui
|
|
||||||
.add(
|
|
||||||
Label::new(format!("🎧 {media}"))
|
|
||||||
.selectable(false)
|
|
||||||
.sense(Sense::click()),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
self.media.toggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.add_space(10.0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use eframe::egui::Label;
|
||||||
|
use eframe::egui::Sense;
|
||||||
|
use eframe::egui::Ui;
|
||||||
use windows::Media::Control::GlobalSystemMediaTransportControlsSessionManager;
|
use windows::Media::Control::GlobalSystemMediaTransportControlsSessionManager;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
@@ -60,4 +63,23 @@ impl BarWidget for Media {
|
|||||||
|
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, ui: &mut Ui) {
|
||||||
|
if self.enable {
|
||||||
|
for output in self.output() {
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
Label::new(format!("🎧 {output}"))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
self.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use eframe::egui::Label;
|
||||||
|
use eframe::egui::Sense;
|
||||||
|
use eframe::egui::Ui;
|
||||||
|
use std::process::Command;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use sysinfo::RefreshKind;
|
use sysinfo::RefreshKind;
|
||||||
@@ -42,4 +46,26 @@ impl BarWidget for Memory {
|
|||||||
let total = self.system.total_memory();
|
let total = self.system.total_memory();
|
||||||
vec![format!("RAM: {}%", (used * 100) / total)]
|
vec![format!("RAM: {}%", (used * 100) / total)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, ui: &mut Ui) {
|
||||||
|
if self.enable {
|
||||||
|
for output in self.output() {
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
Label::new(format!("🐏 {}", output))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
if let Err(error) = Command::new("cmd.exe").args(["/C", "taskmgr.exe"]).spawn()
|
||||||
|
{
|
||||||
|
eprintln!("{}", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use eframe::egui::Label;
|
||||||
|
use eframe::egui::Sense;
|
||||||
|
use eframe::egui::Ui;
|
||||||
|
use std::process::Command;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use sysinfo::Networks;
|
use sysinfo::Networks;
|
||||||
@@ -84,4 +88,48 @@ impl BarWidget for Network {
|
|||||||
|
|
||||||
outputs
|
outputs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, ui: &mut Ui) {
|
||||||
|
if self.enable {
|
||||||
|
let output = self.output();
|
||||||
|
|
||||||
|
if !output.is_empty() {
|
||||||
|
match output.len() {
|
||||||
|
1 => {
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
Label::new(format!("📶 {}", output[0]))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
if let Err(error) = Command::new("cmd.exe").args(["/C", "ncpa"]).spawn()
|
||||||
|
{
|
||||||
|
eprintln!("{}", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
Label::new(format!("📶 {} - {}", output[0], output[1]))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
if let Err(error) = Command::new("cmd.exe").args(["/C", "ncpa"]).spawn()
|
||||||
|
{
|
||||||
|
eprintln!("{}", error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use eframe::egui::Label;
|
||||||
|
use eframe::egui::Sense;
|
||||||
|
use eframe::egui::Ui;
|
||||||
|
use std::process::Command;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use sysinfo::Disks;
|
use sysinfo::Disks;
|
||||||
@@ -52,4 +56,32 @@ impl BarWidget for Storage {
|
|||||||
|
|
||||||
disks
|
disks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, ui: &mut Ui) {
|
||||||
|
if self.enable {
|
||||||
|
for output in self.output() {
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
Label::new(format!("🖴 {}", output))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
if let Err(error) = Command::new("cmd.exe")
|
||||||
|
.args([
|
||||||
|
"/C",
|
||||||
|
"explorer.exe",
|
||||||
|
output.split(' ').collect::<Vec<&str>>()[0],
|
||||||
|
])
|
||||||
|
.spawn()
|
||||||
|
{
|
||||||
|
eprintln!("{}", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,22 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use eframe::egui::Label;
|
||||||
|
use eframe::egui::Sense;
|
||||||
|
use eframe::egui::Ui;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct TimeConfig {
|
||||||
|
pub enable: bool,
|
||||||
|
pub format: TimeFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TimeConfig> for Time {
|
||||||
|
fn from(value: TimeConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
enable: value.enable,
|
||||||
|
format: value.format,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum TimeFormat {
|
pub enum TimeFormat {
|
||||||
@@ -28,16 +46,30 @@ pub struct Time {
|
|||||||
pub format: TimeFormat,
|
pub format: TimeFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Time {
|
|
||||||
pub fn new(enable: bool, format: TimeFormat) -> Self {
|
|
||||||
Self { enable, format }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BarWidget for Time {
|
impl BarWidget for Time {
|
||||||
fn output(&mut self) -> Vec<String> {
|
fn output(&mut self) -> Vec<String> {
|
||||||
vec![chrono::Local::now()
|
vec![chrono::Local::now()
|
||||||
.format(&self.format.fmt_string())
|
.format(&self.format.fmt_string())
|
||||||
.to_string()]
|
.to_string()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, ui: &mut Ui) {
|
||||||
|
if self.enable {
|
||||||
|
for output in self.output() {
|
||||||
|
if ui
|
||||||
|
.add(
|
||||||
|
Label::new(format!("🕐 {}", output))
|
||||||
|
.selectable(false)
|
||||||
|
.sense(Sense::click()),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
self.format.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make spacing configurable
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
use eframe::egui::Ui;
|
||||||
|
|
||||||
pub trait BarWidget {
|
pub trait BarWidget {
|
||||||
fn output(&mut self) -> Vec<String>;
|
fn output(&mut self) -> Vec<String>;
|
||||||
|
fn render(&mut self, ui: &mut Ui);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user