support dynamic rows fixes #42
This commit is contained in:
parent
0f89e367a8
commit
9e2f4d4eac
2 changed files with 83 additions and 130 deletions
|
@ -368,7 +368,7 @@ pub struct Config {
|
|||
hide_search: Option<bool>,
|
||||
|
||||
#[clap(long = "dynamic-lines")]
|
||||
dynamic_lines: Option<bool>, // todo support this
|
||||
dynamic_lines: Option<bool>,
|
||||
|
||||
#[clap(long = "layer")]
|
||||
layer: Option<Layer>,
|
||||
|
@ -635,6 +635,11 @@ impl Config {
|
|||
pub fn layer(&self) -> Layer {
|
||||
self.layer.clone().unwrap_or(Layer::Top)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn dynamic_lines(&self) -> bool {
|
||||
self.dynamic_lines.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn default_false() -> bool {
|
||||
|
@ -645,83 +650,6 @@ fn default_false() -> bool {
|
|||
// true
|
||||
// }
|
||||
|
||||
//
|
||||
// // TODO
|
||||
// // GtkOrientation orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "vertical", "horizontal");
|
||||
// // outer_orientation = config_get_mnemonic(cstoonfig, "orientation", "vertical", 2, "horizontal", "vertical");
|
||||
// // GtkAlign halign = config_get_mnemonic(config, "halign", "fill", 4, "fill", "start", "end", "center");
|
||||
// // content_halign = config_get_mnemonic(config, "content_halign", "fill", 4, "fill", "start", "end", "center");
|
||||
// // char* default_valign = "start";
|
||||
// // if(outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
|
||||
// // default_valign = "center";
|
||||
// // }
|
||||
// // GtkAlign valign = config_get_mnemonic(config, "valign", default_valign, 4, "fill", "start", "end", "center");
|
||||
// // char* prompt = config_get(config, "prompt", mode);
|
||||
// // uint64_t filter_rate = strtol(config_get(config, "filter_rate", "100"), NULL, 10);
|
||||
// // allow_markup = strcmp(config_get(config, "allow_markup", "false"), "true") == 0;
|
||||
// // image_size = strtol(config_get(config, "image_size", "32"), NULL, 10);
|
||||
// // cache_file = map_get(config, "cache_file");
|
||||
// // config_dir = map_get(config, "config_dir");
|
||||
// // terminal = map_get(config, "term");
|
||||
// // exec_search = strcmp(config_get(config, "exec_search", "false"), "true") == 0;
|
||||
// // bool hide_scroll = strcmp(config_get(config, "hide_scroll", "false"), "true") == 0;
|
||||
// // matching = config_get_mnemonic(config, "matching", "contains", 3, "contains", "multi-contains", "fuzzy");
|
||||
// // insensitive = strcmp(config_get(config, "insensitive", "false"), "true") == 0;
|
||||
// // parse_search = strcmp(config_get(config, "parse_search", "false"), "true") == 0;
|
||||
// // location = config_get_mnemonic(config, "location", "center", 18,
|
||||
// // "center", "top_left", "top", "top_right", "right", "bottom_right", "bottom", "bottom_left", "left",
|
||||
// // "0", "1", "2", "3", "4", "5", "6", "7", "8");
|
||||
// // no_actions = strcmp(config_get(config, "no_actions", "false"), "true") == 0;
|
||||
// // lines = strtol(config_get(config, "lines", "0"), NULL, 10);
|
||||
// // max_lines = lines;
|
||||
// // columns = strtol(config_get(config, "columns", "1"), NULL, 10);
|
||||
// // sort_order = config_get_mnemonic(config, "sort_order", "default", 2, "default", "alphabetical");
|
||||
// // bool global_coords = strcmp(config_get(config, "global_coords", "false"), "true") == 0;
|
||||
// // hide_search = strcmp(config_get(config, "hide_search", "false"), "true") == 0;
|
||||
// // char* search = map_get(config, "search");
|
||||
// // dynamic_lines = strcmp(config_get(config, "dynamic_lines", "false"), "true") == 0;
|
||||
// // char* monitor = map_get(config, "monitor");
|
||||
// // char* layer = config_get(config, "layer", "top");
|
||||
// // copy_exec = config_get(config, "copy_exec", "wl-copy");
|
||||
// // pre_display_cmd = map_get(config, "pre_display_cmd");
|
||||
// // pre_display_exec = strcmp(config_get(config, "pre_display_exec", "false"), "true") == 0;
|
||||
// // single_click = strcmp(config_get(config, "single_click", "false"), "true") == 0;
|
||||
// //
|
||||
// // keys = map_init_void();
|
||||
// // mods = map_init_void();
|
||||
// //
|
||||
// // map_put_void(mods, "Shift", &shift_mask);
|
||||
// // map_put_void(mods, "Ctrl", &ctrl_mask);
|
||||
// // map_put_void(mods, "Alt", &alt_mask);
|
||||
// //
|
||||
// // key_default = "Up";
|
||||
// // char* key_up = (i == 0) ? "Up" : config_get(config, "key_up", key_default);
|
||||
// // key_default = "Down";
|
||||
// // char* key_down = (i == 0) ? key_default : config_get(config, "key_down", key_default);
|
||||
// // key_default = "Left";
|
||||
// // char* key_left = (i == 0) ? key_default : config_get(config, "key_left", key_default);
|
||||
// // key_default = "Right";
|
||||
// // char* key_right = (i == 0) ? key_default : config_get(config, "key_right", key_default);
|
||||
// // key_default = "Tab";
|
||||
// // char* key_forward = (i == 0) ? key_default : config_get(config, "key_forward", key_default);
|
||||
// // key_default = "Shift-ISO_Left_Tab";
|
||||
// // char* key_backward = (i == 0) ? key_default : config_get(config, "key_backward", key_default);
|
||||
// // key_default = "Return";
|
||||
// // char* key_submit = (i == 0) ? key_default : config_get(config, "key_submit", key_default);
|
||||
// // key_default = "Escape";
|
||||
// // char* key_exit = (i == 0) ? key_default : config_get(config, "key_exit", key_default);
|
||||
// // key_default = "Page_Up";
|
||||
// // char* key_pgup = (i == 0) ? key_default : config_get(config, "key_pgup", key_default);
|
||||
// // key_default = "Page_Down";
|
||||
// // char* key_pgdn = (i == 0) ? key_default : config_get(config, "key_pgdn", key_default);
|
||||
// // key_default = "";
|
||||
// // char* key_expand = (i == 0) ? key_default: config_get(config, "key_expand", key_default);
|
||||
// // key_default = "";
|
||||
// // char* key_hide_search = (i == 0) ? key_default: config_get(config, "key_hide_search", key_default);
|
||||
// // key_default = "Ctrl-c";
|
||||
// // char* key_copy = (i == 0) ? key_default : config_get(config, "key_copy", key_default);
|
||||
// }
|
||||
|
||||
#[must_use]
|
||||
pub fn parse_args() -> Config {
|
||||
Config::parse()
|
||||
|
|
|
@ -988,7 +988,16 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
|||
&meta.config,
|
||||
meta.search_ignored_words.as_ref(),
|
||||
);
|
||||
|
||||
select_first_visible_child(&*lock, &ui.main_box);
|
||||
drop(lock);
|
||||
if meta.config.dynamic_lines() {
|
||||
ui.window.set_height_request(calculate_row_height(
|
||||
ui,
|
||||
visible_row_count(ui),
|
||||
&meta.config,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let update_view_from_provider = |query: &String| {
|
||||
|
@ -1151,7 +1160,6 @@ fn sort_menu_items_by_score<T: Clone>(
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)] // does not matter for calculating height
|
||||
fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>>) {
|
||||
// Get the surface and associated monitor geometry
|
||||
let Some(surface) = ui.window.surface() else {
|
||||
|
@ -1171,57 +1179,9 @@ fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>
|
|||
};
|
||||
|
||||
let target_height = if let Some(lines) = config.lines() {
|
||||
let (_, _, _, height_search) = ui.search.measure(Orientation::Vertical, 10_000);
|
||||
let (height_box, _, _, _) = ui.custom_key_box.measure(Orientation::Vertical, 10_000);
|
||||
let (_, scroll_height, _, _) = ui.scroll.measure(Orientation::Vertical, 10_000);
|
||||
let (_, window_height, _, _) = ui.window.measure(Orientation::Vertical, 10_000);
|
||||
|
||||
let height = {
|
||||
let lock = ui.menu_rows.read().unwrap();
|
||||
lock.iter()
|
||||
.find_map(|(fb, _)| {
|
||||
let (_, _, _, baseline) = fb.measure(Orientation::Vertical, 10_000);
|
||||
if baseline > 0 {
|
||||
let factor = if lines > 1 {
|
||||
1.4 // todo find a better way to do this
|
||||
// most likely it will not work with all styles
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
|
||||
if config.allow_images() && baseline < i32::from(config.image_size()) {
|
||||
Some(i32::from(config.image_size()))
|
||||
} else {
|
||||
Some((f64::from(baseline) * factor) as i32)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
lock.iter().find_map(|(fb, _)| {
|
||||
let (_, nat, _, _) = fb.measure(Orientation::Vertical, 10_000);
|
||||
if nat > 0 { Some(nat) } else { None }
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
log::debug!(
|
||||
"heights: scroll {scroll_height}, window {window_height}, keys {height_box}, height {height:?}"
|
||||
);
|
||||
|
||||
if let Some(height) = height {
|
||||
Some(
|
||||
height_box
|
||||
+ scroll_height
|
||||
+ height_search
|
||||
+ height * lines
|
||||
+ config.lines_additional_space(),
|
||||
)
|
||||
} else {
|
||||
log::warn!("No widget for height calculation available");
|
||||
Some(0)
|
||||
}
|
||||
Some(calculate_row_height(ui, lines, config))
|
||||
} else if config.dynamic_lines() {
|
||||
Some(calculate_row_height(ui, visible_row_count(ui), config))
|
||||
} else if let Some(height) = percent_or_absolute(&config.height(), geometry.height()) {
|
||||
Some(height)
|
||||
} else {
|
||||
|
@ -1238,10 +1198,75 @@ fn window_show_resize<T: Clone + 'static>(config: &Config, ui: &Rc<UiElements<T>
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)] // does not matter for calculating height
|
||||
fn calculate_row_height<T: Clone + 'static>(
|
||||
ui: &UiElements<T>,
|
||||
lines: i32,
|
||||
config: &Config,
|
||||
) -> i32 {
|
||||
const MEAS_SIZE: i32 = 10_000;
|
||||
let (_, _, _, height_search) = ui.search.measure(Orientation::Vertical, MEAS_SIZE);
|
||||
let (height_box, _, _, _) = ui.custom_key_box.measure(Orientation::Vertical, MEAS_SIZE);
|
||||
let (_, scroll_height, _, _) = ui.scroll.measure(Orientation::Vertical, MEAS_SIZE);
|
||||
let (_, window_height, _, _) = ui.window.measure(Orientation::Vertical, MEAS_SIZE);
|
||||
|
||||
let height = {
|
||||
let lock = ui.menu_rows.read().unwrap();
|
||||
lock.iter()
|
||||
.find_map(|(fb, _)| {
|
||||
let (_, _, _, baseline) = fb.measure(Orientation::Vertical, MEAS_SIZE);
|
||||
if baseline > 0 {
|
||||
let factor = if lines > 1 {
|
||||
1.4 // todo find a better way to do this
|
||||
// most likely it will not work with all styles
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
|
||||
if config.allow_images() && baseline < i32::from(config.image_size()) {
|
||||
Some(i32::from(config.image_size()))
|
||||
} else {
|
||||
Some((f64::from(baseline) * factor) as i32)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
lock.iter().find_map(|(fb, _)| {
|
||||
let (_, nat, _, _) = fb.measure(Orientation::Vertical, MEAS_SIZE);
|
||||
if nat > 0 { Some(nat) } else { None }
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
log::debug!(
|
||||
"heights: scroll {scroll_height}, window {window_height}, keys {height_box}, height {height:?}"
|
||||
);
|
||||
|
||||
height_box
|
||||
+ scroll_height
|
||||
+ height_search
|
||||
+ height.map_or(0, |h| h * lines)
|
||||
+ config.lines_additional_space()
|
||||
}
|
||||
|
||||
fn close_gui(app: &Application) {
|
||||
app.quit();
|
||||
}
|
||||
|
||||
fn visible_row_count<T: Clone + 'static>(ui: &UiElements<T>) -> i32 {
|
||||
i32::try_from(
|
||||
ui.menu_rows
|
||||
.read()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|(_, menu)| menu.visible)
|
||||
.count(),
|
||||
)
|
||||
.unwrap_or(i32::MAX)
|
||||
}
|
||||
|
||||
fn handle_selected_item<T>(
|
||||
ui: &Rc<UiElements<T>>,
|
||||
meta: Rc<MetaData<T>>,
|
||||
|
|
Loading…
Add table
Reference in a new issue