add_display::View done
This commit is contained in:
@@ -2,16 +2,29 @@
|
|||||||
<include src="../t_group_box.xml" />
|
<include src="../t_group_box.xml" />
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<div gap="8" flex_direction="column" width="100%" justify_self="center" align_items="center" justify_content="center">
|
<div gap="16" flex_direction="column" width="100%" justify_self="center" align_items="center" justify_content="center">
|
||||||
<rectangle macro="group_box">
|
<rectangle macro="group_box" align_items="center">
|
||||||
<label translation="POPUP_ADD_DISPLAY.RESOLUTION" weight="bold" size="20" />
|
<label translation="POPUP_ADD_DISPLAY.RESOLUTION" weight="bold" size="20" />
|
||||||
<Slider id="slider_width" min_value="0" max_value="10" width="250" height="24" />
|
<div gap="8" align_items="center">
|
||||||
<Slider id="slider_height" min_value="0" max_value="10" width="250" height="24" />
|
<div flex_direction="column" gap="8" align_items="end">
|
||||||
<rectangle macro="group_box" id="rect_display">
|
<label translation="WIDTH" />
|
||||||
<label id="label_display" />
|
<label translation="HEIGHT" />
|
||||||
|
</div>
|
||||||
|
<div flex_direction="column" gap="8">
|
||||||
|
<Slider show_value="0" id="slider_width" value="2" min_value="0" max_value="6" width="250" height="24" />
|
||||||
|
<Slider show_value="0" id="slider_height" value="2" min_value="0" max_value="6" width="250" height="24" />
|
||||||
|
</div>
|
||||||
|
<div flex_direction="column" gap="8">
|
||||||
|
<label id="label_width" weight="bold" text="px" />
|
||||||
|
<label id="label_height" weight="bold" text="px" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CheckBox id="cb_portrait" translation="DISPLAY_PORTRAIT_MODE" height="24" />
|
||||||
|
<rectangle min_width="64" min_height="32" macro="group_box" id="rect_display" align_items="center" justify_content="center" padding="0" overflow="hidden">
|
||||||
|
<label id="label_display" align="center" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</rectangle>
|
</rectangle>
|
||||||
<Button id="btn_confirm" color="#44ce22FF" padding_top="4" padding_bottom="4" round="8" padding_left="12" padding_right="12">
|
<Button id="btn_confirm" color="#44ce22FF" padding_top="4" padding_bottom="4" round="8" padding_left="12" padding_right="12" min_height="32">
|
||||||
<sprite src_builtin="dashboard/display.svg" width="32" height="32" />
|
<sprite src_builtin="dashboard/display.svg" width="32" height="32" />
|
||||||
<label translation="ADD_DISPLAY" weight="bold" size="17" shadow="#00000099" />
|
<label translation="ADD_DISPLAY" weight="bold" size="17" shadow="#00000099" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
<include src="../t_group_box.xml" />
|
<include src="../t_group_box.xml" />
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<rectangle macro="group_box" flex_direction="row">
|
<rectangle macro="group_box" flex_direction="row" align_items="center">
|
||||||
<div id="list_parent" />
|
<div id="list_parent" gap="8" flex_direction="row" flex_wrap="wrap" flex_grow="1" />
|
||||||
<Button id="btn_add" sprite_src_builtin="dashboard/add.svg" tooltip="ADD_DISPLAY" height="100%" width="32" />
|
<Button id="btn_add" sprite_src_builtin="dashboard/add.svg" tooltip="ADD_DISPLAY" height="100%" min_width="32" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -52,5 +52,8 @@
|
|||||||
"ADD_DISPLAY": "Bildschirm hinzufügen",
|
"ADD_DISPLAY": "Bildschirm hinzufügen",
|
||||||
"POPUP_ADD_DISPLAY": {
|
"POPUP_ADD_DISPLAY": {
|
||||||
"RESOLUTION": "Auflösung"
|
"RESOLUTION": "Auflösung"
|
||||||
}
|
},
|
||||||
|
"WIDTH": "Breite",
|
||||||
|
"HEIGHT": "Höhe",
|
||||||
|
"DISPLAY_PORTRAIT_MODE": "Porträtmodus"
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,8 @@
|
|||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"RECENTER_PLAYSPACE": "Re-center playspace"
|
"RECENTER_PLAYSPACE": "Re-center playspace"
|
||||||
},
|
},
|
||||||
"POPUP_ADD_DISPLAY": {
|
|
||||||
"RESOLUTION": "Resolution"
|
|
||||||
},
|
|
||||||
"ADD_DISPLAY": "Add display",
|
"ADD_DISPLAY": "Add display",
|
||||||
|
"DISPLAY_PORTRAIT_MODE": "Portrait mode",
|
||||||
"APP_SETTINGS": {
|
"APP_SETTINGS": {
|
||||||
"BRIGHTNESS": "Brightness",
|
"BRIGHTNESS": "Brightness",
|
||||||
"HEADSET_SETTINGS": "Headset settings",
|
"HEADSET_SETTINGS": "Headset settings",
|
||||||
@@ -44,6 +42,7 @@
|
|||||||
},
|
},
|
||||||
"GAMES": "Games",
|
"GAMES": "Games",
|
||||||
"GENERAL_SETTINGS": "General settings",
|
"GENERAL_SETTINGS": "General settings",
|
||||||
|
"HEIGHT": "Height",
|
||||||
"HELLO": "Hello!",
|
"HELLO": "Hello!",
|
||||||
"HELLO_USER": "Hello, {USER}!",
|
"HELLO_USER": "Hello, {USER}!",
|
||||||
"HOME_SCREEN": "Home",
|
"HOME_SCREEN": "Home",
|
||||||
@@ -51,6 +50,10 @@
|
|||||||
"LIST_OF_PROCESSES": "Process list",
|
"LIST_OF_PROCESSES": "Process list",
|
||||||
"MONADO_RUNTIME": "„Monado” runtime",
|
"MONADO_RUNTIME": "„Monado” runtime",
|
||||||
"NO_DISPLAYS_FOUND": "No displays found",
|
"NO_DISPLAYS_FOUND": "No displays found",
|
||||||
|
"POPUP_ADD_DISPLAY": {
|
||||||
|
"RESOLUTION": "Resolution"
|
||||||
|
},
|
||||||
"PROCESSES": "Processes",
|
"PROCESSES": "Processes",
|
||||||
"SETTINGS": "Settings"
|
"SETTINGS": "Settings",
|
||||||
|
"WIDTH": "Width"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,5 +52,8 @@
|
|||||||
"ADD_DISPLAY": "Agregar pantalla",
|
"ADD_DISPLAY": "Agregar pantalla",
|
||||||
"POPUP_ADD_DISPLAY": {
|
"POPUP_ADD_DISPLAY": {
|
||||||
"RESOLUTION": "Resolución"
|
"RESOLUTION": "Resolución"
|
||||||
}
|
},
|
||||||
|
"WIDTH": "Ancho",
|
||||||
|
"HEIGHT": "Altura",
|
||||||
|
"DISPLAY_PORTRAIT_MODE": "Modo retrato"
|
||||||
}
|
}
|
||||||
@@ -52,5 +52,8 @@
|
|||||||
"ADD_DISPLAY": "ディスプレイを追加",
|
"ADD_DISPLAY": "ディスプレイを追加",
|
||||||
"POPUP_ADD_DISPLAY": {
|
"POPUP_ADD_DISPLAY": {
|
||||||
"RESOLUTION": "解像度"
|
"RESOLUTION": "解像度"
|
||||||
}
|
},
|
||||||
|
"WIDTH": "幅",
|
||||||
|
"HEIGHT": "高さ",
|
||||||
|
"DISPLAY_PORTRAIT_MODE": "縦向きモード"
|
||||||
}
|
}
|
||||||
@@ -46,11 +46,14 @@
|
|||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"RECENTER_PLAYSPACE": "Wycentruj przestrzeń"
|
"RECENTER_PLAYSPACE": "Wycentruj przestrzeń"
|
||||||
},
|
},
|
||||||
"LIST_OF_DISPLAYS": "Lista wyświetlaczy",
|
"LIST_OF_DISPLAYS": "Lista monitorów",
|
||||||
"LIST_OF_PROCESSES": "Lista procesów",
|
"LIST_OF_PROCESSES": "Lista procesów",
|
||||||
"NO_DISPLAYS_FOUND": "Brak monitorów",
|
"NO_DISPLAYS_FOUND": "Brak monitorów",
|
||||||
"ADD_DISPLAY": "Dodaj monitor",
|
"ADD_DISPLAY": "Dodaj monitor",
|
||||||
"POPUP_ADD_DISPLAY": {
|
"POPUP_ADD_DISPLAY": {
|
||||||
"RESOLUTION": "Rozdzielczość"
|
"RESOLUTION": "Rozdzielczość"
|
||||||
}
|
},
|
||||||
|
"WIDTH": "Szerokość",
|
||||||
|
"HEIGHT": "Wysokość",
|
||||||
|
"DISPLAY_PORTRAIT_MODE": "Tryb pionowy"
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,26 @@
|
|||||||
use std::{collections::HashMap, rc::Rc};
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::{button::ComponentButton, slider::ComponentSlider},
|
components::{button::ComponentButton, checkbox::ComponentCheckbox, slider::ComponentSlider},
|
||||||
|
event::StyleSetRequest,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
taffy::prelude::length,
|
||||||
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{frontend::FrontendTasks, tab::TabUpdateParams, task::Tasks};
|
use crate::{frontend::FrontendTasks, task::Tasks};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum Task {
|
enum Task {
|
||||||
Confirm,
|
Confirm,
|
||||||
|
SetWidth(u16),
|
||||||
|
SetHeight(u16),
|
||||||
|
SetPortrait(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct View {
|
pub struct View {
|
||||||
@@ -21,7 +28,25 @@ pub struct View {
|
|||||||
pub state: ParserState,
|
pub state: ParserState,
|
||||||
tasks: Tasks<Task>,
|
tasks: Tasks<Task>,
|
||||||
frontend_tasks: FrontendTasks,
|
frontend_tasks: FrontendTasks,
|
||||||
on_submit: Rc<dyn Fn()>,
|
on_submit: Rc<dyn Fn(Result)>,
|
||||||
|
|
||||||
|
cur_raw_width: u16,
|
||||||
|
cur_raw_height: u16,
|
||||||
|
cur_display_name: String,
|
||||||
|
cur_portrait: bool,
|
||||||
|
|
||||||
|
id_label_width: WidgetID,
|
||||||
|
id_label_height: WidgetID,
|
||||||
|
id_label_display_name: WidgetID,
|
||||||
|
id_rect_display: WidgetID,
|
||||||
|
id_label_display: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Result {
|
||||||
|
pub width: u16,
|
||||||
|
pub height: u16,
|
||||||
|
pub display_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Params<'a> {
|
pub struct Params<'a> {
|
||||||
@@ -29,9 +54,13 @@ pub struct Params<'a> {
|
|||||||
pub frontend_tasks: FrontendTasks,
|
pub frontend_tasks: FrontendTasks,
|
||||||
pub layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
pub on_submit: Rc<dyn Fn()>,
|
pub on_submit: Rc<dyn Fn(Result)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RES_COUNT: usize = 7;
|
||||||
|
const RES_WIDTHS: [u16; RES_COUNT] = [512, 854, 1280, 1600, 1920, 2560, 3840];
|
||||||
|
const RES_HEIGHTS: [u16; 7] = [256, 480, 720, 900, 1080, 1440, 2160];
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
pub fn new(params: Params) -> anyhow::Result<Self> {
|
pub fn new(params: Params) -> anyhow::Result<Self> {
|
||||||
let doc_params = &ParseDocumentParams {
|
let doc_params = &ParseDocumentParams {
|
||||||
@@ -46,34 +75,176 @@ impl View {
|
|||||||
|
|
||||||
let slider_width = state.fetch_component_as::<ComponentSlider>("slider_width")?;
|
let slider_width = state.fetch_component_as::<ComponentSlider>("slider_width")?;
|
||||||
let slider_height = state.fetch_component_as::<ComponentSlider>("slider_height")?;
|
let slider_height = state.fetch_component_as::<ComponentSlider>("slider_height")?;
|
||||||
let label_display_name = state.fetch_widget_as::<WidgetLabel>(¶ms.layout.state, "label_display_name")?;
|
let id_label_width = state.get_widget_id("label_width")?;
|
||||||
let rect_display = state.fetch_widget_as::<WidgetRectangle>(¶ms.layout.state, "rect_display");
|
let id_label_height = state.get_widget_id("label_height")?;
|
||||||
let label_display = state.fetch_widget_as::<WidgetLabel>(¶ms.layout.state, "label_display");
|
let id_label_display_name = state.get_widget_id("label_display_name")?;
|
||||||
|
let id_rect_display = state.get_widget_id("rect_display")?;
|
||||||
|
let id_label_display = state.get_widget_id("label_display")?;
|
||||||
let btn_confirm = state.fetch_component_as::<ComponentButton>("btn_confirm")?;
|
let btn_confirm = state.fetch_component_as::<ComponentButton>("btn_confirm")?;
|
||||||
|
let cb_portrait = state.fetch_component_as::<ComponentCheckbox>("cb_portrait")?;
|
||||||
|
|
||||||
tasks.handle_button(btn_confirm, Task::Confirm);
|
tasks.handle_button(btn_confirm, Task::Confirm);
|
||||||
|
|
||||||
Ok(Self {
|
// width
|
||||||
|
slider_width.on_value_changed({
|
||||||
|
let tasks = tasks.clone();
|
||||||
|
Box::new(move |_c, e| {
|
||||||
|
tasks.push(Task::SetWidth(RES_WIDTHS[e.value as usize]));
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// height
|
||||||
|
slider_height.on_value_changed({
|
||||||
|
let tasks = tasks.clone();
|
||||||
|
Box::new(move |_c, e| {
|
||||||
|
tasks.push(Task::SetHeight(RES_HEIGHTS[e.value as usize]));
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
cb_portrait.on_toggle({
|
||||||
|
let tasks = tasks.clone();
|
||||||
|
Box::new(move |_c, e| {
|
||||||
|
tasks.push(Task::SetPortrait(e.checked));
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut res = Self {
|
||||||
state,
|
state,
|
||||||
tasks,
|
tasks,
|
||||||
frontend_tasks: params.frontend_tasks,
|
frontend_tasks: params.frontend_tasks,
|
||||||
on_submit: params.on_submit,
|
on_submit: params.on_submit,
|
||||||
})
|
cur_raw_width: RES_WIDTHS[2],
|
||||||
|
cur_raw_height: RES_HEIGHTS[2],
|
||||||
|
cur_display_name: String::new(),
|
||||||
|
cur_portrait: false,
|
||||||
|
id_label_width,
|
||||||
|
id_label_height,
|
||||||
|
id_label_display_name,
|
||||||
|
id_rect_display,
|
||||||
|
id_label_display,
|
||||||
|
};
|
||||||
|
|
||||||
|
res.update_ui(params.layout);
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) -> anyhow::Result<()> {
|
pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
|
||||||
for task in self.tasks.drain() {
|
for task in self.tasks.drain() {
|
||||||
match task {
|
match task {
|
||||||
Task::Confirm => self.confirm(),
|
Task::Confirm => self.confirm(),
|
||||||
|
Task::SetWidth(w) => {
|
||||||
|
self.cur_raw_width = w;
|
||||||
|
self.update_ui_res(layout)?;
|
||||||
|
}
|
||||||
|
Task::SetHeight(h) => {
|
||||||
|
self.cur_raw_height = h;
|
||||||
|
self.update_ui_res(layout)?;
|
||||||
|
}
|
||||||
|
Task::SetPortrait(p) => {
|
||||||
|
self.cur_portrait = p;
|
||||||
|
self.update_ui_res(layout)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// greatest common divisor
|
||||||
|
fn gcd(a: u16, b: u16) -> u16 {
|
||||||
|
let (mut a, mut b) = (a, b);
|
||||||
|
while b != 0 {
|
||||||
|
let temp = b;
|
||||||
|
b = a % b;
|
||||||
|
a = temp;
|
||||||
|
}
|
||||||
|
a
|
||||||
|
}
|
||||||
|
|
||||||
|
// aspect ratio calculation
|
||||||
|
// e.g. returns (16, 9) for input values [1280, 720]
|
||||||
|
fn aspect_ratio(width: u16, height: u16) -> (u16, u16) {
|
||||||
|
let gcd = gcd(width, height);
|
||||||
|
(width / gcd, height / gcd)
|
||||||
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
fn confirm(&mut self) {
|
fn confirm(&mut self) {
|
||||||
log::info!("confirm");
|
let (width, height) = self.get_wh();
|
||||||
(*self.on_submit)();
|
(*self.on_submit)(Result {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
display_name: self.cur_display_name.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_ui(&mut self, layout: &mut Layout) -> Option<()> {
|
||||||
|
let mut c = layout.start_common();
|
||||||
|
|
||||||
|
let (cur_width, cur_height) = self.get_wh();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut common = c.common();
|
||||||
|
|
||||||
|
let mut label_width = common.state.widgets.get_as::<WidgetLabel>(self.id_label_width)?;
|
||||||
|
let mut label_height = common.state.widgets.get_as::<WidgetLabel>(self.id_label_height)?;
|
||||||
|
let mut label_display_name = common.state.widgets.get_as::<WidgetLabel>(self.id_label_display_name)?;
|
||||||
|
let mut label_display = common.state.widgets.get_as::<WidgetLabel>(self.id_label_display)?;
|
||||||
|
|
||||||
|
// todo?
|
||||||
|
self.cur_display_name = format!("wvr-{}x{}", cur_width, cur_height);
|
||||||
|
|
||||||
|
label_width.set_text(
|
||||||
|
&mut common,
|
||||||
|
Translation::from_raw_text_string(format!("{}px", self.cur_raw_width)),
|
||||||
|
);
|
||||||
|
|
||||||
|
label_height.set_text(
|
||||||
|
&mut common,
|
||||||
|
Translation::from_raw_text_string(format!("{}px", self.cur_raw_height)),
|
||||||
|
);
|
||||||
|
|
||||||
|
let aspect = aspect_ratio(cur_width, cur_height);
|
||||||
|
|
||||||
|
label_display.set_text(
|
||||||
|
&mut common,
|
||||||
|
Translation::from_raw_text_string(format!("{}x{}\n{}:{}", cur_width, cur_height, aspect.0, aspect.1)),
|
||||||
|
);
|
||||||
|
|
||||||
|
label_display_name.set_text(&mut common, Translation::from_raw_text(&self.cur_display_name));
|
||||||
|
|
||||||
|
let mult = 0.1;
|
||||||
|
|
||||||
|
common.alterables.set_style(
|
||||||
|
self.id_rect_display,
|
||||||
|
StyleSetRequest::Width(length(cur_width as f32 * mult)),
|
||||||
|
);
|
||||||
|
|
||||||
|
common.alterables.set_style(
|
||||||
|
self.id_rect_display,
|
||||||
|
StyleSetRequest::Height(length(cur_height as f32 * mult)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.finish().ok()?;
|
||||||
|
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_ui_res(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
|
||||||
|
self.update_ui(layout).context("failed to update ui")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_wh(&self) -> (u16, u16) {
|
||||||
|
if self.cur_portrait {
|
||||||
|
(self.cur_raw_height, self.cur_raw_width)
|
||||||
|
} else {
|
||||||
|
(self.cur_raw_width, self.cur_raw_height)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
use wayvr_ipc::packet_server::WvrDisplay;
|
use wayvr_ipc::{
|
||||||
|
packet_client::{AttachTo, WvrDisplayCreateParams},
|
||||||
|
packet_server::WvrDisplay,
|
||||||
|
};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::button::ComponentButton,
|
components::{self, button::ComponentButton},
|
||||||
|
drawing::Color,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, HorizontalAlign, TextStyle},
|
||||||
taffy,
|
taffy::{self, prelude::length},
|
||||||
widget::{
|
widget::{
|
||||||
|
ConstructEssentials,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
|
util::WLength,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use wlx_common::dash_interface;
|
use wlx_common::dash_interface;
|
||||||
@@ -28,7 +34,7 @@ use crate::{
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum Task {
|
enum Task {
|
||||||
AddDisplay,
|
AddDisplay,
|
||||||
AddDisplayFinish,
|
AddDisplayFinish(add_display::Result),
|
||||||
Refresh,
|
Refresh,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +74,6 @@ impl View {
|
|||||||
|
|
||||||
let btn_add = parser_state.fetch_component_as::<ComponentButton>("btn_add")?;
|
let btn_add = parser_state.fetch_component_as::<ComponentButton>("btn_add")?;
|
||||||
tasks.handle_button(btn_add, Task::AddDisplay);
|
tasks.handle_button(btn_add, Task::AddDisplay);
|
||||||
|
|
||||||
tasks.push(Task::Refresh);
|
tasks.push(Task::Refresh);
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(State { view_add_display: None }));
|
let state = Rc::new(RefCell::new(State { view_add_display: None }));
|
||||||
@@ -96,7 +101,7 @@ impl View {
|
|||||||
for task in tasks {
|
for task in tasks {
|
||||||
match task {
|
match task {
|
||||||
Task::AddDisplay => self.add_display(),
|
Task::AddDisplay => self.add_display(),
|
||||||
Task::AddDisplayFinish => self.add_display_finish()?,
|
Task::AddDisplayFinish(result) => self.add_display_finish(interface, result)?,
|
||||||
Task::Refresh => self.refresh(layout, interface)?,
|
Task::Refresh => self.refresh(layout, interface)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +109,7 @@ impl View {
|
|||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
if let Some((_, view)) = &mut state.view_add_display {
|
if let Some((_, view)) = &mut state.view_add_display {
|
||||||
view.update()?;
|
view.update(layout)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -113,27 +118,48 @@ impl View {
|
|||||||
|
|
||||||
fn fill_display_list(
|
fn fill_display_list(
|
||||||
globals: &WguiGlobals,
|
globals: &WguiGlobals,
|
||||||
parent: WidgetID,
|
ess: &mut ConstructEssentials,
|
||||||
layout: &mut Layout,
|
|
||||||
list: Vec<WvrDisplay>,
|
list: Vec<WvrDisplay>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
let accent_color = globals.defaults().accent_color;
|
||||||
|
|
||||||
for entry in list {
|
for entry in list {
|
||||||
let (rect, _) = layout.add_child(
|
let aspect = entry.width as f32 / entry.height as f32;
|
||||||
parent,
|
|
||||||
WidgetRectangle::create(WidgetRectangleParams { ..Default::default() }),
|
let height = 96.0;
|
||||||
taffy::Style {
|
let width = height * aspect;
|
||||||
|
|
||||||
|
let (widget_button, button) = components::button::construct(
|
||||||
|
ess,
|
||||||
|
components::button::Params {
|
||||||
|
color: Some(accent_color.with_alpha(0.2)),
|
||||||
|
border_color: Some(accent_color),
|
||||||
|
style: taffy::Style {
|
||||||
align_items: Some(taffy::AlignItems::Center),
|
align_items: Some(taffy::AlignItems::Center),
|
||||||
justify_content: Some(taffy::JustifyContent::Center),
|
justify_content: Some(taffy::JustifyContent::Center),
|
||||||
|
size: taffy::Size {
|
||||||
|
width: length(width),
|
||||||
|
height: length(height),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
button.on_click(Box::new(move |_, _| {
|
||||||
|
log::error!("display options todo");
|
||||||
|
Ok(())
|
||||||
|
}));
|
||||||
|
|
||||||
let label_name = WidgetLabel::create(
|
let label_name = WidgetLabel::create(
|
||||||
&mut globals.get(),
|
&mut globals.get(),
|
||||||
WidgetLabelParams {
|
WidgetLabelParams {
|
||||||
content: Translation::from_raw_text(&entry.name),
|
content: Translation::from_raw_text(&entry.name),
|
||||||
style: TextStyle {
|
style: TextStyle {
|
||||||
weight: Some(FontWeight::Bold),
|
weight: Some(FontWeight::Bold),
|
||||||
|
wrap: true,
|
||||||
|
align: Some(HorizontalAlign::Center),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -147,8 +173,10 @@ fn fill_display_list(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
layout.add_child(rect.id, label_name, Default::default())?;
|
ess.layout.add_child(widget_button.id, label_name, Default::default())?;
|
||||||
layout.add_child(rect.id, label_resolution, Default::default())?;
|
ess
|
||||||
|
.layout
|
||||||
|
.add_child(widget_button.id, label_resolution, Default::default())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -162,7 +190,14 @@ impl View {
|
|||||||
let frontend_tasks = self.frontend_tasks.clone();
|
let frontend_tasks = self.frontend_tasks.clone();
|
||||||
let globals = self.globals.clone();
|
let globals = self.globals.clone();
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
|
|
||||||
|
let on_submit = {
|
||||||
let tasks = self.tasks.clone();
|
let tasks = self.tasks.clone();
|
||||||
|
Rc::new(move |result| {
|
||||||
|
tasks.push(Task::AddDisplayFinish(result));
|
||||||
|
tasks.push(Task::Refresh);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
Rc::new(move |data| {
|
Rc::new(move |data| {
|
||||||
state.borrow_mut().view_add_display = Some((
|
state.borrow_mut().view_add_display = Some((
|
||||||
@@ -172,7 +207,7 @@ impl View {
|
|||||||
globals: globals.clone(),
|
globals: globals.clone(),
|
||||||
layout: data.layout,
|
layout: data.layout,
|
||||||
parent_id: data.id_content,
|
parent_id: data.id_content,
|
||||||
on_submit: tasks.make_callback(Task::AddDisplayFinish),
|
on_submit: on_submit.clone(),
|
||||||
})?,
|
})?,
|
||||||
));
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -181,7 +216,18 @@ impl View {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_display_finish(&mut self) -> anyhow::Result<()> {
|
fn add_display_finish(
|
||||||
|
&mut self,
|
||||||
|
interface: &mut Box<dyn dash_interface::DashInterface>,
|
||||||
|
result: add_display::Result,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
interface.display_create(WvrDisplayCreateParams {
|
||||||
|
width: result.width,
|
||||||
|
height: result.height,
|
||||||
|
name: result.display_name,
|
||||||
|
attach_to: AttachTo::None,
|
||||||
|
scale: None,
|
||||||
|
})?;
|
||||||
self.state.borrow_mut().view_add_display = None;
|
self.state.borrow_mut().view_add_display = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -199,7 +245,14 @@ impl View {
|
|||||||
if list.is_empty() {
|
if list.is_empty() {
|
||||||
text = Some(Translation::from_translation_key("NO_DISPLAYS_FOUND"))
|
text = Some(Translation::from_translation_key("NO_DISPLAYS_FOUND"))
|
||||||
} else {
|
} else {
|
||||||
fill_display_list(&self.globals, self.id_list_parent, layout, list)?
|
fill_display_list(
|
||||||
|
&self.globals,
|
||||||
|
&mut ConstructEssentials {
|
||||||
|
layout,
|
||||||
|
parent: self.id_list_parent,
|
||||||
|
},
|
||||||
|
list,
|
||||||
|
)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => text = Some(Translation::from_raw_text(&format!("Error: {:?}", e))),
|
Err(e) => text = Some(Translation::from_raw_text(&format!("Error: {:?}", e))),
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ impl Default for Params<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ButtonClickEvent {}
|
pub struct ButtonClickEvent {}
|
||||||
pub type ButtonClickCallback = Box<dyn FnMut(&mut CallbackDataCommon, ButtonClickEvent) -> anyhow::Result<()>>;
|
pub type ButtonClickCallback = Box<dyn Fn(&mut CallbackDataCommon, ButtonClickEvent) -> anyhow::Result<()>>;
|
||||||
|
|
||||||
pub struct Colors {
|
pub struct Colors {
|
||||||
pub color: drawing::Color,
|
pub color: drawing::Color,
|
||||||
@@ -351,7 +351,7 @@ fn register_event_mouse_release(
|
|||||||
state.down = false;
|
state.down = false;
|
||||||
|
|
||||||
if state.hovered
|
if state.hovered
|
||||||
&& let Some(on_click) = &mut state.on_click
|
&& let Some(on_click) = &state.on_click
|
||||||
{
|
{
|
||||||
anim_hover(
|
anim_hover(
|
||||||
rect,
|
rect,
|
||||||
|
|||||||
@@ -26,13 +26,20 @@ impl Translation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_raw_text_rc(text: Rc<str>) -> Self {
|
pub const fn from_raw_text_rc(text: Rc<str>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
text,
|
text,
|
||||||
translated: false,
|
translated: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_raw_text_string(text: String) -> Self {
|
||||||
|
Self {
|
||||||
|
text: text.into(),
|
||||||
|
translated: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_raw_text(text: &str) -> Self {
|
pub fn from_raw_text(text: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
text: Rc::from(text),
|
text: Rc::from(text),
|
||||||
|
|||||||
Reference in New Issue
Block a user