Skip to content

Commit

Permalink
lots more cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
diminishedprime committed Jan 30, 2023
1 parent a2451fe commit 161e1a4
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 369 deletions.
182 changes: 182 additions & 0 deletions src/gui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
use crate::{
keymap::get_keymap,
types::{Args, KeymapEntry, Leaf, Message, SingleModeShortcuts, State},
INPUT_ID, ROBOTO,
};
use clap::Parser;
use iced::{
alignment, color, theme,
widget::{column, container, row, text, text_input},
window, Application, Command, Element, Font, Length, Settings, Theme,
};

pub(crate) fn main() -> iced::Result {
SingleModeShortcuts::run(Settings {
window: window::Settings {
size: (500, 300),
decorations: false,
..window::Settings::default()
},
..Settings::default()
})
}

impl State {
pub(crate) fn new() -> State {
let args = Args::parse();
State {
input_value: args.input,
keymap: get_keymap(),
}
}
async fn load() -> Self {
Self::new()
}
}

impl Application for SingleModeShortcuts {
type Message = Message;
type Theme = Theme;
type Executor = iced::executor::Default;
type Flags = ();

fn new(_flags: ()) -> (SingleModeShortcuts, Command<Message>) {
(
SingleModeShortcuts::Loading,
Command::perform(State::load(), Message::Loaded),
)
}

fn title(&self) -> String {
"Single Mode Shortcuts".to_string()
}

fn update(&mut self, message: Message) -> Command<Message> {
match self {
SingleModeShortcuts::Loaded(state) => {
let command = match message {
Message::InputChanged(value) => {
let current_map = value
.chars()
.fold(Some(&state.keymap), |acc, key| match acc {
Some(current_map) => match current_map {
KeymapEntry::Leaf { .. } => None,
KeymapEntry::Node { map, .. } => map.get(&*key.to_string()),
},
None => None,
});

// If we're on a node, run it right away.
if let Some(KeymapEntry::Leaf(leaf)) = current_map {
leaf.run().unwrap();
}

if !matches!(current_map, Some(KeymapEntry::Leaf(Leaf::LaunchNoQuit(_)))) {
state.input_value = value;
}

Command::none()
}
_ => Command::none(),
};

Command::batch(vec![command])
}
SingleModeShortcuts::Loading => {
*self = SingleModeShortcuts::Loaded(State::new());
text_input::focus(INPUT_ID.clone())
}
}
}

fn theme(&self) -> Self::Theme {
Theme::custom(theme::Palette {
background: color!(0x002b36),
text: color!(0xfdf6e3),
..Theme::Dark.palette()
})
}

fn view(&self) -> Element<Message> {
match self {
SingleModeShortcuts::Loaded(
_state @ State {
input_value,
keymap,
},
) => {
let input = text_input("Enter shortcut", input_value, Message::InputChanged)
.id(INPUT_ID.clone())
.padding(8)
.size(24);

let content = column![
input, // maps,
keymap.view(input_value)
]
.spacing(8);

container(content)
.width(Length::Fill)
.padding(8)
.center_x()
.into()
}
SingleModeShortcuts::Loading => container(
text("Loading...")
.horizontal_alignment(alignment::Horizontal::Center)
.size(50),
)
.width(Length::Fill)
.height(Length::Fill)
.center_y()
.into(),
}
}
}

impl KeymapEntry {
pub(crate) fn view(&self, input: &str) -> Element<Message> {
let current_map = input.chars().fold(Some(self), |acc, key| match acc {
Some(current_map) => match current_map {
KeymapEntry::Leaf { .. } => None,
KeymapEntry::Node { map, .. } => map.get(&*key.to_string()),
},
None => None,
});
if let Some(KeymapEntry::Node { map, .. }) = current_map {
column(
map
.iter()
.map(|(key, value)| {
let key = if key == &" " { "<space>" } else { key };
let key = text(format!("{key: >7}"))
.font(Font::External {
name: "Roboto",
bytes: &ROBOTO,
})
.size(16)
.style(color!(0xcb4b16));

let value = text(value.get_name())
.font(Font::External {
name: "Roboto",
bytes: &ROBOTO,
})
.size(16)
.style(if value.is_mode() {
color!(0x2aa198)
} else {
color!(0xfdf6e3)
});

row![key, value].spacing(8).into()
})
.collect(),
)
.into()
} else {
column![].into()
}
}
}
8 changes: 2 additions & 6 deletions src/keymap.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use crate::{
keymap_entry::{GoToOrLaunch, Launch, Leaf},
KeymapEntry,
};

use crate::types::{GoToOrLaunch, KeymapEntry, Launch, Leaf};
use std::collections::HashMap;

// TODO - for things that have multiple entries, I want to somehow run the
Expand Down Expand Up @@ -55,7 +51,7 @@ fn keymap_for(name: &'static str, entries: Vec<(&'static str, KeymapEntry)>) ->
}

