Implement primary and secondary shortcuts

This commit is contained in:
Exidex 2024-10-04 21:10:41 +02:00
parent 947502e628
commit f07795b76f
No known key found for this signature in database
GPG key ID: 46D8D21671EB48FA
5 changed files with 175 additions and 77 deletions

24
Cargo.lock generated
View file

@ -4061,7 +4061,7 @@ dependencies = [
[[package]]
name = "iced"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"iced_core",
"iced_futures",
@ -4090,7 +4090,7 @@ dependencies = [
[[package]]
name = "iced_core"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"bitflags 2.5.0",
"glam",
@ -4108,7 +4108,7 @@ dependencies = [
[[package]]
name = "iced_futures"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"futures",
"iced_core",
@ -4121,7 +4121,7 @@ dependencies = [
[[package]]
name = "iced_graphics"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"bitflags 2.5.0",
"bytemuck",
@ -4143,7 +4143,7 @@ dependencies = [
[[package]]
name = "iced_renderer"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@ -4155,7 +4155,7 @@ dependencies = [
[[package]]
name = "iced_runtime"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"iced_core",
"iced_futures",
@ -4167,7 +4167,7 @@ dependencies = [
[[package]]
name = "iced_sctk"
version = "0.1.0"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"enum-repr",
"float-cmp",
@ -4193,7 +4193,7 @@ dependencies = [
[[package]]
name = "iced_style"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"iced_core",
"once_cell",
@ -4213,7 +4213,7 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"bytemuck",
"cosmic-text",
@ -4229,7 +4229,7 @@ dependencies = [
[[package]]
name = "iced_wgpu"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"bitflags 2.5.0",
"bytemuck",
@ -4246,7 +4246,7 @@ dependencies = [
[[package]]
name = "iced_widget"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"iced_renderer",
"iced_runtime",
@ -4260,7 +4260,7 @@ dependencies = [
[[package]]
name = "iced_winit"
version = "0.12.3"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#6d56c953989e9d6795f761f40e135842d60216d4"
source = "git+https://github.com/project-gauntlet/iced.git?branch=gauntlet#056421da9e60f212fc948868e107626ddd04e13f"
dependencies = [
"iced_graphics",
"iced_runtime",

View file

@ -434,7 +434,9 @@ impl Application for AppModel {
_ => Command::none()
}
}
AppMsg::PromptSubmit => self.global_state.enter(&self.search_results),
AppMsg::PromptSubmit => {
self.global_state.primary(&self.search_results)
},
AppMsg::SetSearchResults(new_search_results) => {
self.search_results = new_search_results;
@ -471,12 +473,20 @@ impl Application for AppModel {
keyboard::Event::KeyPressed { key, modifiers, physical_key, text, .. } => {
tracing::debug!("Key pressed: {:?}. shift: {:?} control: {:?} alt: {:?} meta: {:?}", key, modifiers.shift(), modifiers.control(), modifiers.alt(), modifiers.logo());
match key {
Key::Named(Named::ArrowUp) => self.global_state.arrow_up(&self.search_results),
Key::Named(Named::ArrowDown) => self.global_state.arrow_down(&self.search_results),
Key::Named(Named::Escape) => self.global_state.escape(),
Key::Named(Named::ArrowUp) => self.global_state.up(&self.search_results),
Key::Named(Named::ArrowDown) => self.global_state.down(&self.search_results),
Key::Named(Named::Escape) => self.global_state.back(),
Key::Named(Named::Enter) => {
// for main view, also fired in cases where main text field is not focused
self.global_state.enter(&self.search_results)
if modifiers.logo() || modifiers.alt() || modifiers.control() {
Command::none() // to avoid not wanted "enter" presses
} else {
if modifiers.shift() {
// for main view, also fired in cases where main text field is not focused
self.global_state.secondary(&self.search_results)
} else {
self.global_state.primary(&self.search_results)
}
}
},
Key::Named(Named::Backspace) => {
match &mut self.global_state {
@ -552,7 +562,7 @@ impl Application for AppModel {
self.hide_window()
}
AppMsg::IcedEvent(_) => Command::none(),
AppMsg::WidgetEvent { widget_event: ComponentWidgetEvent::PreviousView, .. } => self.global_state.escape(),
AppMsg::WidgetEvent { widget_event: ComponentWidgetEvent::PreviousView, .. } => self.global_state.back(),
AppMsg::WidgetEvent { widget_event, plugin_id, render_location } => {
self.handle_plugin_event(widget_event, plugin_id, render_location)
}
@ -619,25 +629,43 @@ impl Application for AppModel {
Command::none()
}
AppMsg::RunSearchItemAction(search_result, action_index) => {
let event = match search_result.entrypoint_type {
SearchResultEntrypointType::Command => AppMsg::RunCommand {
entrypoint_id: search_result.entrypoint_id.clone(),
plugin_id: search_result.plugin_id.clone()
match search_result.entrypoint_type {
SearchResultEntrypointType::Command => {
match action_index {
None => {
let msg = AppMsg::RunCommand {
entrypoint_id: search_result.entrypoint_id.clone(),
plugin_id: search_result.plugin_id.clone()
};
Command::perform(async {}, |_| msg)
}
Some(_) => Command::none()
}
},
SearchResultEntrypointType::View => AppMsg::OpenView {
plugin_id: search_result.plugin_id.clone(),
plugin_name: search_result.plugin_name.clone(),
entrypoint_id: search_result.entrypoint_id.clone(),
entrypoint_name: search_result.entrypoint_name.clone(),
SearchResultEntrypointType::View => {
match action_index {
None => {
let msg = AppMsg::OpenView {
plugin_id: search_result.plugin_id.clone(),
plugin_name: search_result.plugin_name.clone(),
entrypoint_id: search_result.entrypoint_id.clone(),
entrypoint_name: search_result.entrypoint_name.clone(),
};
Command::perform(async {}, |_| msg)
}
Some(_) => Command::none()
}
},
SearchResultEntrypointType::GeneratedCommand => AppMsg::RunGeneratedCommandEvent {
entrypoint_id: search_result.entrypoint_id.clone(),
plugin_id: search_result.plugin_id.clone(),
action_index,
},
};
SearchResultEntrypointType::GeneratedCommand => {
let msg = AppMsg::RunGeneratedCommandEvent {
entrypoint_id: search_result.entrypoint_id.clone(),
plugin_id: search_result.plugin_id.clone(),
action_index,
};
Command::perform(async {}, |_| event)
Command::perform(async {}, |_| msg)
},
}
}
AppMsg::Screenshot { save_path } => {
println!("Creating screenshot at: {}", save_path);
@ -752,7 +780,19 @@ impl Application for AppModel {
GlobalState::ErrorView { .. } => Command::none(),
GlobalState::PluginView { client_context, sub_state, .. } => {
match sub_state {
PluginViewState::None => Command::none(),
PluginViewState::None => {
let client_context = client_context.read().expect("lock is poisoned");
let plugin_id = client_context.get_view_plugin_id();
let widget_event = ComponentWidgetEvent::RunAction {
widget_id,
};
let render_location = UiRenderLocation::View;
Command::perform(async {}, move |_| AppMsg::WidgetEvent { widget_event, plugin_id, render_location })
},
PluginViewState::ActionPanel { .. } => {
let client_context = client_context.read().expect("lock is poisoned");

View file

@ -29,7 +29,7 @@ impl MainViewState {
}
impl Focus<SearchResultEntrypointAction> for MainViewState {
fn enter(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
fn primary(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
match self {
MainViewState::None => {
panic!("invalid state")
@ -42,7 +42,12 @@ impl Focus<SearchResultEntrypointAction> for MainViewState {
}
}
fn escape(&mut self) -> Command<AppMsg> {
fn secondary(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
// secondary action doesn't do anything when action panel is open
panic!("invalid state")
}
fn back(&mut self) -> Command<AppMsg> {
match self {
MainViewState::None => {
Command::perform(async {}, |_| AppMsg::HideWindow)
@ -54,15 +59,15 @@ impl Focus<SearchResultEntrypointAction> for MainViewState {
}
}
fn tab(&mut self) -> Command<AppMsg> {
fn next(&mut self) -> Command<AppMsg> {
todo!()
}
fn shift_tab(&mut self) -> Command<AppMsg> {
fn previous(&mut self) -> Command<AppMsg> {
todo!()
}
fn arrow_up(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
fn up(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
match self {
MainViewState::None => Command::none(),
MainViewState::ActionPanel { focused_action_item, .. } => {
@ -71,7 +76,7 @@ impl Focus<SearchResultEntrypointAction> for MainViewState {
}
}
fn arrow_down(&mut self, focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
fn down(&mut self, focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
match self {
MainViewState::None => Command::none(),
MainViewState::ActionPanel { focused_action_item } => {
@ -84,11 +89,11 @@ impl Focus<SearchResultEntrypointAction> for MainViewState {
}
}
fn arrow_left(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
fn left(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
todo!()
}
fn arrow_right(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
fn right(&mut self, _focus_list: &[SearchResultEntrypointAction]) -> Command<AppMsg> {
todo!()
}
}

View file

@ -119,18 +119,19 @@ impl GlobalState {
}
pub trait Focus<T> {
fn enter(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn escape(&mut self) -> Command<AppMsg>;
fn tab(&mut self) -> Command<AppMsg>;
fn shift_tab(&mut self) -> Command<AppMsg>;
fn arrow_up(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn arrow_down(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn arrow_left(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn arrow_right(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn primary(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn secondary(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn back(&mut self) -> Command<AppMsg>;
fn next(&mut self) -> Command<AppMsg>;
fn previous(&mut self) -> Command<AppMsg>;
fn up(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn down(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn left(&mut self, focus_list: &[T]) -> Command<AppMsg>;
fn right(&mut self, focus_list: &[T]) -> Command<AppMsg>;
}
impl Focus<SearchResult> for GlobalState {
fn enter(&mut self, focus_list: &[SearchResult]) -> Command<AppMsg> {
fn primary(&mut self, focus_list: &[SearchResult]) -> Command<AppMsg> {
match self {
GlobalState::MainView { focused_search_result, sub_state, .. } => {
if let Some(search_item) = focused_search_result.get(focus_list) {
@ -140,7 +141,7 @@ impl Focus<SearchResult> for GlobalState {
Command::perform(async {}, |_| AppMsg::RunSearchItemAction(search_item, None))
}
MainViewState::ActionPanel { .. } => {
sub_state.enter(&search_item.entrypoint_actions)
sub_state.primary(&search_item.entrypoint_actions)
}
}
} else {
@ -152,16 +153,44 @@ impl Focus<SearchResult> for GlobalState {
let action_ids = client_context.get_action_ids();
sub_state.enter(&action_ids)
sub_state.primary(&action_ids)
}
GlobalState::ErrorView { .. } => Command::none()
}
}
fn escape(&mut self) -> Command<AppMsg> {
fn secondary(&mut self, focus_list: &[SearchResult]) -> Command<AppMsg> {
match self {
GlobalState::MainView { focused_search_result, sub_state, .. } => {
if let Some(search_item) = focused_search_result.get(focus_list) {
match sub_state {
MainViewState::None => {
let search_item = search_item.clone();
Command::perform(async {}, |_| AppMsg::RunSearchItemAction(search_item, Some(0)))
}
MainViewState::ActionPanel { .. } => {
Command::none()
}
}
} else {
Command::none()
}
}
GlobalState::PluginView { sub_state, client_context, .. } => {
let client_context = client_context.read().expect("lock is poisoned");
let action_ids = client_context.get_action_ids();
sub_state.secondary(&action_ids)
}
GlobalState::ErrorView { .. } => Command::none()
}
}
fn back(&mut self) -> Command<AppMsg> {
match self {
GlobalState::MainView { sub_state, .. } => {
sub_state.escape()
sub_state.back()
}
GlobalState::PluginView {
plugin_view_data: PluginViewData {
@ -189,7 +218,7 @@ impl Focus<SearchResult> for GlobalState {
}
}
PluginViewState::ActionPanel { .. } => {
sub_state.escape()
sub_state.back()
}
}
}
@ -198,21 +227,21 @@ impl Focus<SearchResult> for GlobalState {
}
}
}
fn tab(&mut self) -> Command<AppMsg> {
fn next(&mut self) -> Command<AppMsg> {
match self {
GlobalState::MainView { .. } => Command::none(),
GlobalState::PluginView { .. } => Command::none(),
GlobalState::ErrorView { .. } => Command::none(),
}
}
fn shift_tab(&mut self) -> Command<AppMsg> {
fn previous(&mut self) -> Command<AppMsg> {
match self {
GlobalState::MainView { .. } => Command::none(),
GlobalState::PluginView { .. } => Command::none(),
GlobalState::ErrorView { .. } => Command::none(),
}
}
fn arrow_up(&mut self, focus_list: &[SearchResult]) -> Command<AppMsg> {
fn up(&mut self, focus_list: &[SearchResult]) -> Command<AppMsg> {
match self {
GlobalState::MainView { focused_search_result, sub_state, .. } => {
match sub_state {
@ -221,7 +250,7 @@ impl Focus<SearchResult> for GlobalState {
}
MainViewState::ActionPanel { .. } => {
if let Some(search_item) = focused_search_result.get(focus_list) {
sub_state.arrow_up(&search_item.entrypoint_actions)
sub_state.up(&search_item.entrypoint_actions)
} else {
Command::none()
}
@ -237,13 +266,13 @@ impl Focus<SearchResult> for GlobalState {
let action_ids = client_context.get_action_ids();
sub_state.arrow_up(&action_ids)
sub_state.up(&action_ids)
}
}
},
}
}
fn arrow_down(&mut self, focus_list: &[SearchResult]) -> Command<AppMsg> {
fn down(&mut self, focus_list: &[SearchResult]) -> Command<AppMsg> {
match self {
GlobalState::MainView { focused_search_result, sub_state, .. } => {
match sub_state {
@ -256,7 +285,7 @@ impl Focus<SearchResult> for GlobalState {
}
MainViewState::ActionPanel { .. } => {
if let Some(search_item) = focused_search_result.get(focus_list) {
sub_state.arrow_down(&search_item.entrypoint_actions)
sub_state.down(&search_item.entrypoint_actions)
} else {
Command::none()
}
@ -272,20 +301,20 @@ impl Focus<SearchResult> for GlobalState {
let action_ids = client_context.get_action_ids();
sub_state.arrow_down(&action_ids)
sub_state.down(&action_ids)
}
}
}
}
}
fn arrow_left(&mut self, _focus_list: &[SearchResult]) -> Command<AppMsg> {
fn left(&mut self, _focus_list: &[SearchResult]) -> Command<AppMsg> {
match self {
GlobalState::MainView { .. } => Command::none(),
GlobalState::PluginView { .. } => Command::none(),
GlobalState::ErrorView { .. } => Command::none(),
}
}
fn arrow_right(&mut self, _focus_list: &[SearchResult]) -> Command<AppMsg> {
fn right(&mut self, _focus_list: &[SearchResult]) -> Command<AppMsg> {
match self {
GlobalState::MainView { .. } => Command::none(),
GlobalState::PluginView { .. } => Command::none(),

View file

@ -30,9 +30,16 @@ impl PluginViewState {
}
impl Focus<UiWidgetId> for PluginViewState {
fn enter(&mut self, focus_list: &[UiWidgetId]) -> Command<AppMsg> {
fn primary(&mut self, focus_list: &[UiWidgetId]) -> Command<AppMsg> {
match self {
PluginViewState::None => Command::none(),
PluginViewState::None => {
if let Some(widget_id) = focus_list.get(0) {
let widget_id = *widget_id;
Command::perform(async {}, move |_| AppMsg::OnEntrypointAction(widget_id))
} else {
Command::none()
}
},
PluginViewState::ActionPanel { focused_action_item, .. } => {
if let Some(widget_id) = focused_action_item.get(focus_list) {
let widget_id = *widget_id;
@ -44,7 +51,24 @@ impl Focus<UiWidgetId> for PluginViewState {
}
}
fn escape(&mut self) -> Command<AppMsg> {
fn secondary(&mut self, focus_list: &[UiWidgetId]) -> Command<AppMsg> {
match self {
PluginViewState::None => {
if let Some(widget_id) = focus_list.get(1) {
let widget_id = *widget_id;
Command::perform(async {}, move |_| AppMsg::OnEntrypointAction(widget_id))
} else {
Command::none()
}
},
PluginViewState::ActionPanel { .. } => {
// secondary does nothing when action panel is opened
Command::none()
}
}
}
fn back(&mut self) -> Command<AppMsg> {
match self {
PluginViewState::None => {
panic!("invalid state")
@ -55,15 +79,15 @@ impl Focus<UiWidgetId> for PluginViewState {
}
}
fn tab(&mut self) -> Command<AppMsg> {
fn next(&mut self) -> Command<AppMsg> {
todo!()
}
fn shift_tab(&mut self) -> Command<AppMsg> {
fn previous(&mut self) -> Command<AppMsg> {
todo!()
}
fn arrow_up(&mut self, _focus_list: &[UiWidgetId]) -> Command<AppMsg> {
fn up(&mut self, _focus_list: &[UiWidgetId]) -> Command<AppMsg> {
match self {
PluginViewState::None => Command::none(),
PluginViewState::ActionPanel { focused_action_item, .. } => {
@ -72,7 +96,7 @@ impl Focus<UiWidgetId> for PluginViewState {
}
}
fn arrow_down(&mut self, focus_list: &[UiWidgetId]) -> Command<AppMsg> {
fn down(&mut self, focus_list: &[UiWidgetId]) -> Command<AppMsg> {
match self {
PluginViewState::None => Command::none(),
PluginViewState::ActionPanel { focused_action_item } => {
@ -85,11 +109,11 @@ impl Focus<UiWidgetId> for PluginViewState {
}
}
fn arrow_left(&mut self, _focus_list: &[UiWidgetId]) -> Command<AppMsg> {
fn left(&mut self, _focus_list: &[UiWidgetId]) -> Command<AppMsg> {
todo!()
}
fn arrow_right(&mut self, _focus_list: &[UiWidgetId]) -> Command<AppMsg> {
fn right(&mut self, _focus_list: &[UiWidgetId]) -> Command<AppMsg> {
todo!()
}
}