Skip to content

Commit

Permalink
refactor: add scrollable list after 8 items
Browse files Browse the repository at this point in the history
  • Loading branch information
wash2 committed Jan 16, 2025
1 parent 70153f4 commit 303ca20
Showing 1 changed file with 69 additions and 19 deletions.
88 changes: 69 additions & 19 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ use cosmic::iced::platform_specific::shell::commands::{
use cosmic::iced::widget::{column, container, Column};
use cosmic::iced::{self, Length, Subscription};
use cosmic::iced_core::keyboard::key::Named;
use cosmic::iced_core::widget::operation;
use cosmic::iced_core::{window, Border, Padding, Point, Rectangle, Shadow};
use cosmic::iced_runtime;
use cosmic::iced_runtime::core::event::wayland::LayerEvent;
use cosmic::iced_runtime::core::event::{wayland, PlatformSpecific};
use cosmic::iced_runtime::core::layout::Limits;
use cosmic::iced_runtime::core::window::Id as SurfaceId;
use cosmic::iced_runtime::platform_specific::wayland::layer_surface::IcedMargin;
use cosmic::iced_widget::row;
use cosmic::iced_widget::scrollable::RelativeOffset;
use cosmic::theme::{self, Button, Container};
use cosmic::widget::icon::{from_name, IconFallback};
use cosmic::widget::id_container;
Expand All @@ -35,10 +38,10 @@ use cosmic::widget::{
use cosmic::{keyboard_nav, Element};
use iced::keyboard::Key;
use iced::{Alignment, Color};
use once_cell::sync::Lazy;
use pop_launcher::{ContextOption, GpuPreference, IconSource, SearchResult};
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use std::sync::LazyLock;
use std::{
collections::{HashMap, VecDeque},
rc::Rc,
Expand All @@ -50,17 +53,13 @@ use tracing::{debug, error, info};
use unicode_truncate::UnicodeTruncateStr;
use unicode_width::UnicodeWidthStr;

static AUTOSIZE_ID: Lazy<Id> = Lazy::new(|| Id::new("autosize"));
static MAIN_ID: Lazy<Id> = Lazy::new(|| Id::new("main"));
static INPUT_ID: Lazy<Id> = Lazy::new(|| Id::new("input_id"));
static RESULT_IDS: Lazy<[Id; 10]> = Lazy::new(|| {
(0..10)
.map(|id| Id::new(id.to_string()))
.collect::<Vec<_>>()
.try_into()
.unwrap()
});
pub(crate) static MENU_ID: Lazy<SurfaceId> = Lazy::new(SurfaceId::unique);
static AUTOSIZE_ID: LazyLock<Id> = LazyLock::new(|| Id::new("autosize"));
static MAIN_ID: LazyLock<Id> = LazyLock::new(|| Id::new("main"));
static INPUT_ID: LazyLock<Id> = LazyLock::new(|| Id::new("input_id"));
static SCROLLABLE: LazyLock<Id> = LazyLock::new(|| Id::new("scrollable"));

pub(crate) static MENU_ID: LazyLock<SurfaceId> = LazyLock::new(SurfaceId::unique);
const SCROLL_MIN: usize = 8;

#[derive(Parser, Debug, Serialize, Deserialize, Clone)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -152,6 +151,7 @@ pub struct CosmicLauncher {
alt_tab: bool,
window_id: window::Id,
queue: VecDeque<Message>,
result_ids: Vec<Id>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -292,6 +292,9 @@ impl cosmic::Application for CosmicLauncher {
alt_tab: false,
window_id: SurfaceId::unique(),
queue: VecDeque::new(),
result_ids: (0..10)
.map(|id| Id::new(id.to_string()))
.collect::<Vec<_>>(),
},
Task::none(),
)
Expand Down Expand Up @@ -320,12 +323,13 @@ impl cosmic::Application for CosmicLauncher {
let focused = self.focused;
self.focused = 0;
return cosmic::task::message(cosmic::app::Message::App(
Self::Message::CompleteFocusedId(RESULT_IDS[focused].clone()),
Self::Message::CompleteFocusedId(self.result_ids[focused].clone()),
));
}
Message::TabPress => {}
Message::CompleteFocusedId(id) => {
let i = RESULT_IDS
let i = self
.result_ids
.iter()
.position(|res_id| res_id == &id)
.unwrap_or_default();
Expand Down Expand Up @@ -447,9 +451,15 @@ impl cosmic::Application for CosmicLauncher {
let b = i32::from(b.window.is_none());
a.cmp(&b)
});
list.truncate(10);
self.launcher_items.splice(.., list);

if self.result_ids.len() > self.launcher_items.len() {
self.result_ids.extend(
(self.launcher_items.len() - self.result_ids.len()
..self.launcher_items.len())
.map(|id| Id::new(id.to_string()))
.collect::<Vec<_>>(),
);
}
let mut cmds = Vec::new();

while let Some(element) = self.queue.pop_front() {
Expand Down Expand Up @@ -490,9 +500,28 @@ impl cosmic::Application for CosmicLauncher {
match e {
keyboard_nav::Message::FocusNext => {
self.focus_next();
// TODO ideally we could use an operation to scroll exactly to a specific widget.
return iced_runtime::task::widget(operation::scrollable::snap_to(
SCROLLABLE.clone(),
RelativeOffset {
x: 0.,
y: (self.focused as f32
/ (self.launcher_items.len() as f32 - 1.).max(1.))
.max(0.0),
},
));
}
keyboard_nav::Message::FocusPrevious => {
self.focus_previous();
return iced_runtime::task::widget(operation::scrollable::snap_to(
SCROLLABLE.clone(),
RelativeOffset {
x: 0.,
y: (self.focused as f32
/ (self.launcher_items.len() as f32 - 1.).max(1.))
.max(0.0),
},
));
}
keyboard_nav::Message::Escape => {
self.input_value.clear();
Expand All @@ -508,9 +537,25 @@ impl cosmic::Application for CosmicLauncher {
}
Message::AltTab => {
self.focus_next();
return iced_runtime::task::widget(operation::scrollable::snap_to(
SCROLLABLE.clone(),
RelativeOffset {
x: 0.,
y: (self.focused as f32 / (self.launcher_items.len() as f32 - 1.).max(1.))
.max(0.0),
},
));
}
Message::ShiftAltTab => {
self.focus_previous();
return iced_runtime::task::widget(operation::scrollable::snap_to(
SCROLLABLE.clone(),
RelativeOffset {
x: 0.,
y: (self.focused as f32 / (self.launcher_items.len() as f32 - 1.).max(1.))
.max(0.0),
},
));
}
Message::AltRelease => {
if self.alt_tab {
Expand Down Expand Up @@ -700,7 +745,7 @@ impl cosmic::Application for CosmicLauncher {
cosmic::widget::button::custom(
row(button_content).spacing(8).align_y(Alignment::Center),
)
.id(RESULT_IDS[i].clone())
.id(self.result_ids[i].clone())
.width(Length::Fill)
.on_press(Message::Activate(Some(i)))
.padding([8, 24])
Expand Down Expand Up @@ -786,9 +831,14 @@ impl cosmic::Application for CosmicLauncher {
.spacing(16)
};

if !buttons.is_empty() {
if buttons.len() > SCROLL_MIN {
content = content.push(
container(scrollable(components::list::column(buttons)).id(SCROLLABLE.clone()))
.max_height(504),
);
} else if !buttons.is_empty() {
content = content.push(components::list::column(buttons));
}
};

let window = container(id_container(content, MAIN_ID.clone()))
.width(Length::Shrink)
Expand Down

0 comments on commit 303ca20

Please sign in to comment.