rework wrap mode

This commit is contained in:
Alexander Mohr 2025-04-21 17:27:28 +02:00
parent d08893d545
commit a655658493
3 changed files with 67 additions and 62 deletions

View file

@ -38,6 +38,7 @@ layerrule = blur, worf
because worf is build on GTK4 instead of GTK3 there will be differences in the look and feel.
* Configuration files are not 100% compatible, Worf is using toml files instead, for most part this only means strings have to be quoted
* Color files are not supported
* `line_wrap` is now called `line-wrap`
## Dropped arguments
* `mode`, use show

View file

@ -51,6 +51,13 @@ pub enum Animation {
ExpandHorizontal,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum WrapMode {
None,
Word,
Inherit,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Mode {
/// searches `$PATH` for executables and allows them to be run by selecting them.
@ -90,7 +97,22 @@ impl FromStr for Mode {
"math" => Ok(Mode::Math),
"auto" => Ok(Mode::Auto),
_ => Err(ArgsError::InvalidParameter(
format!("{s} is not a valid argument show this, see help for details").to_owned(),
format!("{s} is not a valid argument, see help for details").to_owned(),
)),
}
}
}
impl FromStr for WrapMode {
type Err = ArgsError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"none" => Ok(WrapMode::None),
"word" => Ok(WrapMode::Word),
"inherit" => Ok(WrapMode::Inherit),
_ => Err(ArgsError::InvalidParameter(
format!("{s} is not a valid argument, see help for details").to_owned(),
)),
}
}
@ -215,19 +237,23 @@ pub struct Config {
#[clap(long = "orientation")]
pub orientation: Option<Orientation>,
/// Horizontal alignment
#[serde(default = "default_halign")]
#[clap(long = "halign")]
pub halign: Option<Align>,
/// Alignment of content
#[serde(default = "default_content_halign")]
#[clap(long = "content-halign")]
pub content_halign: Option<Align>,
/// Vertical alignment
#[clap(long = "valign")]
pub valign: Option<Align>,
pub filter_rate: Option<u32>,
/// Defines the image size in pixels
#[serde(default = "default_image_size")]
#[clap(long = "image-size")]
pub image_size: Option<i32>,
@ -249,7 +275,6 @@ pub struct Config {
// todo re-add this
// #[serde(flatten)]
// pub key_custom: Option<HashMap<String, String>>,
pub line_wrap: Option<String>,
pub global_coords: Option<bool>,
pub hide_search: Option<bool>,
pub dynamic_lines: Option<bool>,
@ -268,17 +293,16 @@ pub struct Config {
#[clap(long = "row-box-orientation")]
pub row_bow_orientation: Option<Orientation>,
/// Set to to true to wrap text after a given amount of chars
#[serde(default = "default_text_wrap")]
#[clap(long = "text-wrap")]
pub text_wrap: Option<bool>,
/// Defines after how many chars a line is broken over.
/// Only cuts at spaces.
#[serde(default = "default_text_wrap_length")]
#[clap(long = "text-wrap-length")]
pub text_wrap_length: Option<usize>,
// /// Set to to true to wrap text after a given amount of chars
// #[serde(default = "default_text_wrap")]
// #[clap(long = "text-wrap")]
// pub text_wrap: Option<bool>,
//
// /// Defines after how many chars a line is broken over.
// /// Only cuts at spaces.
// #[serde(default = "default_text_wrap_length")]
// #[clap(long = "text-wrap-length")]
// pub text_wrap_length: Option<usize>,
/// Defines the animation when the window is show.
/// Defaults to Expand
#[serde(default = "default_show_animation")]
@ -303,6 +327,10 @@ pub struct Config {
#[serde(default = "default_hide_animation_time")]
#[clap(long = "hide-animation-time")]
pub hide_animation_time: Option<u64>,
#[serde(default = "default_line_wrap")]
#[clap(long = "line-wrap")]
pub line_wrap: Option<WrapMode>,
}
impl Default for Config {
@ -359,7 +387,7 @@ impl Default for Config {
key_hide_search: None,
key_copy: None,
//key_custom: None,
line_wrap: None,
line_wrap: default_line_wrap(),
global_coords: None,
hide_search: None,
dynamic_lines: None,
@ -369,8 +397,6 @@ impl Default for Config {
pre_display_exec: None,
fuzzy_min_score: default_fuzzy_min_score(),
row_bow_orientation: default_row_box_orientation(),
text_wrap: default_text_wrap(),
text_wrap_length: default_text_wrap_length(),
show_animation: default_show_animation(),
show_animation_time: default_show_animation_time(),
hide_animation: default_hide_animation(),
@ -449,6 +475,13 @@ pub fn default_normal_window() -> bool {
false
}
// allowed because option is needed for serde macro
#[allow(clippy::unnecessary_wraps)]
#[must_use]
pub fn default_line_wrap() -> Option<WrapMode> {
Some(WrapMode::Word)
}
// TODO
// GtkOrientation orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "vertical", "horizontal");
// outer_orientation = config_get_mnemonic(cstoonfig, "orientation", "vertical", 2, "horizontal", "vertical");
@ -588,20 +621,6 @@ pub fn default_image_size() -> Option<i32> {
Some(32)
}
// allowed because option is needed for serde macro
#[allow(clippy::unnecessary_wraps)]
#[must_use]
pub fn default_text_wrap_length() -> Option<usize> {
Some(15)
}
// allowed because option is needed for serde macro
#[allow(clippy::unnecessary_wraps)]
#[must_use]
pub fn default_text_wrap() -> Option<bool> {
Some(false)
}
#[must_use]
pub fn parse_args() -> Config {
Config::parse()

View file

@ -15,16 +15,13 @@ use gtk4::prelude::{
ApplicationExt, ApplicationExtManual, BoxExt, EditableExt, FlowBoxChildExt, GestureSingleExt,
GtkWindowExt, ListBoxRowExt, NativeExt, WidgetExt,
};
use gtk4::{
Align, EventControllerKey, Expander, FlowBox, FlowBoxChild, GestureClick, Image, Label,
ListBox, ListBoxRow, Ordering, PolicyType, ScrolledWindow, SearchEntry, Widget, gdk,
};
use gtk4::{Align, EventControllerKey, Expander, FlowBox, FlowBoxChild, GestureClick, Image, Label, ListBox, ListBoxRow, Ordering, PolicyType, ScrolledWindow, SearchEntry, Widget, gdk, NaturalWrapMode};
use gtk4::{Application, ApplicationWindow, CssProvider, Orientation};
use gtk4_layer_shell::{Edge, KeyboardMode, LayerShell};
use log;
use crate::config;
use crate::config::{Animation, Config, MatchMethod};
use crate::config::{Animation, Config, MatchMethod, WrapMode};
type ArcMenuMap<T> = Arc<Mutex<HashMap<FlowBoxChild, MenuItem<T>>>>;
type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T>>>;
@ -44,6 +41,16 @@ impl From<config::Orientation> for Orientation {
}
}
impl From<&WrapMode> for NaturalWrapMode {
fn from(value: &WrapMode) -> Self {
match value {
WrapMode::None => {NaturalWrapMode::None},
WrapMode::Word => {NaturalWrapMode::Word},
WrapMode::Inherit => {NaturalWrapMode::Inherit},
}
}
}
impl From<config::Align> for Align {
fn from(align: config::Align) -> Self {
match align {
@ -808,14 +815,14 @@ fn create_menu_row<T: Clone + 'static>(
row_box.append(&image);
}
// todo make max length configurable
let text = if config.text_wrap.is_some_and(|x| x) {
&wrap_text(&menu_item.label, config.text_wrap_length)
let label = Label::new(Some(menu_item.label.as_str()));
let wrap_mode : NaturalWrapMode = if let Some(config_wrap) = &config.line_wrap {
config_wrap.into()
} else {
menu_item.label.as_str()
NaturalWrapMode::Word
};
let label = Label::new(Some(text));
label.set_natural_wrap_mode(wrap_mode);
label.set_hexpand(true);
label.set_widget_name("label");
label.set_wrap(true);
@ -955,25 +962,3 @@ pub fn sort_menu_items_alphabetically_honor_initial_score<T: std::clone::Clone>(
}
}
}
fn wrap_text(text: &str, line_length: Option<usize>) -> String {
let mut result = String::new();
let mut line = String::new();
let len = line_length.unwrap_or(text.len());
for word in text.split_whitespace() {
if line.len() + word.len() + 1 > len && !line.is_empty() {
result.push_str(line.trim_end());
result.push('\n');
line.clear();
}
line.push_str(word);
line.push(' ');
}
if !line.is_empty() {
result.push_str(line.trim_end());
}
result
}