mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-01-11 22:12:53 +01:00
feat(bar): add basic widget config opts
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum DateFormat {
|
pub enum DateFormat {
|
||||||
MonthDateYear,
|
MonthDateYear,
|
||||||
YearMonthDate,
|
YearMonthDate,
|
||||||
@@ -27,15 +28,15 @@ impl DateFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Date {
|
pub struct Date {
|
||||||
|
pub enable: bool,
|
||||||
pub format: DateFormat,
|
pub format: DateFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Date {
|
impl Date {
|
||||||
fn default() -> Self {
|
pub fn new(enable: bool, format: DateFormat) -> Self {
|
||||||
Self {
|
Self { enable, format }
|
||||||
format: DateFormat::MonthDateYear,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,12 @@ mod time;
|
|||||||
mod widget;
|
mod widget;
|
||||||
|
|
||||||
use crate::date::Date;
|
use crate::date::Date;
|
||||||
|
use crate::date::DateFormat;
|
||||||
use crate::memory::Memory;
|
use crate::memory::Memory;
|
||||||
|
use crate::memory::MemoryConfig;
|
||||||
use crate::storage::Storage;
|
use crate::storage::Storage;
|
||||||
|
use crate::storage::StorageConfig;
|
||||||
|
use crate::time::TimeFormat;
|
||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
use crossbeam_channel::Receiver;
|
use crossbeam_channel::Receiver;
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
@@ -31,20 +35,20 @@ pub struct Position {
|
|||||||
y: f32,
|
y: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Vec2> for Position {
|
impl From<Position> for Vec2 {
|
||||||
fn into(self) -> Vec2 {
|
fn from(value: Position) -> Self {
|
||||||
Vec2 {
|
Self {
|
||||||
x: self.x,
|
x: value.x,
|
||||||
y: self.y,
|
y: value.y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Pos2> for Position {
|
impl From<Position> for Pos2 {
|
||||||
fn into(self) -> Pos2 {
|
fn from(value: Position) -> Self {
|
||||||
Pos2 {
|
Self {
|
||||||
x: self.x,
|
x: value.x,
|
||||||
y: self.y,
|
y: value.y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,6 +61,10 @@ pub struct Config {
|
|||||||
transparent: bool,
|
transparent: bool,
|
||||||
monitor_index: usize,
|
monitor_index: usize,
|
||||||
monitor_work_area_offset: Option<komorebi_client::Rect>,
|
monitor_work_area_offset: Option<komorebi_client::Rect>,
|
||||||
|
time: Time,
|
||||||
|
date: Date,
|
||||||
|
storage: StorageConfig,
|
||||||
|
memory: MemoryConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> eframe::Result<()> {
|
fn main() -> eframe::Result<()> {
|
||||||
@@ -72,6 +80,10 @@ fn main() -> eframe::Result<()> {
|
|||||||
right: 0,
|
right: 0,
|
||||||
bottom: 40,
|
bottom: 40,
|
||||||
}),
|
}),
|
||||||
|
time: Time::new(true, TimeFormat::TwentyFourHour),
|
||||||
|
date: Date::new(true, DateFormat::DayDateMonthYear),
|
||||||
|
storage: StorageConfig { enable: true },
|
||||||
|
memory: MemoryConfig { enable: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: ensure that config.monitor_index represents a valid komorebi monitor index
|
// TODO: ensure that config.monitor_index represents a valid komorebi monitor index
|
||||||
@@ -165,6 +177,8 @@ struct Komobar {
|
|||||||
config: Config,
|
config: Config,
|
||||||
state_receiver: Receiver<komorebi_client::Notification>,
|
state_receiver: Receiver<komorebi_client::Notification>,
|
||||||
selected_workspace: String,
|
selected_workspace: String,
|
||||||
|
focused_window_title: String,
|
||||||
|
workspace_layout: String,
|
||||||
workspaces: Vec<String>,
|
workspaces: Vec<String>,
|
||||||
time: Time,
|
time: Time,
|
||||||
date: Date,
|
date: Date,
|
||||||
@@ -184,14 +198,16 @@ impl Komobar {
|
|||||||
// for e.g. egui::PaintCallback.
|
// for e.g. egui::PaintCallback.
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
config: *config.as_ref(),
|
config: *config,
|
||||||
state_receiver: rx,
|
state_receiver: rx,
|
||||||
selected_workspace: String::new(),
|
selected_workspace: String::new(),
|
||||||
|
focused_window_title: String::new(),
|
||||||
|
workspace_layout: String::new(),
|
||||||
workspaces: vec![],
|
workspaces: vec![],
|
||||||
time: Time::default(),
|
time: config.time,
|
||||||
date: Date::default(),
|
date: config.date,
|
||||||
memory: Memory::default(),
|
memory: Memory::from(config.memory),
|
||||||
storage: Storage::default(),
|
storage: Storage::from(config.storage),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,20 +215,32 @@ impl Komobar {
|
|||||||
impl Komobar {
|
impl Komobar {
|
||||||
fn handle_komorebi_notification(&mut self) {
|
fn handle_komorebi_notification(&mut self) {
|
||||||
if let Ok(notification) = self.state_receiver.try_recv() {
|
if let Ok(notification) = self.state_receiver.try_recv() {
|
||||||
self.workspaces = {
|
let monitor = ¬ification.state.monitors.elements()[self.config.monitor_index];
|
||||||
let mut workspaces = vec![];
|
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||||
let monitor = ¬ification.state.monitors.elements()[self.config.monitor_index];
|
|
||||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
|
||||||
self.selected_workspace = monitor.workspaces()[focused_workspace_idx]
|
|
||||||
.name()
|
|
||||||
.to_owned()
|
|
||||||
.unwrap_or_else(|| format!("{}", focused_workspace_idx + 1));
|
|
||||||
|
|
||||||
for (i, ws) in monitor.workspaces().iter().enumerate() {
|
let mut workspaces = vec![];
|
||||||
workspaces.push(ws.name().to_owned().unwrap_or_else(|| format!("{}", i + 1)));
|
self.selected_workspace = monitor.workspaces()[focused_workspace_idx]
|
||||||
|
.name()
|
||||||
|
.to_owned()
|
||||||
|
.unwrap_or_else(|| format!("{}", focused_workspace_idx + 1));
|
||||||
|
|
||||||
|
for (i, ws) in monitor.workspaces().iter().enumerate() {
|
||||||
|
workspaces.push(ws.name().to_owned().unwrap_or_else(|| format!("{}", i + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.workspaces = workspaces;
|
||||||
|
self.workspace_layout = match monitor.workspaces()[focused_workspace_idx].layout() {
|
||||||
|
komorebi_client::Layout::Default(layout) => layout.to_string(),
|
||||||
|
komorebi_client::Layout::Custom(_) => String::from("Custom"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(container) = monitor.workspaces()[focused_workspace_idx].focused_container()
|
||||||
|
{
|
||||||
|
if let Some(window) = container.focused_window() {
|
||||||
|
if let Ok(title) = window.title() {
|
||||||
|
self.focused_window_title.clone_from(&title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaces
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,78 +295,91 @@ impl eframe::App for Komobar {
|
|||||||
komorebi_client::send_message(&SocketMessage::Retile).unwrap();
|
komorebi_client::send_message(&SocketMessage::Retile).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.label(&self.workspace_layout);
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
|
||||||
|
ui.label(&self.focused_window_title);
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: make the order configurable
|
// TODO: make the order configurable
|
||||||
// TODO: make each widget optional??
|
|
||||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||||
for time in self.time.output() {
|
if self.time.enable {
|
||||||
ctx.request_repaint();
|
for time in self.time.output() {
|
||||||
if ui
|
ctx.request_repaint();
|
||||||
.label(format!("🕐 {}", time))
|
if ui
|
||||||
.on_hover_cursor(CursorIcon::default())
|
.label(format!("🕐 {}", time))
|
||||||
.clicked()
|
.on_hover_cursor(CursorIcon::default())
|
||||||
{
|
.clicked()
|
||||||
// TODO: make default format configurable
|
{
|
||||||
self.time.format.toggle()
|
self.time.format.toggle()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: make spacing configurable
|
||||||
|
ui.add_space(10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make spacing configurable
|
if self.date.enable {
|
||||||
ui.add_space(10.0);
|
for date in self.date.output() {
|
||||||
|
if ui
|
||||||
for date in self.date.output() {
|
.label(format!("📅 {}", date))
|
||||||
if ui
|
.on_hover_cursor(CursorIcon::default())
|
||||||
.label(format!("📅 {}", date))
|
.clicked()
|
||||||
.on_hover_cursor(CursorIcon::default())
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
// TODO: make default format configurable
|
|
||||||
self.date.format.next()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: make spacing configurable
|
|
||||||
ui.add_space(10.0);
|
|
||||||
|
|
||||||
for ram in self.memory.output() {
|
|
||||||
if ui
|
|
||||||
// TODO: make label configurable??
|
|
||||||
.label(format!("🐏 {}", ram))
|
|
||||||
.on_hover_cursor(CursorIcon::default())
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
if let Err(error) =
|
|
||||||
Command::new("cmd.exe").args(["/C", "taskmgr.exe"]).output()
|
|
||||||
{
|
{
|
||||||
eprintln!("{}", error)
|
self.date.format.next()
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// TODO: make spacing configurable
|
||||||
|
ui.add_space(10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.add_space(10.0);
|
if self.memory.enable {
|
||||||
|
for ram in self.memory.output() {
|
||||||
for disk in self.storage.output() {
|
if ui
|
||||||
if ui
|
// TODO: make label configurable??
|
||||||
// TODO: Make emoji configurable??
|
.label(format!("🐏 {}", ram))
|
||||||
.label(format!("🖴 {}", disk))
|
.on_hover_cursor(CursorIcon::default())
|
||||||
.on_hover_cursor(CursorIcon::default())
|
.clicked()
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
if let Err(error) = Command::new("cmd.exe")
|
|
||||||
.args([
|
|
||||||
"/C",
|
|
||||||
"explorer.exe",
|
|
||||||
disk.split(' ').collect::<Vec<&str>>()[0],
|
|
||||||
])
|
|
||||||
.output()
|
|
||||||
{
|
{
|
||||||
eprintln!("{}", error)
|
if let Err(error) =
|
||||||
}
|
Command::new("cmd.exe").args(["/C", "taskmgr.exe"]).output()
|
||||||
};
|
{
|
||||||
|
eprintln!("{}", error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.storage.enable {
|
||||||
|
for disk in self.storage.output() {
|
||||||
|
if ui
|
||||||
|
// TODO: Make emoji configurable??
|
||||||
|
.label(format!("🖴 {}", disk))
|
||||||
|
.on_hover_cursor(CursorIcon::default())
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
if let Err(error) = Command::new("cmd.exe")
|
||||||
|
.args([
|
||||||
|
"/C",
|
||||||
|
"explorer.exe",
|
||||||
|
disk.split(' ').collect::<Vec<&str>>()[0],
|
||||||
|
])
|
||||||
|
.output()
|
||||||
|
{
|
||||||
|
eprintln!("{}", error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ui.add_space(10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,12 +3,19 @@ use sysinfo::RefreshKind;
|
|||||||
use sysinfo::System;
|
use sysinfo::System;
|
||||||
|
|
||||||
pub struct Memory {
|
pub struct Memory {
|
||||||
|
pub enable: bool,
|
||||||
system: System,
|
system: System,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Memory {
|
#[derive(Copy, Clone, Debug)]
|
||||||
fn default() -> Self {
|
pub struct MemoryConfig {
|
||||||
|
pub enable: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<MemoryConfig> for Memory {
|
||||||
|
fn from(value: MemoryConfig) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
enable: value.enable,
|
||||||
system: System::new_with_specifics(
|
system: System::new_with_specifics(
|
||||||
RefreshKind::default().without_cpu().without_processes(),
|
RefreshKind::default().without_cpu().without_processes(),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
use sysinfo::Disks;
|
use sysinfo::Disks;
|
||||||
|
|
||||||
pub struct Storage {
|
#[derive(Copy, Clone, Debug)]
|
||||||
disks: Disks,
|
pub struct StorageConfig {
|
||||||
|
pub enable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Storage {
|
impl From<StorageConfig> for Storage {
|
||||||
fn default() -> Self {
|
fn from(value: StorageConfig) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
enable: value.enable,
|
||||||
disks: Disks::new_with_refreshed_list(),
|
disks: Disks::new_with_refreshed_list(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Storage {
|
||||||
|
pub enable: bool,
|
||||||
|
disks: Disks,
|
||||||
|
}
|
||||||
|
|
||||||
impl BarWidget for Storage {
|
impl BarWidget for Storage {
|
||||||
fn output(&mut self) -> Vec<String> {
|
fn output(&mut self) -> Vec<String> {
|
||||||
self.disks.refresh();
|
self.disks.refresh();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum TimeFormat {
|
pub enum TimeFormat {
|
||||||
TwelveHour,
|
TwelveHour,
|
||||||
TwentyFourHour,
|
TwentyFourHour,
|
||||||
@@ -21,15 +22,15 @@ impl TimeFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Time {
|
pub struct Time {
|
||||||
|
pub enable: bool,
|
||||||
pub format: TimeFormat,
|
pub format: TimeFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Time {
|
impl Time {
|
||||||
fn default() -> Self {
|
pub fn new(enable: bool, format: TimeFormat) -> Self {
|
||||||
Self {
|
Self { enable, format }
|
||||||
format: TimeFormat::TwelveHour,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user