rework wrap mode
This commit is contained in:
parent
d08893d545
commit
a655658493
3 changed files with 67 additions and 62 deletions
|
@ -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.
|
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
|
* 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
|
* Color files are not supported
|
||||||
|
* `line_wrap` is now called `line-wrap`
|
||||||
|
|
||||||
## Dropped arguments
|
## Dropped arguments
|
||||||
* `mode`, use show
|
* `mode`, use show
|
||||||
|
|
|
@ -51,6 +51,13 @@ pub enum Animation {
|
||||||
ExpandHorizontal,
|
ExpandHorizontal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum WrapMode {
|
||||||
|
None,
|
||||||
|
Word,
|
||||||
|
Inherit,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
/// searches `$PATH` for executables and allows them to be run by selecting them.
|
/// 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),
|
"math" => Ok(Mode::Math),
|
||||||
"auto" => Ok(Mode::Auto),
|
"auto" => Ok(Mode::Auto),
|
||||||
_ => Err(ArgsError::InvalidParameter(
|
_ => 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")]
|
#[clap(long = "orientation")]
|
||||||
pub orientation: Option<Orientation>,
|
pub orientation: Option<Orientation>,
|
||||||
|
|
||||||
|
/// Horizontal alignment
|
||||||
#[serde(default = "default_halign")]
|
#[serde(default = "default_halign")]
|
||||||
#[clap(long = "halign")]
|
#[clap(long = "halign")]
|
||||||
pub halign: Option<Align>,
|
pub halign: Option<Align>,
|
||||||
|
|
||||||
|
/// Alignment of content
|
||||||
#[serde(default = "default_content_halign")]
|
#[serde(default = "default_content_halign")]
|
||||||
#[clap(long = "content-halign")]
|
#[clap(long = "content-halign")]
|
||||||
pub content_halign: Option<Align>,
|
pub content_halign: Option<Align>,
|
||||||
|
|
||||||
|
/// Vertical alignment
|
||||||
#[clap(long = "valign")]
|
#[clap(long = "valign")]
|
||||||
pub valign: Option<Align>,
|
pub valign: Option<Align>,
|
||||||
|
|
||||||
pub filter_rate: Option<u32>,
|
pub filter_rate: Option<u32>,
|
||||||
|
|
||||||
|
/// Defines the image size in pixels
|
||||||
#[serde(default = "default_image_size")]
|
#[serde(default = "default_image_size")]
|
||||||
#[clap(long = "image-size")]
|
#[clap(long = "image-size")]
|
||||||
pub image_size: Option<i32>,
|
pub image_size: Option<i32>,
|
||||||
|
@ -249,7 +275,6 @@ pub struct Config {
|
||||||
// todo re-add this
|
// todo re-add this
|
||||||
// #[serde(flatten)]
|
// #[serde(flatten)]
|
||||||
// pub key_custom: Option<HashMap<String, String>>,
|
// pub key_custom: Option<HashMap<String, String>>,
|
||||||
pub line_wrap: Option<String>,
|
|
||||||
pub global_coords: Option<bool>,
|
pub global_coords: Option<bool>,
|
||||||
pub hide_search: Option<bool>,
|
pub hide_search: Option<bool>,
|
||||||
pub dynamic_lines: Option<bool>,
|
pub dynamic_lines: Option<bool>,
|
||||||
|
@ -268,17 +293,16 @@ pub struct Config {
|
||||||
#[clap(long = "row-box-orientation")]
|
#[clap(long = "row-box-orientation")]
|
||||||
pub row_bow_orientation: Option<Orientation>,
|
pub row_bow_orientation: Option<Orientation>,
|
||||||
|
|
||||||
/// Set to to true to wrap text after a given amount of chars
|
// /// Set to to true to wrap text after a given amount of chars
|
||||||
#[serde(default = "default_text_wrap")]
|
// #[serde(default = "default_text_wrap")]
|
||||||
#[clap(long = "text-wrap")]
|
// #[clap(long = "text-wrap")]
|
||||||
pub text_wrap: Option<bool>,
|
// pub text_wrap: Option<bool>,
|
||||||
|
//
|
||||||
/// Defines after how many chars a line is broken over.
|
// /// Defines after how many chars a line is broken over.
|
||||||
/// Only cuts at spaces.
|
// /// Only cuts at spaces.
|
||||||
#[serde(default = "default_text_wrap_length")]
|
// #[serde(default = "default_text_wrap_length")]
|
||||||
#[clap(long = "text-wrap-length")]
|
// #[clap(long = "text-wrap-length")]
|
||||||
pub text_wrap_length: Option<usize>,
|
// pub text_wrap_length: Option<usize>,
|
||||||
|
|
||||||
/// Defines the animation when the window is show.
|
/// Defines the animation when the window is show.
|
||||||
/// Defaults to Expand
|
/// Defaults to Expand
|
||||||
#[serde(default = "default_show_animation")]
|
#[serde(default = "default_show_animation")]
|
||||||
|
@ -303,6 +327,10 @@ pub struct Config {
|
||||||
#[serde(default = "default_hide_animation_time")]
|
#[serde(default = "default_hide_animation_time")]
|
||||||
#[clap(long = "hide-animation-time")]
|
#[clap(long = "hide-animation-time")]
|
||||||
pub hide_animation_time: Option<u64>,
|
pub hide_animation_time: Option<u64>,
|
||||||
|
|
||||||
|
#[serde(default = "default_line_wrap")]
|
||||||
|
#[clap(long = "line-wrap")]
|
||||||
|
pub line_wrap: Option<WrapMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
@ -359,7 +387,7 @@ impl Default for Config {
|
||||||
key_hide_search: None,
|
key_hide_search: None,
|
||||||
key_copy: None,
|
key_copy: None,
|
||||||
//key_custom: None,
|
//key_custom: None,
|
||||||
line_wrap: None,
|
line_wrap: default_line_wrap(),
|
||||||
global_coords: None,
|
global_coords: None,
|
||||||
hide_search: None,
|
hide_search: None,
|
||||||
dynamic_lines: None,
|
dynamic_lines: None,
|
||||||
|
@ -369,8 +397,6 @@ impl Default for Config {
|
||||||
pre_display_exec: None,
|
pre_display_exec: None,
|
||||||
fuzzy_min_score: default_fuzzy_min_score(),
|
fuzzy_min_score: default_fuzzy_min_score(),
|
||||||
row_bow_orientation: default_row_box_orientation(),
|
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: default_show_animation(),
|
||||||
show_animation_time: default_show_animation_time(),
|
show_animation_time: default_show_animation_time(),
|
||||||
hide_animation: default_hide_animation(),
|
hide_animation: default_hide_animation(),
|
||||||
|
@ -449,6 +475,13 @@ pub fn default_normal_window() -> bool {
|
||||||
false
|
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
|
// TODO
|
||||||
// GtkOrientation orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "vertical", "horizontal");
|
// GtkOrientation orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "vertical", "horizontal");
|
||||||
// outer_orientation = config_get_mnemonic(cstoonfig, "orientation", "vertical", 2, "horizontal", "vertical");
|
// outer_orientation = config_get_mnemonic(cstoonfig, "orientation", "vertical", 2, "horizontal", "vertical");
|
||||||
|
@ -588,20 +621,6 @@ pub fn default_image_size() -> Option<i32> {
|
||||||
Some(32)
|
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]
|
#[must_use]
|
||||||
pub fn parse_args() -> Config {
|
pub fn parse_args() -> Config {
|
||||||
Config::parse()
|
Config::parse()
|
||||||
|
|
|
@ -15,16 +15,13 @@ use gtk4::prelude::{
|
||||||
ApplicationExt, ApplicationExtManual, BoxExt, EditableExt, FlowBoxChildExt, GestureSingleExt,
|
ApplicationExt, ApplicationExtManual, BoxExt, EditableExt, FlowBoxChildExt, GestureSingleExt,
|
||||||
GtkWindowExt, ListBoxRowExt, NativeExt, WidgetExt,
|
GtkWindowExt, ListBoxRowExt, NativeExt, WidgetExt,
|
||||||
};
|
};
|
||||||
use gtk4::{
|
use gtk4::{Align, EventControllerKey, Expander, FlowBox, FlowBoxChild, GestureClick, Image, Label, ListBox, ListBoxRow, Ordering, PolicyType, ScrolledWindow, SearchEntry, Widget, gdk, NaturalWrapMode};
|
||||||
Align, EventControllerKey, Expander, FlowBox, FlowBoxChild, GestureClick, Image, Label,
|
|
||||||
ListBox, ListBoxRow, Ordering, PolicyType, ScrolledWindow, SearchEntry, Widget, gdk,
|
|
||||||
};
|
|
||||||
use gtk4::{Application, ApplicationWindow, CssProvider, Orientation};
|
use gtk4::{Application, ApplicationWindow, CssProvider, Orientation};
|
||||||
use gtk4_layer_shell::{Edge, KeyboardMode, LayerShell};
|
use gtk4_layer_shell::{Edge, KeyboardMode, LayerShell};
|
||||||
use log;
|
use log;
|
||||||
|
|
||||||
use crate::config;
|
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 ArcMenuMap<T> = Arc<Mutex<HashMap<FlowBoxChild, MenuItem<T>>>>;
|
||||||
type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<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 {
|
impl From<config::Align> for Align {
|
||||||
fn from(align: config::Align) -> Self {
|
fn from(align: config::Align) -> Self {
|
||||||
match align {
|
match align {
|
||||||
|
@ -808,14 +815,14 @@ fn create_menu_row<T: Clone + 'static>(
|
||||||
row_box.append(&image);
|
row_box.append(&image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo make max length configurable
|
let label = Label::new(Some(menu_item.label.as_str()));
|
||||||
let text = if config.text_wrap.is_some_and(|x| x) {
|
let wrap_mode : NaturalWrapMode = if let Some(config_wrap) = &config.line_wrap {
|
||||||
&wrap_text(&menu_item.label, config.text_wrap_length)
|
config_wrap.into()
|
||||||
} else {
|
} 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_hexpand(true);
|
||||||
label.set_widget_name("label");
|
label.set_widget_name("label");
|
||||||
label.set_wrap(true);
|
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
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue