dropdown for capture_method + random tweaks
This commit is contained in:
1
dash-frontend/assets/dashboard/down.svg
Symbolic link
1
dash-frontend/assets/dashboard/down.svg
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../wlx-overlay-s/src/assets/keyboard/down.svg
|
||||
27
dash-frontend/assets/gui/t_dropdown_button.xml
Normal file
27
dash-frontend/assets/gui/t_dropdown_button.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<layout>
|
||||
<include src="theme.xml" />
|
||||
|
||||
<macro name="dropdown_button"
|
||||
flex_direction="row"
|
||||
border="2"
|
||||
color="#00000055"
|
||||
border_color="#FFFFFF66"
|
||||
justify_content="space_between" />
|
||||
|
||||
<!-- id, text, translation, tooltip -->
|
||||
<template name="DropdownButton">
|
||||
<label text="${text}" translation="${translation}" />
|
||||
<Button id="${id}" height="32" tooltip="${tooltip}" >
|
||||
<div padding_left="8" padding_right="8" min_width="200">
|
||||
<label id="${id}_value" weight="bold" />
|
||||
</div>
|
||||
<div gap="2">
|
||||
<div padding_top="4" padding_bottom="4">
|
||||
<rectangle width="2" height="100%" color="#FFFFFF66" />
|
||||
</div>
|
||||
<sprite margin_left="-4" width="30" height="30" color="~text_color" src_builtin="dashboard/down.svg" />
|
||||
</div>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
</layout>
|
||||
@@ -1,6 +1,7 @@
|
||||
<layout>
|
||||
<include src="t_tab_title.xml" />
|
||||
<include src="../t_group_box.xml" />
|
||||
<include src="../t_dropdown_button.xml" />
|
||||
|
||||
<template name="SettingsGroupBox">
|
||||
<rectangle macro="group_box" id="${id}" flex_grow="1">
|
||||
@@ -27,7 +28,10 @@
|
||||
</template>
|
||||
|
||||
<template name="DangerButton">
|
||||
<Button id="${id}" color="#AA3333" height="32" width="100%" sprite_src_builtin="${icon}" translation="${translation}" tooltip="${translation}_HELP" />
|
||||
<Button id="${id}" color="#AA3333" height="32" tooltip="${translation}_HELP" padding="4" gap="8" >
|
||||
<sprite src_builtin="${icon}" height="24" width="24" />
|
||||
<label align="left" translation="${translation}" weight="bold" min_width="200" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
<elements>
|
||||
|
||||
@@ -69,7 +69,16 @@
|
||||
"CLEAR_SAVED_STATE_HELP": "Reset sets & overlay positions",
|
||||
"CLEAR_PIPEWIRE_TOKENS_HELP": "Prompt for screen selection on next start",
|
||||
"DELETE_ALL_CONFIGS_HELP": "Remove all configuration files from conf.d",
|
||||
"RESTART_SOFTWARE_HELP": "Apply settings that require a restart"
|
||||
"RESTART_SOFTWARE_HELP": "Apply settings that require a restart",
|
||||
|
||||
"CAPTURE_METHOD": "Wayland screen capture",
|
||||
"CAPTURE_METHOD_HELP": "Try changing this if experiencing\nblack or glitchy screens",
|
||||
|
||||
"OPTION": {
|
||||
"PIPEWIRE_HELP": "Fast GPU capture. Recommended",
|
||||
"PW_FALLBACK_HELP": "Slow. Try in case PipeWire GPU doesn't work",
|
||||
"SCREENCOPY_HELP": "Slow. Works on: Hyprland, Niri, River, Sway"
|
||||
}
|
||||
},
|
||||
"APPLICATION_LAUNCHER": "Application launcher",
|
||||
"APPLICATION_STARTED": "Application started",
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
use std::{collections::HashMap, marker::PhantomData, rc::Rc};
|
||||
use std::{collections::HashMap, marker::PhantomData, rc::Rc, str::FromStr};
|
||||
|
||||
use strum::AsRefStr;
|
||||
use glam::Vec2;
|
||||
use strum::{AsRefStr, EnumProperty, EnumString, VariantArray};
|
||||
use wgui::{
|
||||
assets::AssetPath,
|
||||
components::{button::ComponentButton, checkbox::ComponentCheckbox, slider::ComponentSlider},
|
||||
event::{CallbackDataCommon, EventAlterables},
|
||||
i18n::Translation,
|
||||
layout::{Layout, WidgetID},
|
||||
log::LogErr,
|
||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||
task::Tasks,
|
||||
widget::label::WidgetLabel,
|
||||
windowing::context_menu::{self, Blueprint, ContextMenu, TickResult},
|
||||
};
|
||||
use wlx_common::{config::GeneralConfig, config_io::ConfigRoot};
|
||||
|
||||
@@ -20,6 +25,7 @@ enum Task {
|
||||
UpdateBool(SettingType, bool),
|
||||
UpdateFloat(SettingType, f32),
|
||||
UpdateInt(SettingType, i32),
|
||||
OpenContextMenu(Vec2, Vec<context_menu::Cell>),
|
||||
ClearPipewireTokens,
|
||||
ClearSavedState,
|
||||
DeleteAllConfigs,
|
||||
@@ -30,6 +36,8 @@ pub struct TabSettings<T> {
|
||||
#[allow(dead_code)]
|
||||
pub state: ParserState,
|
||||
|
||||
context_menu: ContextMenu,
|
||||
|
||||
tasks: Tasks<Task>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
@@ -76,17 +84,56 @@ impl<T> Tab<T> for TabSettings<T> {
|
||||
frontend.interface.restart(data);
|
||||
return Ok(());
|
||||
}
|
||||
Task::OpenContextMenu(position, cells) => {
|
||||
self.context_menu.open(context_menu::OpenParams {
|
||||
on_custom_attribs: None,
|
||||
position,
|
||||
blueprint: Blueprint::Cells(cells),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown handling
|
||||
if let TickResult::Action(name) = self.context_menu.tick(&mut frontend.layout, &mut self.state)? {
|
||||
if let (Some(setting), Some(id), Some(value), Some(text), Some(translated)) = {
|
||||
let mut s = name.splitn(5, ';');
|
||||
(s.next(), s.next(), s.next(), s.next(), s.next())
|
||||
} {
|
||||
let mut label = self
|
||||
.state
|
||||
.fetch_widget_as::<WidgetLabel>(&frontend.layout.state, &format!("{id}_value"))?;
|
||||
|
||||
let mut alterables = EventAlterables::default();
|
||||
let mut common = CallbackDataCommon {
|
||||
alterables: &mut alterables,
|
||||
state: &frontend.layout.state,
|
||||
};
|
||||
|
||||
let translation = Translation {
|
||||
text: text.into(),
|
||||
translated: translated == "1",
|
||||
};
|
||||
|
||||
label.set_text(&mut common, translation);
|
||||
|
||||
let setting = SettingType::from_str(setting).expect("Invalid Enum string");
|
||||
setting.set_enum(config, value);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify overlays of the change
|
||||
if changed {
|
||||
frontend.interface.config_changed(data);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Clone, Copy, AsRefStr)]
|
||||
#[derive(Clone, Copy, AsRefStr, EnumString)]
|
||||
enum SettingType {
|
||||
AnimationSpeed,
|
||||
RoundMultiplier,
|
||||
@@ -120,6 +167,7 @@ enum SettingType {
|
||||
HideUsername,
|
||||
OpaqueBackground,
|
||||
XwaylandByDefault,
|
||||
CaptureMethod,
|
||||
}
|
||||
|
||||
impl SettingType {
|
||||
@@ -173,6 +221,40 @@ impl SettingType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_enum<'a>(self, config: &'a mut GeneralConfig, value: &str) {
|
||||
match self {
|
||||
Self::CaptureMethod => {
|
||||
config.capture_method = wlx_common::config::CaptureMethod::from_str(value).expect("Invalid enum value!")
|
||||
}
|
||||
_ => panic!("Requested enum for non-enum SettingType"),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_enum_title<'a>(self, config: &'a mut GeneralConfig) -> Translation {
|
||||
match self {
|
||||
Self::CaptureMethod => Self::get_enum_title_inner(config.capture_method),
|
||||
_ => panic!("Requested enum for non-enum SettingType"),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_enum_title_inner<E>(value: E) -> Translation
|
||||
where
|
||||
E: EnumProperty + AsRef<str>,
|
||||
{
|
||||
value
|
||||
.get_str("Translation")
|
||||
.map(|x| Translation::from_translation_key(x))
|
||||
.or_else(|| value.get_str("Text").map(|x| Translation::from_raw_text(x)))
|
||||
.unwrap_or_else(|| Translation::from_raw_text(value.as_ref()))
|
||||
}
|
||||
|
||||
fn get_enum_tooltip_inner<E>(value: E) -> Option<Translation>
|
||||
where
|
||||
E: EnumProperty + AsRef<str>,
|
||||
{
|
||||
value.get_str("Tooltip").map(|x| Translation::from_translation_key(x))
|
||||
}
|
||||
|
||||
/// Ok is translation, Err is raw text
|
||||
fn get_translation(self) -> Result<&'static str, &'static str> {
|
||||
match self {
|
||||
@@ -208,6 +290,7 @@ impl SettingType {
|
||||
Self::HideUsername => Ok("APP_SETTINGS.HIDE_USERNAME"),
|
||||
Self::OpaqueBackground => Ok("APP_SETTINGS.OPAQUE_BACKGROUND"),
|
||||
Self::XwaylandByDefault => Ok("APP_SETTINGS.XWAYLAND_BY_DEFAULT"),
|
||||
Self::CaptureMethod => Ok("APP_SETTINGS.CAPTURE_METHOD"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +307,7 @@ impl SettingType {
|
||||
Self::UseSkybox => Some("APP_SETTINGS.USE_SKYBOX_HELP"),
|
||||
Self::UsePassthrough => Some("APP_SETTINGS.USE_PASSTHROUGH_HELP"),
|
||||
Self::ScreenRenderDown => Some("APP_SETTINGS.SCREEN_RENDER_DOWN_HELP"),
|
||||
Self::CaptureMethod => Some("APP_SETTINGS.CAPTURE_METHOD_HELP"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -381,6 +465,72 @@ macro_rules! slider_i32 {
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! dropdown {
|
||||
($mp:expr, $root:expr, $setting:expr, $options:expr) => {
|
||||
let id = $mp.idx.to_string();
|
||||
$mp.idx += 1;
|
||||
|
||||
let mut params: HashMap<Rc<str>, Rc<str>> = HashMap::new();
|
||||
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
||||
|
||||
match $setting.get_translation() {
|
||||
Ok(translation) => params.insert(Rc::from("translation"), translation.into()),
|
||||
Err(raw_text) => params.insert(Rc::from("text"), raw_text.into()),
|
||||
};
|
||||
|
||||
if let Some(tooltip) = $setting.get_tooltip() {
|
||||
params.insert(Rc::from("tooltip"), Rc::from(tooltip));
|
||||
}
|
||||
|
||||
$mp
|
||||
.parser_state
|
||||
.instantiate_template($mp.doc_params, "DropdownButton", $mp.layout, $root, params)?;
|
||||
|
||||
let setting_str = $setting.as_ref();
|
||||
let title = $setting.get_enum_title($mp.config);
|
||||
|
||||
{
|
||||
let mut label = $mp
|
||||
.parser_state
|
||||
.fetch_widget_as::<WidgetLabel>(&$mp.layout.state, &format!("{id}_value"))?;
|
||||
label.set_text_simple(&mut $mp.layout.state.globals.get(), title);
|
||||
}
|
||||
|
||||
let btn = $mp.parser_state.fetch_component_as::<ComponentButton>(&id)?;
|
||||
btn.on_click(Box::new({
|
||||
let tasks = $mp.tasks.clone();
|
||||
move |_common, e| {
|
||||
tasks.push(Task::OpenContextMenu(
|
||||
e.mouse_pos_absolute.unwrap_or_default(),
|
||||
$options
|
||||
.iter()
|
||||
.filter_map(|item| {
|
||||
if item.get_bool("Hidden").unwrap_or(false) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let value = item.as_ref();
|
||||
let title = SettingType::get_enum_title_inner(*item);
|
||||
let tooltip = SettingType::get_enum_tooltip_inner(*item);
|
||||
|
||||
let text = &title.text;
|
||||
let translated = if title.translated { "1" } else { "0" };
|
||||
|
||||
Some(context_menu::Cell {
|
||||
action_name: Some(format!("{setting_str};{id};{value};{text};{translated}").into()),
|
||||
title,
|
||||
tooltip,
|
||||
attribs: vec![],
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! button {
|
||||
($mp:expr, $root:expr, $translation:expr, $icon:expr, $task:expr) => {
|
||||
let id = $mp.idx.to_string();
|
||||
@@ -474,27 +624,33 @@ impl<T> TabSettings<T> {
|
||||
checkbox!(mp, c, SettingType::UprightScreenFix);
|
||||
checkbox!(mp, c, SettingType::DoubleCursorFix);
|
||||
checkbox!(mp, c, SettingType::ScreenRenderDown);
|
||||
dropdown!(
|
||||
mp,
|
||||
c,
|
||||
SettingType::CaptureMethod,
|
||||
wlx_common::config::CaptureMethod::VARIANTS
|
||||
);
|
||||
|
||||
let c = category!(mp, root, "APP_SETTINGS.TROUBLESHOOTING", "dashboard/blocks.svg")?;
|
||||
button!(
|
||||
mp,
|
||||
c,
|
||||
"APP_SETTINGS.CLEAR_SAVED_STATE",
|
||||
"dashboard/remove_circle.svg",
|
||||
Task::ClearSavedState
|
||||
);
|
||||
button!(
|
||||
mp,
|
||||
c,
|
||||
"APP_SETTINGS.CLEAR_PIPEWIRE_TOKENS",
|
||||
"dashboard/remove_circle.svg",
|
||||
"dashboard/display.svg",
|
||||
Task::ClearPipewireTokens
|
||||
);
|
||||
button!(
|
||||
mp,
|
||||
c,
|
||||
"APP_SETTINGS.CLEAR_SAVED_STATE",
|
||||
"dashboard/binary.svg",
|
||||
Task::ClearSavedState
|
||||
);
|
||||
button!(
|
||||
mp,
|
||||
c,
|
||||
"APP_SETTINGS.DELETE_ALL_CONFIGS",
|
||||
"dashboard/remove_circle.svg",
|
||||
"dashboard/circle.svg",
|
||||
Task::DeleteAllConfigs
|
||||
);
|
||||
button!(
|
||||
@@ -509,6 +665,7 @@ impl<T> TabSettings<T> {
|
||||
tasks: mp.tasks,
|
||||
state: parser_state,
|
||||
marker: PhantomData,
|
||||
context_menu: ContextMenu::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user