Skip to content

Commit

Permalink
feat(bar): add interactive layout and media widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
LGUG2Z committed Aug 28, 2024
1 parent ca6bf69 commit 18358ef
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 21 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@ features = [
"Win32_UI_Shell_Common",
"Win32_UI_WindowsAndMessaging",
"Win32_System_SystemServices",
"Win32_System_WindowsProgramming"
"Win32_System_WindowsProgramming",
"Media",
"Media_Control"
]
3 changes: 2 additions & 1 deletion komorebi-bar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ chrono = "0.4"
eframe = "0.28"
serde_json = "1"
sysinfo = "0.30"
crossbeam-channel = "0.5"
crossbeam-channel = "0.5"
windows = { workspace = true }
103 changes: 84 additions & 19 deletions komorebi-bar/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
mod date;
mod media;
mod memory;
mod storage;
mod time;
mod widget;

use crate::date::Date;
use crate::date::DateFormat;
use crate::media::Media;
use crate::media::MediaConfig;
use crate::memory::Memory;
use crate::memory::MemoryConfig;
use crate::storage::Storage;
Expand All @@ -15,12 +18,14 @@ use crate::widget::BarWidget;
use crossbeam_channel::Receiver;
use eframe::egui;
use eframe::egui::Align;
use eframe::egui::CursorIcon;
use eframe::egui::Label;
use eframe::egui::Layout;
use eframe::egui::Sense;
use eframe::egui::ViewportBuilder;
use eframe::egui::Visuals;
use eframe::emath::Pos2;
use eframe::emath::Vec2;
use komorebi_client::CycleDirection;
use komorebi_client::SocketMessage;
use std::io::BufReader;
use std::io::Read;
Expand Down Expand Up @@ -65,6 +70,7 @@ pub struct Config {
date: Date,
storage: StorageConfig,
memory: MemoryConfig,
media: MediaConfig,
}

fn main() -> eframe::Result<()> {
Expand All @@ -84,6 +90,7 @@ fn main() -> eframe::Result<()> {
date: Date::new(true, DateFormat::DayDateMonthYear),
storage: StorageConfig { enable: true },
memory: MemoryConfig { enable: true },
media: MediaConfig { enable: true },
};

// TODO: ensure that config.monitor_index represents a valid komorebi monitor index
Expand Down Expand Up @@ -178,12 +185,13 @@ struct Komobar {
state_receiver: Receiver<komorebi_client::Notification>,
selected_workspace: String,
focused_window_title: String,
workspace_layout: String,
layout: String,
workspaces: Vec<String>,
time: Time,
date: Date,
memory: Memory,
storage: Storage,
media: Media,
}

impl Komobar {
Expand All @@ -202,12 +210,13 @@ impl Komobar {
state_receiver: rx,
selected_workspace: String::new(),
focused_window_title: String::new(),
workspace_layout: String::new(),
layout: String::new(),
workspaces: vec![],
time: config.time,
date: config.date,
memory: Memory::from(config.memory),
storage: Storage::from(config.storage),
media: Media::from(config.media),
}
}
}
Expand All @@ -229,7 +238,7 @@ impl Komobar {
}

self.workspaces = workspaces;
self.workspace_layout = match monitor.workspaces()[focused_workspace_idx].layout() {
self.layout = match monitor.workspaces()[focused_workspace_idx].layout() {
komorebi_client::Layout::Default(layout) => layout.to_string(),
komorebi_client::Layout::Custom(_) => String::from("Custom"),
};
Expand All @@ -241,6 +250,23 @@ impl Komobar {
self.focused_window_title.clone_from(&title);
}
}
} else {
self.focused_window_title.clear();
}

if let Some(container) = monitor.workspaces()[focused_workspace_idx].monocle_container()
{
if let Some(window) = container.focused_window() {
if let Ok(title) = window.title() {
self.focused_window_title.clone_from(&title);
}
}
}