#[cfg(target_os = "linux")]
pub fn get_keymap() -> KeymapEntry {
pub(crate) fn get_keymap() -> KeymapEntry {
let apps = {
let chrome = launch("chrome", "google-chrome-stable", &[]);
let files = launch("files", "thunar", &[]);
Expand Down
154 changes: 2 additions & 152 deletions src/keymap_entry.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,11 @@
use crate::types::{GoToOrLaunch, KeymapEntry, Launch, Leaf};
use anyhow::Result;
use std::{
collections::HashMap,
fmt::Display,
process::{self, Command},
str,
};

use anyhow::Result;
use iced::{
color,
widget::{column, row, text},
Element, Font,
};
use itertools::Itertools;

use crate::{Message, ROBOTO};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GoToOrLaunch {
pub(crate) workspace_name: &'static str,
pub(crate) instance_match: &'static str,
pub(crate) launch: Launch,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Launch {
pub(crate) name: &'static str,
pub(crate) program: &'static str,
pub(crate) args: &'static [&'static str],
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Leaf {
GoToOrLaunch(GoToOrLaunch),
Launch(Launch),
LaunchNoQuit(Launch),
Quit,
}
impl Leaf {
pub(crate) fn run(&self) -> Result<()> {
match self {
Expand Down Expand Up @@ -74,15 +44,6 @@ impl Leaf {
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum KeymapEntry {
Leaf(Leaf),
Node {
name: &'static str,
map: HashMap<&'static str, KeymapEntry>,
},
}

impl KeymapEntry {
pub(crate) fn is_mode(&self) -> bool {
match self {
Expand All @@ -105,18 +66,6 @@ impl KeymapEntry {
}
}

impl PartialOrd for KeymapEntry {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.get_name().partial_cmp(other.get_name())
}
}

impl Ord for KeymapEntry {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.get_name().cmp(other.get_name())
}
}

impl Default for KeymapEntry {
fn default() -> Self {
Self::Node {
Expand All @@ -125,102 +74,3 @@ impl Default for KeymapEntry {
}
}
}

impl KeymapEntry {
pub(crate) fn run(&self, input_value: &str) {
if let Some(KeymapEntry::Leaf(leaf)) =
input_value.chars().fold(Some(self), |acc, key| match acc {
Some(current_map) => match current_map {
KeymapEntry::Leaf { .. } => None,
KeymapEntry::Node { map, .. } => map.get(&*key.to_string()),
},
None => None,
})
{
leaf.run().unwrap();
}
}
}

impl Display for KeymapEntry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
KeymapEntry::Leaf(leaf) => match leaf {
Leaf::GoToOrLaunch(GoToOrLaunch {
launch: Launch { name, .. },
..
}) => write!(f, "{name}"),
Leaf::Launch(Launch { name, .. }) | Leaf::LaunchNoQuit(Launch { name, .. }) => {
write!(f, "{name}")
}
Leaf::Quit => write!(f, "Quit"),
},
KeymapEntry::Node { map, .. } => {
for (key, value) in map.iter().sorted() {
let key = if key == &" " { "<space>" } else { key };
let formatted_value = match value {
KeymapEntry::Leaf(leaf) => match leaf {
Leaf::GoToOrLaunch(GoToOrLaunch {
launch: Launch { name, .. },
..
}) => name.to_string(),
Leaf::Launch(Launch { name, .. }) | Leaf::LaunchNoQuit(Launch { name, .. }) => {
name.to_string()
}
Leaf::Quit => "Quit".to_string(),
},
KeymapEntry::Node { name, .. } => format!("m::{name}"),
};
writeln!(f, "{key: >7} => {formatted_value}")?
}
Ok(())
}
}
}
}

impl KeymapEntry {
pub(crate) fn view(&self, input: &str) -> Element<Message> {
let current_map = input.chars().fold(Some(self), |acc, key| match acc {
Some(current_map) => match current_map {
KeymapEntry::Leaf { .. } => None,
KeymapEntry::Node { map, .. } => map.get(&*key.to_string()),
},
None => None,
});
if let Some(KeymapEntry::Node { map, .. }) = current_map {
column(
map
.iter()
.map(|(key, value)| {
let key = if key == &" " { "<space>" } else { key };
let key = text(format!("{key: >7}"))
.font(Font::External {
name: "Roboto",
bytes: &ROBOTO,
})
.size(16)
.style(color!(0xcb4b16));

let value = text(value.get_name())
.font(Font::External {
name: "Roboto",
bytes: &ROBOTO,
})
.size(16)
.style(if value.is_mode() {
color!(0x2aa198)
} else {
color!(0xfdf6e3)
});

row![key, value].spacing(8).into()
})
.collect(),
)
.into()
} else {
column![].into()
}
}
}
Loading

0 comments on commit 161e1a4

Please sign in to comment.