if let Some(window) = monitor.workspaces()[focused_workspace_idx].maximized_window() {
if let Ok(title) = window.title() {
self.focused_window_title.clone_from(&title);
}
}
}
}
Expand Down Expand Up @@ -296,11 +322,23 @@ impl eframe::App for Komobar {
}
}

ui.label(&self.workspace_layout);
if ui
.add(
Label::new(&self.layout)
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
komorebi_client::send_message(&SocketMessage::CycleLayout(
CycleDirection::Next,
))
.unwrap();
}

ui.add_space(10.0);

ui.label(&self.focused_window_title);
ui.add(Label::new(&self.focused_window_title).selectable(false));

ui.add_space(10.0);
});
Expand All @@ -311,8 +349,11 @@ impl eframe::App for Komobar {
for time in self.time.output() {
ctx.request_repaint();
if ui
.label(format!("🕐 {}", time))
.on_hover_cursor(CursorIcon::default())
.add(
Label::new(format!("🕐 {}", time))
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
self.time.format.toggle()
Expand All @@ -326,12 +367,15 @@ impl eframe::App for Komobar {
if self.date.enable {
for date in self.date.output() {
if ui
.label(format!("📅 {}", date))
.on_hover_cursor(CursorIcon::default())
.add(
Label::new(format!("📅 {}", date))
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
self.date.format.next()
};
}
}

// TODO: make spacing configurable
Expand All @@ -341,17 +385,19 @@ impl eframe::App for Komobar {
if self.memory.enable {
for ram in self.memory.output() {
if ui
// TODO: make label configurable??
.label(format!("🐏 {}", ram))
.on_hover_cursor(CursorIcon::default())
.add(
Label::new(format!("🐏 {}", ram))
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
if let Err(error) =
Command::new("cmd.exe").args(["/C", "taskmgr.exe"]).output()
{
eprintln!("{}", error)
}
};
}
}

ui.add_space(10.0);
Expand All @@ -360,9 +406,11 @@ impl eframe::App for Komobar {
if self.storage.enable {
for disk in self.storage.output() {
if ui
// TODO: Make emoji configurable??
.label(format!("🖴 {}", disk))
.on_hover_cursor(CursorIcon::default())
.add(
Label::new(format!("🖴 {}", disk))
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
if let Err(error) = Command::new("cmd.exe")
Expand All @@ -375,7 +423,24 @@ impl eframe::App for Komobar {
{
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);
}
Expand Down
63 changes: 63 additions & 0 deletions komorebi-bar/src/media.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use crate::widget::BarWidget;
use windows::Media::Control::GlobalSystemMediaTransportControlsSessionManager;

#[derive(Copy, Clone, Debug)]
pub struct MediaConfig {
pub enable: bool,
}

impl From<MediaConfig> for Media {
fn from(value: MediaConfig) -> Self {
Self::new(value.enable)
}
}

#[derive(Clone, Debug)]
pub struct Media {
pub enable: bool,
pub session_manager: GlobalSystemMediaTransportControlsSessionManager,
}

impl Media {
pub fn new(enable: bool) -> Self {
Self {
enable,
session_manager: GlobalSystemMediaTransportControlsSessionManager::RequestAsync()
.unwrap()
.get()
.unwrap(),
}
}

pub fn toggle(&self) {
if let Ok(session) = self.session_manager.GetCurrentSession() {
if let Ok(op) = session.TryTogglePlayPauseAsync() {
op.get().unwrap_or_default();
}
}
}
}

impl BarWidget for Media {
fn output(&mut self) -> Vec<String> {
if let Ok(session) = self.session_manager.GetCurrentSession() {
if let Ok(operation) = session.TryGetMediaPropertiesAsync() {
if let Ok(properties) = operation.get() {
if let (Ok(artist), Ok(title)) = (properties.Artist(), properties.Title()) {
if artist.is_empty() {
return vec![format!("{title}")];
}

if title.is_empty() {
return vec![format!("{artist}")];
}

return vec![format!("{artist} - {title}")];
}
}
}
}

vec![]
}
}

0 comments on commit 18358ef

Please sign in to comment.