Mainly fix elements
This commit is contained in:
parent
afc101effc
commit
ac733ecdc7
19 changed files with 754 additions and 620 deletions
|
@ -116,24 +116,26 @@ impl ButtonBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, gui_handler: Arc<GuiHandler<'_>>) -> Result<Arc<Button<'_>>> {
|
pub fn build<'a>(self, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<Button<'a>>> {
|
||||||
let framable = Framable::new(gui_handler.clone(), false)?;
|
let framable = Framable::new(gui_handler.width(), gui_handler.height(), false)?;
|
||||||
|
|
||||||
let normal = FillType::new(
|
let normal = FillType::new(
|
||||||
|
gui_handler,
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
self.normal
|
self.normal
|
||||||
.ok_or(anyhow!("normal button layout not set!"))?,
|
.ok_or(anyhow!("normal button layout not set!"))?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let selected = FillType::new(
|
let selected = FillType::new(
|
||||||
|
gui_handler,
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
self.selected
|
self.selected
|
||||||
.ok_or(anyhow!("selected button layout not set!"))?,
|
.ok_or(anyhow!("selected button layout not set!"))?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let click_executable = Executable::new(&gui_handler);
|
let click_executable = Executable::new();
|
||||||
let select_executable = Executable::new(&gui_handler);
|
let select_executable = Executable::new();
|
||||||
let on_select_executable = Executable::new(&gui_handler);
|
let on_select_executable = Executable::new();
|
||||||
|
|
||||||
#[cfg(feature = "audio")]
|
#[cfg(feature = "audio")]
|
||||||
let click_sound = self
|
let click_sound = self
|
||||||
|
@ -150,7 +152,6 @@ impl ButtonBuilder {
|
||||||
let clickable = Clickable::new(framable.clone(), click_executable.clone());
|
let clickable = Clickable::new(framable.clone(), click_executable.clone());
|
||||||
|
|
||||||
let selectable = Selectable::new(
|
let selectable = Selectable::new(
|
||||||
&gui_handler,
|
|
||||||
click_executable.clone(),
|
click_executable.clone(),
|
||||||
select_executable.clone(),
|
select_executable.clone(),
|
||||||
on_select_executable.clone(),
|
on_select_executable.clone(),
|
||||||
|
@ -183,10 +184,11 @@ impl ButtonBuilder {
|
||||||
);
|
);
|
||||||
|
|
||||||
if !self.text.is_empty() {
|
if !self.text.is_empty() {
|
||||||
textable.set_text(&self.text, false)?;
|
textable.set_text(gui_handler, &self.text, false)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let iconizable = IconizableWrapper::new(
|
let iconizable = IconizableWrapper::new(
|
||||||
|
gui_handler,
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
self.icon.map(IconBuilderType::Image),
|
self.icon.map(IconBuilderType::Image),
|
||||||
None,
|
None,
|
||||||
|
@ -194,6 +196,7 @@ impl ButtonBuilder {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let info_icon = IconizableWrapper::new(
|
let info_icon = IconizableWrapper::new(
|
||||||
|
gui_handler,
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
None,
|
None,
|
||||||
Some(IconizablePositioning {
|
Some(IconizablePositioning {
|
||||||
|
@ -268,7 +271,7 @@ pub struct Button<'a> {
|
||||||
_hover_sound: Option<Arc<Audible>>,
|
_hover_sound: Option<Arc<Audible>>,
|
||||||
|
|
||||||
click_executable: Arc<Executable<()>>,
|
click_executable: Arc<Executable<()>>,
|
||||||
select_executable: Arc<Executable<bool>>,
|
select_executable: Arc<Executable<(&'a mut GuiHandler<'a>, bool)>>,
|
||||||
on_select_executable: Arc<Executable<bool>>,
|
on_select_executable: Arc<Executable<bool>>,
|
||||||
|
|
||||||
normal: FillType,
|
normal: FillType,
|
||||||
|
@ -305,8 +308,8 @@ impl<'a> Button<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select(&self) -> Result<()> {
|
pub fn select(&self, gui_handler: &mut GuiHandler<'a>) -> Result<()> {
|
||||||
self.selectable.select()
|
self.selectable.select(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_callback<F>(&self, callback: F)
|
pub fn set_callback<F>(&self, callback: F)
|
||||||
|
@ -330,45 +333,53 @@ impl<'a> Button<'a> {
|
||||||
self.selectable.set_custom_callback(callback);
|
self.selectable.set_custom_callback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||||
self.textable.set_text(text, self.visible())
|
self.textable.set_text(gui_handler, text, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_icon(&self, icon: &Arc<Image>) -> Result<()> {
|
pub fn set_icon(&self, gui_handler: &mut GuiHandler<'_>, icon: &Arc<Image>) -> Result<()> {
|
||||||
self.iconizable.set_icon(icon, self.visible())
|
self.iconizable.set_icon(gui_handler, icon, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_icon_margon(&self, margin: u32) -> Result<()> {
|
pub fn set_icon_margon(&self, gui_handler: &mut GuiHandler<'_>, margin: u32) -> Result<()> {
|
||||||
self.iconizable.set_margin(margin)
|
self.iconizable.set_margin(gui_handler, margin)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_icon(&self) -> Result<()> {
|
pub fn clear_icon(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.iconizable.clear_icon(self.visible())
|
self.iconizable.clear_icon(gui_handler, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn icon(&self) -> Result<Option<Arc<Image>>> {
|
pub fn icon(&self) -> Result<Option<Arc<Image>>> {
|
||||||
self.iconizable.icon()
|
self.iconizable.icon()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_info_icon(&self, button: &Arc<Image>) -> Result<()> {
|
pub fn set_info_icon(
|
||||||
self.info_icon.set_icon(button, self.visible())
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
button: &Arc<Image>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.info_icon.set_icon(gui_handler, button, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_info_icon(&self) -> Result<()> {
|
pub fn clear_info_icon(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.info_icon.clear_icon(self.visible())
|
self.info_icon.clear_icon(gui_handler, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text(&self) -> Result<Option<String>> {
|
pub fn text(&self) -> Result<Option<String>> {
|
||||||
self.textable.text()
|
self.textable.text()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
|
pub fn set_text_color(
|
||||||
self.textable.set_text_color(text_color)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_color: Color,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.textable.set_text_color(gui_handler, text_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from(
|
pub fn try_from(
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
button_info: &ButtonInfo,
|
button_info: &ButtonInfo,
|
||||||
gui_handler: &Arc<GuiHandler<'a>>,
|
|
||||||
) -> Result<Arc<Self>> {
|
) -> Result<Arc<Self>> {
|
||||||
let mut button_builder = Button::builder()
|
let mut button_builder = Button::builder()
|
||||||
.set_select_mode(button_info.select_mode)
|
.set_select_mode(button_info.select_mode)
|
||||||
|
@ -420,14 +431,14 @@ impl<'a> Button<'a> {
|
||||||
button_info.margin,
|
button_info.margin,
|
||||||
);
|
);
|
||||||
|
|
||||||
let button = button_builder.build(gui_handler.clone())?;
|
let button = button_builder.build(gui_handler)?;
|
||||||
|
|
||||||
Ok(button)
|
Ok(button)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GuiElementTraits for Button<'a> {
|
impl<'a> GuiElementTraits<'a> for Button<'a> {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +446,7 @@ impl<'a> GuiElementTraits for Button<'a> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'b>(&'b self) -> Option<GuiElement<'b>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::Button(self))
|
Some(GuiElement::Button(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,26 +456,26 @@ impl<'a> Visibility for Button<'a> {
|
||||||
self.visible.load(SeqCst)
|
self.visible.load(SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
if visibility != self.visible.load(SeqCst) {
|
if visibility != self.visible.load(SeqCst) {
|
||||||
self.visible.store(visibility, SeqCst);
|
self.visible.store(visibility, SeqCst);
|
||||||
|
|
||||||
if visibility {
|
if visibility {
|
||||||
self.framable.add()?;
|
self.framable.add(gui_handler)?;
|
||||||
self.selectable.add()?;
|
self.selectable.add(gui_handler)?;
|
||||||
self.hoverable.add()?;
|
self.hoverable.add(gui_handler)?;
|
||||||
self.clickable.add()?;
|
self.clickable.add(gui_handler)?;
|
||||||
|
|
||||||
self.textable.enable()?;
|
self.textable.enable(gui_handler)?;
|
||||||
self.iconizable.enable()?;
|
self.iconizable.enable(gui_handler)?;
|
||||||
self.info_icon.enable()?;
|
self.info_icon.enable(gui_handler)?;
|
||||||
|
|
||||||
match *self.button_state.lock().unwrap() {
|
match *self.button_state.lock().unwrap() {
|
||||||
ButtonState::Normal => self.normal.enable()?,
|
ButtonState::Normal => self.normal.enable(gui_handler)?,
|
||||||
ButtonState::Selected => self.selected.enable()?,
|
ButtonState::Selected => self.selected.enable(gui_handler)?,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.disable_base()?;
|
self.disable_base(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,9 +483,10 @@ impl<'a> Visibility for Button<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Gridable for Button<'a> {
|
impl<'a> Gridable<'a> for Button<'a> {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -482,22 +494,23 @@ impl<'a> Gridable for Button<'a> {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.framable.set_frame(x, y, w, h, vert_align, hori_align);
|
self.framable
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align);
|
||||||
|
|
||||||
self.normal.update_frame()?;
|
self.normal.update_frame(gui_handler)?;
|
||||||
self.selected.update_frame()?;
|
self.selected.update_frame(gui_handler)?;
|
||||||
self.textable.update()?;
|
self.textable.update(gui_handler)?;
|
||||||
self.iconizable.update_frame()?;
|
self.iconizable.update_frame(gui_handler)?;
|
||||||
self.info_icon.update_frame()?;
|
self.info_icon.update_frame(gui_handler)?;
|
||||||
|
|
||||||
if self.select_mode == ButtonSelectMode::Bigger {
|
if self.select_mode == ButtonSelectMode::Bigger {
|
||||||
self.modify_hovered_vbo()?;
|
self.modify_hovered_vbo(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable<'_>>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
Some(&self.selectable)
|
Some(&self.selectable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,14 +538,6 @@ impl<'a> Gridable for Button<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for Button<'a> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible.load(SeqCst) {
|
|
||||||
self.disable_base().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// private
|
// private
|
||||||
impl<'a> Button<'a> {
|
impl<'a> Button<'a> {
|
||||||
// fn create_hovered_changed_callback(button: Arc<Button>) -> Result<()> {
|
// fn create_hovered_changed_callback(button: Arc<Button>) -> Result<()> {
|
||||||
|
@ -560,10 +565,10 @@ impl<'a> Button<'a> {
|
||||||
fn create_clicked_changed_callback(button: Arc<Button<'a>>) {
|
fn create_clicked_changed_callback(button: Arc<Button<'a>>) {
|
||||||
let button_weak = Arc::downgrade(&button);
|
let button_weak = Arc::downgrade(&button);
|
||||||
|
|
||||||
let clicked_changed = Box::new(move || {
|
let clicked_changed = Box::new(move |gui_handler| {
|
||||||
if let Some(button) = button_weak.upgrade() {
|
if let Some(button) = button_weak.upgrade() {
|
||||||
if button.clickable.clicked() {
|
if button.clickable.clicked() {
|
||||||
button.hoverable.set_hovered(false)?;
|
button.hoverable.set_hovered(gui_handler, false)?;
|
||||||
} else {
|
} else {
|
||||||
// if let Some(displayable) = displayable_weak.upgrade() {
|
// if let Some(displayable) = displayable_weak.upgrade() {
|
||||||
// displayable.update_frame()?;
|
// displayable.update_frame()?;
|
||||||
|
@ -582,12 +587,12 @@ impl<'a> Button<'a> {
|
||||||
fn create_selected_changed_callback(button: Arc<Button<'a>>) {
|
fn create_selected_changed_callback(button: Arc<Button<'a>>) {
|
||||||
let button_weak = Arc::downgrade(&button);
|
let button_weak = Arc::downgrade(&button);
|
||||||
|
|
||||||
let selected_changed = move |selected| {
|
let selected_changed = move |(gui_handler, selected)| {
|
||||||
if let Some(button) = button_weak.upgrade() {
|
if let Some(button) = button_weak.upgrade() {
|
||||||
if selected {
|
if selected {
|
||||||
button.set_button_state(ButtonState::Selected)?;
|
button.set_button_state(gui_handler, ButtonState::Selected)?;
|
||||||
} else {
|
} else {
|
||||||
button.set_button_state(ButtonState::Normal)?;
|
button.set_button_state(gui_handler, ButtonState::Normal)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,7 +602,7 @@ impl<'a> Button<'a> {
|
||||||
button.select_executable.set_callback(selected_changed);
|
button.select_executable.set_callback(selected_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_hovered_vbo(&self) -> Result<()> {
|
fn modify_hovered_vbo(&self, gui_handler: &GuiHandler<'_>) -> Result<()> {
|
||||||
assert!(
|
assert!(
|
||||||
self.framable.is_framed(),
|
self.framable.is_framed(),
|
||||||
"button frame needs to be defined before hovering can be calculated"
|
"button frame needs to be defined before hovering can be calculated"
|
||||||
|
@ -610,7 +615,7 @@ impl<'a> Button<'a> {
|
||||||
let buffer = displayable.buffer();
|
let buffer = displayable.buffer();
|
||||||
let mut frame = buffer.map_complete()?;
|
let mut frame = buffer.map_complete()?;
|
||||||
|
|
||||||
let ortho = self.framable.ortho();
|
let ortho = gui_handler.ortho();
|
||||||
let left = self.framable.left() as f32;
|
let left = self.framable.left() as f32;
|
||||||
let right = self.framable.right() as f32;
|
let right = self.framable.right() as f32;
|
||||||
let top = self.framable.top() as f32;
|
let top = self.framable.top() as f32;
|
||||||
|
@ -634,7 +639,7 @@ impl<'a> Button<'a> {
|
||||||
let buffer = colorable.buffer();
|
let buffer = colorable.buffer();
|
||||||
let mut frame = buffer.map_complete()?;
|
let mut frame = buffer.map_complete()?;
|
||||||
|
|
||||||
let ortho = self.framable.ortho();
|
let ortho = gui_handler.ortho();
|
||||||
let left = self.framable.left() as f32;
|
let left = self.framable.left() as f32;
|
||||||
let right = self.framable.right() as f32;
|
let right = self.framable.right() as f32;
|
||||||
let top = self.framable.top() as f32;
|
let top = self.framable.top() as f32;
|
||||||
|
@ -652,25 +657,29 @@ impl<'a> Button<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_base(&self) -> Result<()> {
|
fn disable_base(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.framable.delete()?;
|
self.framable.delete(gui_handler)?;
|
||||||
|
|
||||||
self.selectable.delete()?;
|
self.selectable.delete(gui_handler)?;
|
||||||
self.hoverable.delete()?;
|
self.hoverable.delete(gui_handler)?;
|
||||||
self.clickable.delete()?;
|
self.clickable.delete(gui_handler)?;
|
||||||
|
|
||||||
self.textable.disable()?;
|
self.textable.disable(gui_handler)?;
|
||||||
self.iconizable.disable()?;
|
self.iconizable.disable(gui_handler)?;
|
||||||
self.info_icon.disable()?;
|
self.info_icon.disable(gui_handler)?;
|
||||||
|
|
||||||
self.normal.disable()?;
|
self.normal.disable(gui_handler)?;
|
||||||
self.selected.disable()?;
|
self.selected.disable(gui_handler)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_button_state(&self, button_state: ButtonState) -> Result<()> {
|
fn set_button_state(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
button_state: ButtonState,
|
||||||
|
) -> Result<()> {
|
||||||
let mut current_button_state = self.button_state.lock().unwrap();
|
let mut current_button_state = self.button_state.lock().unwrap();
|
||||||
|
|
||||||
if button_state == *current_button_state {
|
if button_state == *current_button_state {
|
||||||
|
@ -682,16 +691,16 @@ impl<'a> Button<'a> {
|
||||||
match button_state {
|
match button_state {
|
||||||
ButtonState::Normal => {
|
ButtonState::Normal => {
|
||||||
if self.visible() {
|
if self.visible() {
|
||||||
self.normal.enable()?;
|
self.normal.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.selected.disable()?;
|
self.selected.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
ButtonState::Selected => {
|
ButtonState::Selected => {
|
||||||
self.normal.disable()?;
|
self.normal.disable(gui_handler)?;
|
||||||
|
|
||||||
if self.visible() {
|
if self.visible() {
|
||||||
self.selected.enable()?;
|
self.selected.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ use assetpath::AssetPath;
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering::SeqCst},
|
|
||||||
Arc,
|
Arc,
|
||||||
|
atomic::{AtomicBool, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -60,44 +60,52 @@ pub(crate) enum InnerFillType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InnerFillType {
|
impl InnerFillType {
|
||||||
pub(crate) fn new(framable: Arc<Framable>, fill_type_info: FillTypeInfo) -> Result<Self> {
|
pub(crate) fn new(
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
framable: Arc<Framable>,
|
||||||
|
fill_type_info: FillTypeInfo,
|
||||||
|
) -> Result<Self> {
|
||||||
match fill_type_info {
|
match fill_type_info {
|
||||||
FillTypeInfo::Element(descriptor, fill_type) => Ok(InnerFillType::Image(
|
FillTypeInfo::Element(descriptor, fill_type) => Ok(InnerFillType::Image(
|
||||||
Displayable::new(framable, descriptor, fill_type)?,
|
Displayable::new(gui_handler, framable, descriptor, fill_type)?,
|
||||||
)),
|
)),
|
||||||
FillTypeInfo::Image(path) => Ok(InnerFillType::Image(Displayable::new(
|
FillTypeInfo::Image(path) => Ok(InnerFillType::Image(Displayable::new(
|
||||||
|
gui_handler,
|
||||||
framable,
|
framable,
|
||||||
path,
|
path,
|
||||||
DisplayableFillType::Expand,
|
DisplayableFillType::Expand,
|
||||||
)?)),
|
)?)),
|
||||||
FillTypeInfo::Color(color, fill_type) => Ok(InnerFillType::Color(Colorable::new(
|
FillTypeInfo::Color(color, fill_type) => Ok(InnerFillType::Color(Colorable::new(
|
||||||
framable, color, fill_type,
|
gui_handler,
|
||||||
|
framable,
|
||||||
|
color,
|
||||||
|
fill_type,
|
||||||
)?)),
|
)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enable(&self) -> Result<()> {
|
pub(crate) fn enable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Image(displayable) => displayable.add()?,
|
Self::Image(displayable) => displayable.add(gui_handler)?,
|
||||||
Self::Color(colorable) => colorable.add()?,
|
Self::Color(colorable) => colorable.add(gui_handler)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn disable(&self) -> Result<()> {
|
pub(crate) fn disable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Image(displayable) => displayable.delete()?,
|
Self::Image(displayable) => displayable.delete(gui_handler)?,
|
||||||
Self::Color(colorable) => colorable.delete()?,
|
Self::Color(colorable) => colorable.delete(gui_handler)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_frame(&self) -> Result<()> {
|
pub(crate) fn update_frame(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Image(displayable) => displayable.update_frame()?,
|
Self::Image(displayable) => displayable.update_frame(gui_handler)?,
|
||||||
Self::Color(colorable) => colorable.update_frame()?,
|
Self::Color(colorable) => colorable.update_frame(gui_handler)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -119,9 +127,13 @@ pub(crate) struct FillType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FillType {
|
impl FillType {
|
||||||
pub(crate) fn new(framable: Arc<Framable>, fill_type_info: FillTypeInfo) -> Result<Self> {
|
pub(crate) fn new(
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
framable: Arc<Framable>,
|
||||||
|
fill_type_info: FillTypeInfo,
|
||||||
|
) -> Result<Self> {
|
||||||
let me = Self {
|
let me = Self {
|
||||||
inner: InnerFillType::new(framable.clone(), fill_type_info)?,
|
inner: InnerFillType::new(gui_handler, framable.clone(), fill_type_info)?,
|
||||||
visible: AtomicBool::new(false),
|
visible: AtomicBool::new(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,26 +142,26 @@ impl FillType {
|
||||||
Ok(me)
|
Ok(me)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enable(&self) -> Result<()> {
|
pub(crate) fn enable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if !self.visible.load(SeqCst) {
|
if !self.visible.load(SeqCst) {
|
||||||
self.visible.store(true, SeqCst);
|
self.visible.store(true, SeqCst);
|
||||||
self.inner.enable()?;
|
self.inner.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn disable(&self) -> Result<()> {
|
pub(crate) fn disable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if self.visible.load(SeqCst) {
|
if self.visible.load(SeqCst) {
|
||||||
self.visible.store(false, SeqCst);
|
self.visible.store(false, SeqCst);
|
||||||
self.inner.disable()?;
|
self.inner.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_frame(&self) -> Result<()> {
|
pub(crate) fn update_frame(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.inner.update_frame()
|
self.inner.update_frame(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_ui_layer(&self, layer: i32) {
|
pub(crate) fn set_ui_layer(&self, layer: i32) {
|
||||||
|
@ -183,14 +195,3 @@ impl PartialEq<FillTypeInfo> for FillType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for FillType {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible.load(SeqCst) {
|
|
||||||
match &self.inner {
|
|
||||||
InnerFillType::Image(displayable) => displayable.delete().unwrap(),
|
|
||||||
InnerFillType::Color(colorable) => colorable.delete().unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ use anyhow::Result;
|
||||||
use crate::builder::validator::gridinfo::GridInfo;
|
use crate::builder::validator::gridinfo::GridInfo;
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
|
|
||||||
Arc, RwLock, RwLockReadGuard,
|
Arc, RwLock, RwLockReadGuard,
|
||||||
|
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
use std::{ops::Deref, sync::Weak};
|
use std::{ops::Deref, sync::Weak};
|
||||||
|
|
||||||
|
@ -19,21 +19,21 @@ pub enum ConnectDirection {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum ChildState {
|
enum ChildState<'a> {
|
||||||
Some {
|
Some {
|
||||||
child: Arc<dyn GuiElementTraits>,
|
child: Arc<dyn GuiElementTraits<'a>>,
|
||||||
x: u32,
|
x: u32,
|
||||||
y: u32,
|
y: u32,
|
||||||
},
|
},
|
||||||
Extend {
|
Extend {
|
||||||
weak_child: Weak<dyn GuiElementTraits>,
|
weak_child: Weak<dyn GuiElementTraits<'a>>,
|
||||||
x: u32,
|
x: u32,
|
||||||
y: u32,
|
y: u32,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChildState {
|
impl<'a> ChildState<'a> {
|
||||||
fn downgrade(&self) -> Self {
|
fn downgrade(&self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Some { child, x, y } => Self::Extend {
|
Self::Some { child, x, y } => Self::Extend {
|
||||||
|
@ -62,7 +62,7 @@ impl ChildState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_some(&self) -> Option<(&Arc<dyn GuiElementTraits>, u32, u32)> {
|
fn get_some(&self) -> Option<(&Arc<dyn GuiElementTraits<'a>>, u32, u32)> {
|
||||||
match self {
|
match self {
|
||||||
ChildState::Some { child, x, y } => Some((child, *x, *y)),
|
ChildState::Some { child, x, y } => Some((child, *x, *y)),
|
||||||
ChildState::Extend { .. } => None,
|
ChildState::Extend { .. } => None,
|
||||||
|
@ -70,7 +70,7 @@ impl ChildState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self) -> Option<(Arc<dyn GuiElementTraits>, u32, u32)> {
|
fn get(&self) -> Option<(Arc<dyn GuiElementTraits<'a>>, u32, u32)> {
|
||||||
match self {
|
match self {
|
||||||
ChildState::Some { child, x, y } => Some((child.clone(), *x, *y)),
|
ChildState::Some { child, x, y } => Some((child.clone(), *x, *y)),
|
||||||
ChildState::Extend { weak_child, x, y } => {
|
ChildState::Extend { weak_child, x, y } => {
|
||||||
|
@ -82,7 +82,7 @@ impl ChildState {
|
||||||
|
|
||||||
fn map<C, R>(&self, f: C) -> Option<R>
|
fn map<C, R>(&self, f: C) -> Option<R>
|
||||||
where
|
where
|
||||||
C: FnOnce(&Arc<dyn GuiElementTraits>) -> R,
|
C: FnOnce(&Arc<dyn GuiElementTraits<'a>>) -> R,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
ChildState::Some { child, .. } => Some(f(child)),
|
ChildState::Some { child, .. } => Some(f(child)),
|
||||||
|
@ -92,13 +92,11 @@ impl ChildState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Grid {
|
pub struct Grid<'a> {
|
||||||
gui_handler: Arc<GuiHandler>,
|
|
||||||
|
|
||||||
pub(crate) framable: Arc<Framable>,
|
pub(crate) framable: Arc<Framable>,
|
||||||
background: RwLock<Option<FillType>>,
|
background: RwLock<Option<FillType>>,
|
||||||
|
|
||||||
children: RwLock<Vec<Vec<ChildState>>>,
|
children: RwLock<Vec<Vec<ChildState<'a>>>>,
|
||||||
|
|
||||||
dim_x: usize,
|
dim_x: usize,
|
||||||
dim_y: usize,
|
dim_y: usize,
|
||||||
|
@ -109,17 +107,15 @@ pub struct Grid {
|
||||||
visible: AtomicBool,
|
visible: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Grid {
|
impl<'a> Grid<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
gui_handler: Arc<GuiHandler>,
|
gui_handler: &GuiHandler<'a>,
|
||||||
dim_x: usize,
|
dim_x: usize,
|
||||||
dim_y: usize,
|
dim_y: usize,
|
||||||
top_level: bool,
|
top_level: bool,
|
||||||
) -> Result<Arc<Self>> {
|
) -> Result<Arc<Self>> {
|
||||||
let grid = Arc::new(Grid {
|
let grid = Arc::new(Grid {
|
||||||
gui_handler: gui_handler.clone(),
|
framable: Framable::new(gui_handler.width(), gui_handler.height(), top_level)?,
|
||||||
|
|
||||||
framable: Framable::new(gui_handler, top_level)?,
|
|
||||||
background: RwLock::new(None),
|
background: RwLock::new(None),
|
||||||
|
|
||||||
children: RwLock::new(vec![vec![ChildState::None; dim_y]; dim_x]),
|
children: RwLock::new(vec![vec![ChildState::None; dim_y]; dim_x]),
|
||||||
|
@ -138,9 +134,9 @@ impl Grid {
|
||||||
|
|
||||||
grid.framable.add_callback(
|
grid.framable.add_callback(
|
||||||
weak_grid.clone(),
|
weak_grid.clone(),
|
||||||
Box::new(move || {
|
Box::new(move |gui_handler| {
|
||||||
if let Some(grid) = weak_grid.upgrade() {
|
if let Some(grid) = weak_grid.upgrade() {
|
||||||
grid.calculate_child_positions()?;
|
grid.calculate_child_positions(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -155,8 +151,18 @@ impl Grid {
|
||||||
(self.dim_x, self.dim_y)
|
(self.dim_x, self.dim_y)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_background(&self, background: impl Into<FillTypeInfo>) -> Result<()> {
|
pub fn set_background(
|
||||||
super::set_background(self.visible(), &self.framable, &self.background, background)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
background: impl Into<FillTypeInfo>,
|
||||||
|
) -> Result<()> {
|
||||||
|
super::set_background(
|
||||||
|
gui_handler,
|
||||||
|
self.visible(),
|
||||||
|
&self.framable,
|
||||||
|
&self.background,
|
||||||
|
background,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn background(&self) -> RwLockReadGuard<'_, Option<FillType>> {
|
pub(crate) fn background(&self) -> RwLockReadGuard<'_, Option<FillType>> {
|
||||||
|
@ -171,7 +177,7 @@ impl Grid {
|
||||||
self.padding.store(padding, SeqCst);
|
self.padding.store(padding, SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn child_at(&self, x: usize, y: usize) -> Result<Option<Arc<dyn GuiElementTraits>>> {
|
pub fn child_at(&self, x: usize, y: usize) -> Result<Option<Arc<dyn GuiElementTraits<'a>>>> {
|
||||||
if x >= self.dim_x {
|
if x >= self.dim_x {
|
||||||
return Err(anyhow::anyhow!(
|
return Err(anyhow::anyhow!(
|
||||||
"Tried to access Grid at {} while only being {} wide",
|
"Tried to access Grid at {} while only being {} wide",
|
||||||
|
@ -191,7 +197,12 @@ impl Grid {
|
||||||
Ok(self.children.read().unwrap()[x][y].map(|c| c.clone()))
|
Ok(self.children.read().unwrap()[x][y].map(|c| c.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn detach(&self, pos_x: usize, pos_y: usize) -> Result<Option<Arc<dyn GuiElementTraits>>> {
|
pub fn detach(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
pos_x: usize,
|
||||||
|
pos_y: usize,
|
||||||
|
) -> Result<Option<Arc<dyn GuiElementTraits<'a>>>> {
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
if pos_x >= self.dim_x as usize {
|
if pos_x >= self.dim_x as usize {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -220,7 +231,7 @@ impl Grid {
|
||||||
Some((child, _x, _y)) => {
|
Some((child, _x, _y)) => {
|
||||||
if self.visible() {
|
if self.visible() {
|
||||||
if let Some(child_visibility) = child.visibility() {
|
if let Some(child_visibility) = child.visibility() {
|
||||||
child_visibility.set_visibility(false)?;
|
child_visibility.set_visibility(gui_handler, false)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +242,11 @@ impl Grid {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if item got detached
|
/// Returns `true` if item got detached
|
||||||
pub fn detach_item(&self, item: Arc<dyn GuiElementTraits>) -> Result<bool> {
|
pub fn detach_item(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
item: Arc<dyn GuiElementTraits<'a>>,
|
||||||
|
) -> Result<bool> {
|
||||||
let mut grid = self.children.write().unwrap();
|
let mut grid = self.children.write().unwrap();
|
||||||
let mut removed = false;
|
let mut removed = false;
|
||||||
|
|
||||||
|
@ -250,7 +265,7 @@ impl Grid {
|
||||||
|
|
||||||
if self.visible() {
|
if self.visible() {
|
||||||
if let Some(child_visibility) = child.visibility() {
|
if let Some(child_visibility) = child.visibility() {
|
||||||
child_visibility.set_visibility(false)?;
|
child_visibility.set_visibility(gui_handler, false)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,20 +288,20 @@ impl Grid {
|
||||||
Ok(removed)
|
Ok(removed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&self, x: i32, y: i32) -> Result<()> {
|
pub fn set_position(&self, gui_handler: &mut GuiHandler<'_>, x: i32, y: i32) -> Result<()> {
|
||||||
// update own position
|
// update own position
|
||||||
self.framable.change_position(x, y)?;
|
self.framable.change_position(gui_handler, x, y)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.update_frame()?;
|
background.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.calculate_child_positions()?;
|
self.calculate_child_positions(gui_handler)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_child_positions(&self) -> Result<()> {
|
fn calculate_child_positions(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
// recalculate positions of the children
|
// recalculate positions of the children
|
||||||
let children = self.children.read().unwrap();
|
let children = self.children.read().unwrap();
|
||||||
|
|
||||||
|
@ -294,7 +309,7 @@ impl Grid {
|
||||||
for (y, child_opt) in row.iter().enumerate() {
|
for (y, child_opt) in row.iter().enumerate() {
|
||||||
if let Some((child, dim_x, dim_y)) = child_opt.get_some() {
|
if let Some((child, dim_x, dim_y)) = child_opt.get_some() {
|
||||||
if let Some(child_gridable) = child.gridable() {
|
if let Some(child_gridable) = child.gridable() {
|
||||||
self.child_position(child_gridable, x, y, dim_x, dim_y)?;
|
self.child_position(gui_handler, child_gridable, x, y, dim_x, dim_y)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,18 +329,18 @@ impl Grid {
|
||||||
(width, height)
|
(width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disallow_position_scale(&self) -> Result<()> {
|
pub fn disallow_position_scale(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.framable.allow_position_scale(false)
|
self.framable.allow_position_scale(gui_handler, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disallow_size_scale(&self) -> Result<()> {
|
pub fn disallow_size_scale(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.framable.allow_size_scale(false)
|
self.framable.allow_size_scale(gui_handler, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect<'a>(
|
pub fn connect(
|
||||||
&self,
|
&self,
|
||||||
direction: ConnectDirection,
|
direction: ConnectDirection,
|
||||||
elements: impl IntoIterator<Item = (usize, &'a Arc<Selectable>)>,
|
elements: impl IntoIterator<Item = (usize, &'a Arc<Selectable<'a>>)>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (index, selectable) in elements {
|
for (index, selectable) in elements {
|
||||||
match direction {
|
match direction {
|
||||||
|
@ -393,7 +408,8 @@ impl Grid {
|
||||||
|
|
||||||
pub fn attach(
|
pub fn attach(
|
||||||
&self,
|
&self,
|
||||||
child: Arc<dyn GuiElementTraits>,
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
child: Arc<dyn GuiElementTraits<'a>>,
|
||||||
pos_x: usize,
|
pos_x: usize,
|
||||||
pos_y: usize,
|
pos_y: usize,
|
||||||
dim_x: u32,
|
dim_x: u32,
|
||||||
|
@ -431,7 +447,7 @@ impl Grid {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.framable.is_framed() {
|
if self.framable.is_framed() {
|
||||||
self.child_position(child_gridable, pos_x, pos_y, dim_x, dim_y)?;
|
self.child_position(gui_handler, child_gridable, pos_x, pos_y, dim_x, dim_y)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_gridable.set_layer(self.framable.ui_layer())?;
|
child_gridable.set_layer(self.framable.ui_layer())?;
|
||||||
|
@ -442,7 +458,7 @@ impl Grid {
|
||||||
ChildState::Some { child, .. } => {
|
ChildState::Some { child, .. } => {
|
||||||
if self.visible() {
|
if self.visible() {
|
||||||
if let Some(child_visibility) = child.visibility() {
|
if let Some(child_visibility) = child.visibility() {
|
||||||
child_visibility.set_visibility(false)?;
|
child_visibility.set_visibility(gui_handler, false)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,7 +468,7 @@ impl Grid {
|
||||||
|
|
||||||
if self.visible() {
|
if self.visible() {
|
||||||
if let Some(child_visibility) = child.visibility() {
|
if let Some(child_visibility) = child.visibility() {
|
||||||
child_visibility.set_visibility(true)?;
|
child_visibility.set_visibility(gui_handler, true)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,11 +500,11 @@ impl Grid {
|
||||||
|
|
||||||
pub fn try_from(
|
pub fn try_from(
|
||||||
grid_info: &GridInfo,
|
grid_info: &GridInfo,
|
||||||
gui_handler: &Arc<GuiHandler>,
|
gui_handler: &mut GuiHandler<'a>,
|
||||||
top_level: bool,
|
top_level: bool,
|
||||||
) -> Result<Arc<Self>> {
|
) -> Result<Arc<Self>> {
|
||||||
let grid = Grid::new(
|
let grid = Grid::new(
|
||||||
gui_handler.clone(),
|
gui_handler,
|
||||||
grid_info.x_dimension.get()?,
|
grid_info.x_dimension.get()?,
|
||||||
grid_info.y_dimension.get()?,
|
grid_info.y_dimension.get()?,
|
||||||
top_level,
|
top_level,
|
||||||
|
@ -498,27 +514,33 @@ impl Grid {
|
||||||
grid.set_padding(grid_info.padding);
|
grid.set_padding(grid_info.padding);
|
||||||
|
|
||||||
if let Some(background) = &grid_info.background_type {
|
if let Some(background) = &grid_info.background_type {
|
||||||
grid.set_background(background.clone())?;
|
grid.set_background(gui_handler, background.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(grid)
|
Ok(grid)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_position_unscaled(&self, x: i32, y: i32) -> Result<()> {
|
pub fn change_position_unscaled(
|
||||||
self.framable.change_position_unscaled(x, y)?;
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.framable.change_position_unscaled(gui_handler, x, y)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.update_frame()?;
|
background.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.calculate_child_positions()?;
|
self.calculate_child_positions(gui_handler)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child_position(
|
fn child_position(
|
||||||
&self,
|
&self,
|
||||||
child: &dyn Gridable,
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
child: &dyn Gridable<'_>,
|
||||||
pos_x: usize,
|
pos_x: usize,
|
||||||
pos_y: usize,
|
pos_y: usize,
|
||||||
dim_x: u32,
|
dim_x: u32,
|
||||||
|
@ -546,8 +568,8 @@ impl Grid {
|
||||||
single_height + (dim_y - 1) as i32 * (single_height + self.margin.load(SeqCst) as i32)
|
single_height + (dim_y - 1) as i32 * (single_height + self.margin.load(SeqCst) as i32)
|
||||||
};
|
};
|
||||||
|
|
||||||
let win_width = self.gui_handler.width();
|
let win_width = gui_handler.width();
|
||||||
let win_height = self.gui_handler.height();
|
let win_height = gui_handler.height();
|
||||||
|
|
||||||
let y_align = match self.framable.vertical_alignment() {
|
let y_align = match self.framable.vertical_alignment() {
|
||||||
VerticalAlign::Top => 0,
|
VerticalAlign::Top => 0,
|
||||||
|
@ -571,6 +593,7 @@ impl Grid {
|
||||||
+ pos_y as i32 * (single_height + self.margin.load(SeqCst) as i32);
|
+ pos_y as i32 * (single_height + self.margin.load(SeqCst) as i32);
|
||||||
|
|
||||||
child.set_frame(
|
child.set_frame(
|
||||||
|
gui_handler,
|
||||||
child_x - x_align as i32,
|
child_x - x_align as i32,
|
||||||
child_y - y_align as i32,
|
child_y - y_align as i32,
|
||||||
child_width as u32,
|
child_width as u32,
|
||||||
|
@ -582,12 +605,12 @@ impl Grid {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select(&self, x: u32, y: u32) -> Result<()> {
|
pub fn select(&self, gui_handler: &mut GuiHandler<'_>, x: u32, y: u32) -> Result<()> {
|
||||||
match self.children.read().unwrap()[x as usize][y as usize].get_some() {
|
match self.children.read().unwrap()[x as usize][y as usize].get_some() {
|
||||||
Some((child, ..)) => match child.gridable() {
|
Some((child, ..)) => match child.gridable() {
|
||||||
Some(gridable) => match gridable.selectable() {
|
Some(gridable) => match gridable.selectable() {
|
||||||
Some(selectable) => {
|
Some(selectable) => {
|
||||||
selectable.select()?;
|
selectable.select(gui_handler)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => panic!("gridable at position ({}, {}), is not selectable", x, y),
|
None => panic!("gridable at position ({}, {}), is not selectable", x, y),
|
||||||
|
@ -599,26 +622,26 @@ impl Grid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_tree(&self) -> Result<()> {
|
fn disable_tree(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.framable.delete()?;
|
self.framable.delete(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.disable()?;
|
background.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_tree_visibility(false)?;
|
self.set_tree_visibility(gui_handler, false)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_tree_visibility(&self, visible: bool) -> Result<()> {
|
fn set_tree_visibility(&self, gui_handler: &mut GuiHandler<'_>, visible: bool) -> Result<()> {
|
||||||
let tree = self.children.read().unwrap();
|
let tree = self.children.read().unwrap();
|
||||||
|
|
||||||
for row in tree.deref() {
|
for row in tree.deref() {
|
||||||
for child_state in row {
|
for child_state in row {
|
||||||
if let Some((child, ..)) = child_state.get_some() {
|
if let Some((child, ..)) = child_state.get_some() {
|
||||||
if let Some(visibility) = child.visibility() {
|
if let Some(visibility) = child.visibility() {
|
||||||
visibility.set_visibility(visible)?;
|
visibility.set_visibility(gui_handler, visible)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -629,8 +652,8 @@ impl Grid {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_neighbours(
|
fn set_neighbours(
|
||||||
grid: &Vec<Vec<ChildState>>,
|
grid: &Vec<Vec<ChildState<'_>>>,
|
||||||
current_child: &Arc<Selectable>,
|
current_child: &Arc<Selectable<'a>>,
|
||||||
pos: (usize, usize),
|
pos: (usize, usize),
|
||||||
dim: (usize, usize),
|
dim: (usize, usize),
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -651,8 +674,8 @@ impl Grid {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_north_neighbour(
|
fn set_north_neighbour(
|
||||||
grid: &Vec<Vec<ChildState>>,
|
grid: &Vec<Vec<ChildState<'_>>>,
|
||||||
current_child: &Arc<Selectable>,
|
current_child: &Arc<Selectable<'a>>,
|
||||||
pos: (usize, usize),
|
pos: (usize, usize),
|
||||||
dim: (usize, usize),
|
dim: (usize, usize),
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
|
@ -669,8 +692,8 @@ impl Grid {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_south_neighbour(
|
fn set_south_neighbour(
|
||||||
grid: &Vec<Vec<ChildState>>,
|
grid: &Vec<Vec<ChildState<'_>>>,
|
||||||
current_child: &Arc<Selectable>,
|
current_child: &Arc<Selectable<'a>>,
|
||||||
pos: (usize, usize),
|
pos: (usize, usize),
|
||||||
dim: (usize, usize),
|
dim: (usize, usize),
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
|
@ -687,8 +710,8 @@ impl Grid {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_east_neighbour(
|
fn set_east_neighbour(
|
||||||
grid: &Vec<Vec<ChildState>>,
|
grid: &Vec<Vec<ChildState<'_>>>,
|
||||||
current_child: &Arc<Selectable>,
|
current_child: &Arc<Selectable<'a>>,
|
||||||
pos: (usize, usize),
|
pos: (usize, usize),
|
||||||
dim: (usize, usize),
|
dim: (usize, usize),
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
|
@ -705,8 +728,8 @@ impl Grid {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_west_neighbour(
|
fn set_west_neighbour(
|
||||||
grid: &Vec<Vec<ChildState>>,
|
grid: &Vec<Vec<ChildState<'_>>>,
|
||||||
current_child: &Arc<Selectable>,
|
current_child: &Arc<Selectable<'a>>,
|
||||||
pos: (usize, usize),
|
pos: (usize, usize),
|
||||||
dim: (usize, usize),
|
dim: (usize, usize),
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
|
@ -723,11 +746,11 @@ impl Grid {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn search_neighbour_in_direction(
|
fn search_neighbour_in_direction(
|
||||||
grid: &Vec<Vec<ChildState>>,
|
grid: &Vec<Vec<ChildState<'_>>>,
|
||||||
pos: (usize, usize),
|
pos: (usize, usize),
|
||||||
dir: (i32, i32),
|
dir: (i32, i32),
|
||||||
dim: (usize, usize),
|
dim: (usize, usize),
|
||||||
) -> Option<Arc<Selectable>> {
|
) -> Option<Arc<Selectable<'a>>> {
|
||||||
let (mut x, mut y) = pos;
|
let (mut x, mut y) = pos;
|
||||||
let (x_step, y_step) = dir;
|
let (x_step, y_step) = dir;
|
||||||
let (dim_x, dim_y) = dim;
|
let (dim_x, dim_y) = dim;
|
||||||
|
@ -751,8 +774,8 @@ impl Grid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiElementTraits for Grid {
|
impl<'a> GuiElementTraits<'a> for Grid<'a> {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,30 +783,30 @@ impl GuiElementTraits for Grid {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::Grid(self))
|
Some(GuiElement::Grid(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visibility for Grid {
|
impl<'a> Visibility for Grid<'a> {
|
||||||
fn visible(&self) -> bool {
|
fn visible(&self) -> bool {
|
||||||
self.visible.load(SeqCst)
|
self.visible.load(SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
if visibility != self.visible.load(SeqCst) {
|
if visibility != self.visible.load(SeqCst) {
|
||||||
self.visible.store(visibility, SeqCst);
|
self.visible.store(visibility, SeqCst);
|
||||||
|
|
||||||
if visibility {
|
if visibility {
|
||||||
Framable::add(&self.framable)?;
|
self.framable.add(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.enable()?;
|
background.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_tree_visibility(true)?;
|
self.set_tree_visibility(gui_handler, true)?;
|
||||||
} else {
|
} else {
|
||||||
self.disable_tree()?;
|
self.disable_tree(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,9 +814,10 @@ impl Visibility for Grid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gridable for Grid {
|
impl<'a> Gridable<'a> for Grid<'a> {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -801,18 +825,19 @@ impl Gridable for Grid {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.framable.set_frame(x, y, w, h, vert_align, hori_align);
|
self.framable
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align);
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.update_frame()?;
|
background.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.calculate_child_positions()?;
|
self.calculate_child_positions(gui_handler)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,11 +869,3 @@ impl Gridable for Grid {
|
||||||
self.framable.position()
|
self.framable.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Grid {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible.load(SeqCst) {
|
|
||||||
self.disable_tree().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,14 +8,14 @@ use utilities::prelude::*;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering::SeqCst},
|
|
||||||
Arc, RwLock,
|
Arc, RwLock,
|
||||||
|
atomic::{AtomicBool, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
IconBuilderType,
|
||||||
fill_type::FillType,
|
fill_type::FillType,
|
||||||
wrapper::{IconizableWrapper, TextableWrapper},
|
wrapper::{IconizableWrapper, TextableWrapper},
|
||||||
IconBuilderType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct IconBuilder {
|
pub struct IconBuilder {
|
||||||
|
@ -65,15 +65,20 @@ impl IconBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, gui_handler: Arc<GuiHandler>) -> Result<Arc<Icon>> {
|
pub fn build(self, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<Icon>> {
|
||||||
let framable = Framable::new(gui_handler, false)?;
|
let framable = Framable::new(gui_handler.width(), gui_handler.height(), false)?;
|
||||||
|
|
||||||
let iconizable_wrapper =
|
let iconizable_wrapper = IconizableWrapper::new(
|
||||||
IconizableWrapper::new(framable.clone(), self.content, None, self.margin)?;
|
gui_handler,
|
||||||
|
framable.clone(),
|
||||||
|
self.content,
|
||||||
|
None,
|
||||||
|
self.margin,
|
||||||
|
)?;
|
||||||
|
|
||||||
let background = RwLock::new(
|
let background = RwLock::new(
|
||||||
self.background
|
self.background
|
||||||
.map(|info| FillType::new(framable.clone(), info))
|
.map(|info| FillType::new(gui_handler, framable.clone(), info))
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -85,10 +90,11 @@ impl IconBuilder {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(text) = self.text {
|
if let Some(text) = self.text {
|
||||||
textable_wrapper.set_text(&text, false)?;
|
textable_wrapper.set_text(gui_handler, &text, false)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let info_icon = IconizableWrapper::new(
|
let info_icon = IconizableWrapper::new(
|
||||||
|
gui_handler,
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
None,
|
None,
|
||||||
Some(IconizablePositioning {
|
Some(IconizablePositioning {
|
||||||
|
@ -135,51 +141,74 @@ impl Icon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_icon(&self) -> Result<()> {
|
pub fn clear_icon(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.iconizable_wrapper.clear_icon(self.visible())
|
self.iconizable_wrapper
|
||||||
|
.clear_icon(gui_handler, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_icon(&self, icon: &Arc<Image>) -> Result<()> {
|
pub fn set_icon(&self, gui_handler: &mut GuiHandler<'_>, icon: &Arc<Image>) -> Result<()> {
|
||||||
self.iconizable_wrapper.set_icon(icon, self.visible())
|
self.iconizable_wrapper
|
||||||
|
.set_icon(gui_handler, icon, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_icon_from_path(&self, asset_path: AssetPath) -> Result<()> {
|
pub fn set_icon_from_path(
|
||||||
self.iconizable_wrapper.set_icon(asset_path, self.visible())
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
asset_path: AssetPath,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.iconizable_wrapper
|
||||||
|
.set_icon(gui_handler, asset_path, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_margin(&self, margin: u32) -> Result<()> {
|
pub fn set_margin(&self, gui_handler: &mut GuiHandler<'_>, margin: u32) -> Result<()> {
|
||||||
self.iconizable_wrapper.set_margin(margin)
|
self.iconizable_wrapper.set_margin(gui_handler, margin)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_background(&self, background: impl Into<FillTypeInfo>) -> Result<()> {
|
pub fn set_background(
|
||||||
super::set_background(self.visible(), &self.framable, &self.background, background)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
background: impl Into<FillTypeInfo>,
|
||||||
|
) -> Result<()> {
|
||||||
|
super::set_background(
|
||||||
|
gui_handler,
|
||||||
|
self.visible(),
|
||||||
|
&self.framable,
|
||||||
|
&self.background,
|
||||||
|
background,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_background(&self) {
|
pub fn clear_background(&self) {
|
||||||
*self.background.write().unwrap() = None;
|
*self.background.write().unwrap() = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||||
self.textable_wrapper.set_text(text, self.visible())
|
self.textable_wrapper
|
||||||
|
.set_text(gui_handler, text, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_text(&self) -> Result<()> {
|
pub fn clear_text(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.textable_wrapper.set_text("", self.visible())
|
self.textable_wrapper
|
||||||
|
.set_text(gui_handler, "", self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, color: Color) -> Result<()> {
|
pub fn set_text_color(&self, gui_handler: &mut GuiHandler<'_>, color: Color) -> Result<()> {
|
||||||
self.textable_wrapper.set_text_color(color)
|
self.textable_wrapper.set_text_color(gui_handler, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_info_icon(&self, button: &Arc<Image>) -> Result<()> {
|
pub fn set_info_icon(
|
||||||
self.info_icon.set_icon(button, self.visible())
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
button: &Arc<Image>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.info_icon.set_icon(gui_handler, button, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_info_icon(&self) -> Result<()> {
|
pub fn clear_info_icon(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.info_icon.clear_icon(self.visible())
|
self.info_icon.clear_icon(gui_handler, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from(icon_info: &IconInfo, gui_handler: &Arc<GuiHandler>) -> Result<Arc<Self>> {
|
pub fn try_from(icon_info: &IconInfo, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<Self>> {
|
||||||
let mut icon_builder = Icon::builder().set_text_color(icon_info.text_color);
|
let mut icon_builder = Icon::builder().set_text_color(icon_info.text_color);
|
||||||
|
|
||||||
if let Some(text_ratio) = icon_info.text_ratio {
|
if let Some(text_ratio) = icon_info.text_ratio {
|
||||||
|
@ -207,7 +236,7 @@ impl Icon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
icon_builder.build(gui_handler.clone())
|
icon_builder.build(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn icon(&self) -> Result<Option<Arc<Image>>> {
|
pub fn icon(&self) -> Result<Option<Arc<Image>>> {
|
||||||
|
@ -221,23 +250,23 @@ impl Icon {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_base(&self) -> Result<()> {
|
fn disable_base(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.framable.delete()?;
|
self.framable.delete(gui_handler)?;
|
||||||
|
|
||||||
self.iconizable_wrapper.disable()?;
|
self.iconizable_wrapper.disable(gui_handler)?;
|
||||||
self.textable_wrapper.disable()?;
|
self.textable_wrapper.disable(gui_handler)?;
|
||||||
self.info_icon.disable()?;
|
self.info_icon.disable(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.disable()?;
|
background.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiElementTraits for Icon {
|
impl<'a> GuiElementTraits<'a> for Icon {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +274,7 @@ impl GuiElementTraits for Icon {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::Icon(self))
|
Some(GuiElement::Icon(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,22 +284,22 @@ impl Visibility for Icon {
|
||||||
self.visible.load(SeqCst)
|
self.visible.load(SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
if visibility != self.visible.load(SeqCst) {
|
if visibility != self.visible.load(SeqCst) {
|
||||||
self.visible.store(visibility, SeqCst);
|
self.visible.store(visibility, SeqCst);
|
||||||
|
|
||||||
if visibility {
|
if visibility {
|
||||||
self.framable.add()?;
|
self.framable.add(gui_handler)?;
|
||||||
|
|
||||||
self.info_icon.enable()?;
|
self.info_icon.enable(gui_handler)?;
|
||||||
self.iconizable_wrapper.enable()?;
|
self.iconizable_wrapper.enable(gui_handler)?;
|
||||||
self.textable_wrapper.enable()?;
|
self.textable_wrapper.enable(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.enable()?;
|
background.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.disable_base()?;
|
self.disable_base(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,9 +307,10 @@ impl Visibility for Icon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gridable for Icon {
|
impl<'a> Gridable<'a> for Icon {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -288,20 +318,21 @@ impl Gridable for Icon {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.framable.set_frame(x, y, w, h, vert_align, hori_align);
|
self.framable
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align);
|
||||||
|
|
||||||
self.iconizable_wrapper.update_frame()?;
|
self.iconizable_wrapper.update_frame(gui_handler)?;
|
||||||
self.textable_wrapper.update()?;
|
self.textable_wrapper.update(gui_handler)?;
|
||||||
self.info_icon.update_frame()?;
|
self.info_icon.update_frame(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.update_frame()?;
|
background.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,11 +357,3 @@ impl Gridable for Icon {
|
||||||
self.framable.position()
|
self.framable.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Icon {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible.load(SeqCst) {
|
|
||||||
self.disable_base().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ use super::{
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering::SeqCst},
|
|
||||||
Arc, RwLock,
|
Arc, RwLock,
|
||||||
|
atomic::{AtomicBool, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -57,8 +57,8 @@ impl LabelBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, gui_handler: Arc<GuiHandler>) -> Result<Arc<Label>> {
|
pub fn build(self, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<Label>> {
|
||||||
let framable = Framable::new(gui_handler, false)?;
|
let framable = Framable::new(gui_handler.width(), gui_handler.height(), false)?;
|
||||||
|
|
||||||
let textable_wrapper = TextableWrapper::new(
|
let textable_wrapper = TextableWrapper::new(
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
|
@ -68,15 +68,16 @@ impl LabelBuilder {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(text) = &self.text {
|
if let Some(text) = &self.text {
|
||||||
textable_wrapper.set_text(text, false)?;
|
textable_wrapper.set_text(gui_handler, text, false)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let background = self
|
let background = self
|
||||||
.background
|
.background
|
||||||
.map(|info| FillType::new(framable.clone(), info))
|
.map(|info| FillType::new(gui_handler, framable.clone(), info))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let info_icon = IconizableWrapper::new(
|
let info_icon = IconizableWrapper::new(
|
||||||
|
gui_handler,
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
None,
|
None,
|
||||||
Some(IconizablePositioning {
|
Some(IconizablePositioning {
|
||||||
|
@ -120,43 +121,67 @@ impl Label {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||||
self.textable_wrapper.set_text(text, self.visible())
|
self.textable_wrapper
|
||||||
|
.set_text(gui_handler, text, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text(&self) -> Result<Option<String>> {
|
pub fn text(&self) -> Result<Option<String>> {
|
||||||
self.textable_wrapper.text()
|
self.textable_wrapper.text()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
|
pub fn set_text_color(
|
||||||
self.textable_wrapper.set_text_color(text_color)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_color: Color,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.textable_wrapper
|
||||||
|
.set_text_color(gui_handler, text_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_alignment(&self, alignment: TextAlignment) -> Result<()> {
|
pub fn set_alignment(
|
||||||
self.textable_wrapper.set_alignment(alignment)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
alignment: TextAlignment,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.textable_wrapper.set_alignment(gui_handler, alignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_ratio(&self, ratio: f32) -> Result<()> {
|
pub fn set_text_ratio(&self, gui_handler: &mut GuiHandler<'_>, ratio: f32) -> Result<()> {
|
||||||
self.textable_wrapper.set_height_ratio(ratio)
|
self.textable_wrapper.set_height_ratio(gui_handler, ratio)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_ratio(&self) -> f32 {
|
pub fn text_ratio(&self) -> f32 {
|
||||||
self.textable_wrapper.height_ratio()
|
self.textable_wrapper.height_ratio()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_info_icon(&self, button: &Arc<Image>) -> Result<()> {
|
pub fn set_info_icon(
|
||||||
self.info_icon.set_icon(button, self.visible())
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
button: &Arc<Image>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.info_icon.set_icon(gui_handler, button, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_info_icon(&self) -> Result<()> {
|
pub fn clear_info_icon(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.info_icon.clear_icon(self.visible())
|
self.info_icon.clear_icon(gui_handler, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_background(&self, background: impl Into<FillTypeInfo>) -> Result<()> {
|
pub fn set_background(
|
||||||
super::set_background(self.visible(), &self.framable, &self.background, background)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
background: impl Into<FillTypeInfo>,
|
||||||
|
) -> Result<()> {
|
||||||
|
super::set_background(
|
||||||
|
gui_handler,
|
||||||
|
self.visible(),
|
||||||
|
&self.framable,
|
||||||
|
&self.background,
|
||||||
|
background,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from(label_info: &LabelInfo, gui_handler: &Arc<GuiHandler>) -> Result<Arc<Self>> {
|
pub fn try_from(label_info: &LabelInfo, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<Self>> {
|
||||||
let text = label_info.text.read().unwrap().clone();
|
let text = label_info.text.read().unwrap().clone();
|
||||||
let color = label_info.text_color;
|
let color = label_info.text_color;
|
||||||
|
|
||||||
|
@ -176,25 +201,25 @@ impl Label {
|
||||||
label_builder = label_builder.set_text(text);
|
label_builder = label_builder.set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
label_builder.build(gui_handler.clone())
|
label_builder.build(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_base(&self) -> Result<()> {
|
fn disable_base(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.framable.delete()?;
|
self.framable.delete(gui_handler)?;
|
||||||
|
|
||||||
self.textable_wrapper.disable()?;
|
self.textable_wrapper.disable(gui_handler)?;
|
||||||
self.info_icon.disable()?;
|
self.info_icon.disable(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.disable()?;
|
background.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiElementTraits for Label {
|
impl<'a> GuiElementTraits<'a> for Label {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +227,7 @@ impl GuiElementTraits for Label {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::Label(self))
|
Some(GuiElement::Label(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,21 +237,21 @@ impl Visibility for Label {
|
||||||
self.visible.load(SeqCst)
|
self.visible.load(SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
if visibility != self.visible() {
|
if visibility != self.visible() {
|
||||||
self.visible.store(visibility, SeqCst);
|
self.visible.store(visibility, SeqCst);
|
||||||
|
|
||||||
if visibility {
|
if visibility {
|
||||||
self.framable.add()?;
|
self.framable.add(gui_handler)?;
|
||||||
|
|
||||||
self.textable_wrapper.enable()?;
|
self.textable_wrapper.enable(gui_handler)?;
|
||||||
self.info_icon.enable()?;
|
self.info_icon.enable(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.enable()?;
|
background.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.disable_base()?;
|
self.disable_base(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,9 +259,10 @@ impl Visibility for Label {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gridable for Label {
|
impl<'a> Gridable<'a> for Label {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -244,19 +270,20 @@ impl Gridable for Label {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.framable.set_frame(x, y, w, h, vert_align, hori_align);
|
self.framable
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align);
|
||||||
|
|
||||||
self.textable_wrapper.update()?;
|
self.textable_wrapper.update(gui_handler)?;
|
||||||
self.info_icon.update_frame()?;
|
self.info_icon.update_frame(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.update_frame()?;
|
background.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,11 +307,3 @@ impl Gridable for Label {
|
||||||
self.framable.position()
|
self.framable.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Label {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible.load(SeqCst) {
|
|
||||||
self.disable_base().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub mod prelude;
|
||||||
mod wrapper;
|
mod wrapper;
|
||||||
|
|
||||||
pub(crate) fn set_background(
|
pub(crate) fn set_background(
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
visible: bool,
|
visible: bool,
|
||||||
framable: &Arc<Framable>,
|
framable: &Arc<Framable>,
|
||||||
current: &RwLock<Option<FillType>>,
|
current: &RwLock<Option<FillType>>,
|
||||||
|
@ -37,14 +38,14 @@ pub(crate) fn set_background(
|
||||||
};
|
};
|
||||||
|
|
||||||
if update {
|
if update {
|
||||||
let fill_type = FillType::new(framable.clone(), fill_info)?;
|
let fill_type = FillType::new(gui_handler, framable.clone(), fill_info)?;
|
||||||
|
|
||||||
if framable.is_framed() {
|
if framable.is_framed() {
|
||||||
fill_type.update_frame()?;
|
fill_type.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if visible {
|
if visible {
|
||||||
fill_type.enable()?;
|
fill_type.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
*current_background = Some(fill_type);
|
*current_background = Some(fill_type);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{builder::validator::multi_line_labelinfo::MultiLineLabelInfo, prelude::*};
|
use crate::{builder::validator::multi_line_labelinfo::MultiLineLabelInfo, prelude::*};
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicU32, Ordering::SeqCst},
|
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
|
atomic::{AtomicU32, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
@ -56,13 +56,13 @@ impl MultiLineLabelBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, gui_handler: Arc<GuiHandler>) -> Result<Arc<MultiLineLabel>> {
|
pub fn build<'a>(self, gui_handler: &mut GuiHandler<'a>) -> Result<Arc<MultiLineLabel<'a>>> {
|
||||||
let base_grid = Grid::new(gui_handler.clone(), 1, self.line_count as usize, false)?;
|
let base_grid = Grid::new(gui_handler, 1, self.line_count as usize, false)?;
|
||||||
base_grid.set_margin(0);
|
base_grid.set_margin(0);
|
||||||
base_grid.set_padding(0);
|
base_grid.set_padding(0);
|
||||||
|
|
||||||
if let Some(background) = self.background {
|
if let Some(background) = self.background {
|
||||||
base_grid.set_background(background)?;
|
base_grid.set_background(gui_handler, background)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..self.line_count {
|
for i in 0..self.line_count {
|
||||||
|
@ -70,9 +70,9 @@ impl MultiLineLabelBuilder {
|
||||||
.set_ratio(self.text_ratio)
|
.set_ratio(self.text_ratio)
|
||||||
.set_text_color(self.text_color)
|
.set_text_color(self.text_color)
|
||||||
.set_text_alignment(self.text_alignment)
|
.set_text_alignment(self.text_alignment)
|
||||||
.build(gui_handler.clone())?;
|
.build(gui_handler)?;
|
||||||
|
|
||||||
base_grid.attach(label, 0, i as usize, 1, 1)?;
|
base_grid.attach(gui_handler, label, 0, i as usize, 1, 1)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Arc::new(MultiLineLabel {
|
Ok(Arc::new(MultiLineLabel {
|
||||||
|
@ -85,15 +85,15 @@ impl MultiLineLabelBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MultiLineLabel {
|
pub struct MultiLineLabel<'a> {
|
||||||
grid: Arc<Grid>,
|
grid: Arc<Grid<'a>>,
|
||||||
|
|
||||||
characters_per_line: AtomicU32,
|
characters_per_line: AtomicU32,
|
||||||
text: Mutex<String>,
|
text: Mutex<String>,
|
||||||
splits: Mutex<Vec<String>>,
|
splits: Mutex<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MultiLineLabel {
|
impl<'a> MultiLineLabel<'a> {
|
||||||
pub fn builder() -> MultiLineLabelBuilder {
|
pub fn builder() -> MultiLineLabelBuilder {
|
||||||
MultiLineLabelBuilder {
|
MultiLineLabelBuilder {
|
||||||
text_alignment: TextAlignment::Center,
|
text_alignment: TextAlignment::Center,
|
||||||
|
@ -107,13 +107,13 @@ impl MultiLineLabel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||||
*self.text.lock().unwrap() = text.to_string();
|
*self.text.lock().unwrap() = text.to_string();
|
||||||
|
|
||||||
self.update_text()
|
self.update_text(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_text(&self) -> Result<()> {
|
fn update_text(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
let text = self.text.lock().unwrap();
|
let text = self.text.lock().unwrap();
|
||||||
let splits = text.split(' ');
|
let splits = text.split(' ');
|
||||||
let character_count = self.characters_per_line.load(SeqCst) as usize;
|
let character_count = self.characters_per_line.load(SeqCst) as usize;
|
||||||
|
@ -145,9 +145,9 @@ impl MultiLineLabel {
|
||||||
|
|
||||||
self.iter_label(|label, y| {
|
self.iter_label(|label, y| {
|
||||||
if y < lines.len() {
|
if y < lines.len() {
|
||||||
label.set_text(&lines[y])?;
|
label.set_text(gui_handler, &lines[y])?;
|
||||||
} else {
|
} else {
|
||||||
label.set_text("")?;
|
label.set_text(gui_handler, "")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -158,25 +158,37 @@ impl MultiLineLabel {
|
||||||
self.text.lock().unwrap().clone()
|
self.text.lock().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
|
pub fn set_text_color(
|
||||||
self.iter_label(|label, _| label.set_text_color(text_color))
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_color: Color,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.iter_label(|label, _| label.set_text_color(gui_handler, text_color))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_alignment(&self, alignment: TextAlignment) -> Result<()> {
|
pub fn set_alignment(
|
||||||
self.iter_label(|label, _| label.set_alignment(alignment))
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
alignment: TextAlignment,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.iter_label(|label, _| label.set_alignment(gui_handler, alignment))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_ratio(&self, ratio: f32) -> Result<()> {
|
pub fn set_text_ratio(&self, gui_handler: &mut GuiHandler<'_>, ratio: f32) -> Result<()> {
|
||||||
self.iter_label(|label, _| label.set_text_ratio(ratio))
|
self.iter_label(|label, _| label.set_text_ratio(gui_handler, ratio))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_background(&self, background: impl Into<FillTypeInfo>) -> Result<()> {
|
pub fn set_background(
|
||||||
self.grid.set_background(background)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
background: impl Into<FillTypeInfo>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.grid.set_background(gui_handler, background)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from(
|
pub fn try_from(
|
||||||
multi_line_label_info: &MultiLineLabelInfo,
|
multi_line_label_info: &MultiLineLabelInfo,
|
||||||
gui_handler: &Arc<GuiHandler>,
|
gui_handler: &mut GuiHandler<'a>,
|
||||||
) -> Result<Arc<Self>> {
|
) -> Result<Arc<Self>> {
|
||||||
let text = multi_line_label_info.text.read().unwrap().clone();
|
let text = multi_line_label_info.text.read().unwrap().clone();
|
||||||
let color = multi_line_label_info.text_color;
|
let color = multi_line_label_info.text_color;
|
||||||
|
@ -204,12 +216,12 @@ impl MultiLineLabel {
|
||||||
multi_line_label_builder = multi_line_label_builder.set_text(text);
|
multi_line_label_builder = multi_line_label_builder.set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
multi_line_label_builder.build(gui_handler.clone())
|
multi_line_label_builder.build(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_label<F>(&self, f: F) -> Result<()>
|
fn iter_label<F>(&self, mut f: F) -> Result<()>
|
||||||
where
|
where
|
||||||
F: Fn(&Label, usize) -> Result<()>,
|
F: FnMut(&Label, usize) -> Result<()>,
|
||||||
{
|
{
|
||||||
for y in 0..self.grid.dimensions().1 {
|
for y in 0..self.grid.dimensions().1 {
|
||||||
let child = self.grid.child_at(0, y)?.unwrap();
|
let child = self.grid.child_at(0, y)?.unwrap();
|
||||||
|
@ -223,8 +235,8 @@ impl MultiLineLabel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiElementTraits for MultiLineLabel {
|
impl<'a> GuiElementTraits<'a> for MultiLineLabel<'a> {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,24 +244,25 @@ impl GuiElementTraits for MultiLineLabel {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::MultiLineLabel(self))
|
Some(GuiElement::MultiLineLabel(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visibility for MultiLineLabel {
|
impl<'a> Visibility for MultiLineLabel<'a> {
|
||||||
fn visible(&self) -> bool {
|
fn visible(&self) -> bool {
|
||||||
self.grid.visible()
|
self.grid.visible()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
self.grid.set_visibility(visibility)
|
self.grid.set_visibility(gui_handler, visibility)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gridable for MultiLineLabel {
|
impl<'a> Gridable<'a> for MultiLineLabel<'a> {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -257,7 +270,8 @@ impl Gridable for MultiLineLabel {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.grid.set_frame(x, y, w, h, vert_align, hori_align)?;
|
self.grid
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align)?;
|
||||||
|
|
||||||
if let Some(child) = self.grid.child_at(0, 0)? {
|
if let Some(child) = self.grid.child_at(0, 0)? {
|
||||||
let gui_element = child.downcast().unwrap();
|
let gui_element = child.downcast().unwrap();
|
||||||
|
@ -279,13 +293,13 @@ impl Gridable for MultiLineLabel {
|
||||||
self.characters_per_line
|
self.characters_per_line
|
||||||
.store(max_letter_count as u32, SeqCst);
|
.store(max_letter_count as u32, SeqCst);
|
||||||
|
|
||||||
self.update_text()?;
|
self.update_text(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicU32, Ordering::SeqCst},
|
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
|
atomic::{AtomicU32, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
@ -62,13 +62,16 @@ impl MultiLineTextFieldBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, gui_handler: Arc<GuiHandler>) -> Result<Arc<MultiLineTextField>> {
|
pub fn build<'a>(
|
||||||
let base_grid = Grid::new(gui_handler.clone(), 1, self.line_count as usize, false)?;
|
self,
|
||||||
|
gui_handler: &mut GuiHandler<'a>,
|
||||||
|
) -> Result<Arc<MultiLineTextField<'a>>> {
|
||||||
|
let base_grid = Grid::new(gui_handler, 1, self.line_count as usize, false)?;
|
||||||
base_grid.set_margin(0);
|
base_grid.set_margin(0);
|
||||||
base_grid.set_padding(0);
|
base_grid.set_padding(0);
|
||||||
|
|
||||||
if let Some(background) = self.background {
|
if let Some(background) = self.background {
|
||||||
base_grid.set_background(background)?;
|
base_grid.set_background(gui_handler, background)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..self.line_count {
|
for i in 0..self.line_count {
|
||||||
|
@ -76,14 +79,14 @@ impl MultiLineTextFieldBuilder {
|
||||||
.set_ratio(self.text_ratio)
|
.set_ratio(self.text_ratio)
|
||||||
.set_text_color(self.text_color)
|
.set_text_color(self.text_color)
|
||||||
.set_text_alignment(self.text_alignment)
|
.set_text_alignment(self.text_alignment)
|
||||||
.build(gui_handler.clone())?;
|
.build(gui_handler)?;
|
||||||
|
|
||||||
base_grid.attach(label, 0, i as usize, 1, 1)?;
|
base_grid.attach(gui_handler, label, 0, i as usize, 1, 1)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = Arc::new(SplittedText::new(self.text));
|
let text = Arc::new(SplittedText::new(self.text));
|
||||||
let text_changed_exec = Executable::new(&gui_handler);
|
let text_changed_exec = Executable::new();
|
||||||
let writeable = Writeable::new(gui_handler, text.clone(), text_changed_exec.clone())?;
|
let writeable = Writeable::new(text.clone(), text_changed_exec.clone())?;
|
||||||
|
|
||||||
let multi_line_text_field = Arc::new(MultiLineTextField {
|
let multi_line_text_field = Arc::new(MultiLineTextField {
|
||||||
grid: base_grid,
|
grid: base_grid,
|
||||||
|
@ -96,9 +99,9 @@ impl MultiLineTextFieldBuilder {
|
||||||
multi_line_text_field.text_changed_exec.set_callback({
|
multi_line_text_field.text_changed_exec.set_callback({
|
||||||
let weak_tf = Arc::downgrade(&multi_line_text_field);
|
let weak_tf = Arc::downgrade(&multi_line_text_field);
|
||||||
|
|
||||||
move |_text| {
|
move |(gui_handler, _text)| {
|
||||||
if let Some(tf) = weak_tf.upgrade() {
|
if let Some(tf) = weak_tf.upgrade() {
|
||||||
tf.update_text()?;
|
tf.update_text(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -173,13 +176,13 @@ impl SplittedText {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModifyText for SplittedText {
|
impl ModifyText for SplittedText {
|
||||||
fn set_text(&self, text: String) -> Result<()> {
|
fn set_text(&self, _gui_handler: &mut GuiHandler<'_>, text: String) -> Result<()> {
|
||||||
*self.text.lock().unwrap() = text;
|
*self.text.lock().unwrap() = text;
|
||||||
|
|
||||||
self.update_text()
|
self.update_text()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_letter(&self, letter: char) -> Result<String> {
|
fn add_letter(&self, _gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<String> {
|
||||||
*self.text.lock().unwrap() += &format!("{}", letter);
|
*self.text.lock().unwrap() += &format!("{}", letter);
|
||||||
|
|
||||||
self.update_text()?;
|
self.update_text()?;
|
||||||
|
@ -187,7 +190,7 @@ impl ModifyText for SplittedText {
|
||||||
Ok(self.text.lock().unwrap().clone())
|
Ok(self.text.lock().unwrap().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_last(&self) -> Result<Option<String>> {
|
fn remove_last(&self, _gui_handler: &mut GuiHandler<'_>) -> Result<Option<String>> {
|
||||||
self.text.lock().unwrap().pop();
|
self.text.lock().unwrap().pop();
|
||||||
|
|
||||||
self.update_text()?;
|
self.update_text()?;
|
||||||
|
@ -197,15 +200,15 @@ impl ModifyText for SplittedText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MultiLineTextField {
|
pub struct MultiLineTextField<'a> {
|
||||||
grid: Arc<Grid>,
|
grid: Arc<Grid<'a>>,
|
||||||
|
|
||||||
text: Arc<SplittedText>,
|
text: Arc<SplittedText>,
|
||||||
text_changed_exec: Arc<Executable<Option<String>>>,
|
text_changed_exec: Arc<Executable<(&'a mut GuiHandler<'a>, Option<String>)>>,
|
||||||
writeable: Arc<Writeable>,
|
writeable: Arc<Writeable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MultiLineTextField {
|
impl<'a> MultiLineTextField<'a> {
|
||||||
pub fn builder() -> MultiLineTextFieldBuilder {
|
pub fn builder() -> MultiLineTextFieldBuilder {
|
||||||
MultiLineTextFieldBuilder {
|
MultiLineTextFieldBuilder {
|
||||||
text_alignment: TextAlignment::Center,
|
text_alignment: TextAlignment::Center,
|
||||||
|
@ -219,18 +222,18 @@ impl MultiLineTextField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||||
self.text.set_text(text.to_string())
|
self.text.set_text(gui_handler, text.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_text(&self) -> Result<()> {
|
fn update_text(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
let lines = self.text.lines();
|
let lines = self.text.lines();
|
||||||
|
|
||||||
self.iter_label(|label, y| {
|
self.iter_label(|label, y| {
|
||||||
if y < lines.len() {
|
if y < lines.len() {
|
||||||
label.set_text(&lines[y])?;
|
label.set_text(gui_handler, &lines[y])?;
|
||||||
} else {
|
} else {
|
||||||
label.set_text("")?;
|
label.set_text(gui_handler, "")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -245,14 +248,19 @@ impl MultiLineTextField {
|
||||||
|
|
||||||
let weak_self = Arc::downgrade(self);
|
let weak_self = Arc::downgrade(self);
|
||||||
|
|
||||||
self.writeable.set_activation_changed(move |active| {
|
self.writeable
|
||||||
|
.set_activation_changed(move |gui_handler, active| {
|
||||||
if let Some(me) = weak_self.upgrade() {
|
if let Some(me) = weak_self.upgrade() {
|
||||||
if active {
|
if active {
|
||||||
me.grid
|
me.grid.set_background(
|
||||||
.set_background((focus_color, DisplayableFillType::Expand))?;
|
gui_handler,
|
||||||
|
(focus_color, DisplayableFillType::Expand),
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
me.grid
|
me.grid.set_background(
|
||||||
.set_background((normal_color, DisplayableFillType::Expand))?;
|
gui_handler,
|
||||||
|
(normal_color, DisplayableFillType::Expand),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,32 +274,44 @@ impl MultiLineTextField {
|
||||||
self.text.text()
|
self.text.text()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
|
pub fn set_text_color(
|
||||||
self.iter_label(|label, _| label.set_text_color(text_color))
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_color: Color,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.iter_label(|label, _| label.set_text_color(gui_handler, text_color))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_alignment(&self, alignment: TextAlignment) -> Result<()> {
|
pub fn set_alignment(
|
||||||
self.iter_label(|label, _| label.set_alignment(alignment))
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
alignment: TextAlignment,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.iter_label(|label, _| label.set_alignment(gui_handler, alignment))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_ratio(&self, ratio: f32) -> Result<()> {
|
pub fn set_text_ratio(&self, gui_handler: &mut GuiHandler<'_>, ratio: f32) -> Result<()> {
|
||||||
self.iter_label(|label, _| label.set_text_ratio(ratio))
|
self.iter_label(|label, _| label.set_text_ratio(gui_handler, ratio))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_background(self: &Arc<Self>, background: impl Into<FillTypeInfo>) -> Result<()> {
|
pub fn set_background(
|
||||||
self.grid.set_background(background)?;
|
self: &Arc<Self>,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
background: impl Into<FillTypeInfo>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.grid.set_background(gui_handler, background)?;
|
||||||
self.update_color_change();
|
self.update_color_change();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus_input(&self) -> Result<()> {
|
pub fn focus_input(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.writeable.set_active()
|
self.writeable.set_active(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from(
|
pub fn try_from(
|
||||||
multi_line_text_field_info: &MultiLineTextFieldInfo,
|
multi_line_text_field_info: &MultiLineTextFieldInfo,
|
||||||
gui_handler: &Arc<GuiHandler>,
|
gui_handler: &mut GuiHandler<'a>,
|
||||||
) -> Result<Arc<Self>> {
|
) -> Result<Arc<Self>> {
|
||||||
let text = multi_line_text_field_info.text.read().unwrap().clone();
|
let text = multi_line_text_field_info.text.read().unwrap().clone();
|
||||||
let color = multi_line_text_field_info.text_color;
|
let color = multi_line_text_field_info.text_color;
|
||||||
|
@ -319,12 +339,12 @@ impl MultiLineTextField {
|
||||||
multi_line_text_field_builder = multi_line_text_field_builder.set_text(text);
|
multi_line_text_field_builder = multi_line_text_field_builder.set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
multi_line_text_field_builder.build(gui_handler.clone())
|
multi_line_text_field_builder.build(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_label<F>(&self, f: F) -> Result<()>
|
fn iter_label<F>(&self, mut f: F) -> Result<()>
|
||||||
where
|
where
|
||||||
F: Fn(&Label, usize) -> Result<()>,
|
F: FnMut(&Label, usize) -> Result<()>,
|
||||||
{
|
{
|
||||||
for y in 0..self.grid.dimensions().1 {
|
for y in 0..self.grid.dimensions().1 {
|
||||||
let child = self.grid.child_at(0, y)?.unwrap();
|
let child = self.grid.child_at(0, y)?.unwrap();
|
||||||
|
@ -338,8 +358,8 @@ impl MultiLineTextField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiElementTraits for MultiLineTextField {
|
impl<'a> GuiElementTraits<'a> for MultiLineTextField<'a> {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,32 +367,33 @@ impl GuiElementTraits for MultiLineTextField {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::MultiLineTextField(self))
|
Some(GuiElement::MultiLineTextField(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visibility for MultiLineTextField {
|
impl<'a> Visibility for MultiLineTextField<'a> {
|
||||||
fn visible(&self) -> bool {
|
fn visible(&self) -> bool {
|
||||||
self.grid.visible()
|
self.grid.visible()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
if visibility != self.visible() {
|
if visibility != self.visible() {
|
||||||
if visibility {
|
if visibility {
|
||||||
self.writeable.add()?;
|
self.writeable.add(gui_handler)?;
|
||||||
} else {
|
} else {
|
||||||
self.writeable.delete()?;
|
self.writeable.delete(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.grid.set_visibility(visibility)
|
self.grid.set_visibility(gui_handler, visibility)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gridable for MultiLineTextField {
|
impl<'a> Gridable<'a> for MultiLineTextField<'a> {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -380,7 +401,8 @@ impl Gridable for MultiLineTextField {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.grid.set_frame(x, y, w, h, vert_align, hori_align)?;
|
self.grid
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align)?;
|
||||||
|
|
||||||
if let Some(child) = self.grid.child_at(0, 0)? {
|
if let Some(child) = self.grid.child_at(0, 0)? {
|
||||||
let gui_element = child.downcast().unwrap();
|
let gui_element = child.downcast().unwrap();
|
||||||
|
@ -401,13 +423,13 @@ impl Gridable for MultiLineTextField {
|
||||||
|
|
||||||
self.text.set_characters_per_line(max_letter_count as u32);
|
self.text.set_characters_per_line(max_letter_count as u32);
|
||||||
|
|
||||||
self.update_text()?;
|
self.update_text(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,11 +446,3 @@ impl Gridable for MultiLineTextField {
|
||||||
self.grid.position_extent()
|
self.grid.position_extent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for MultiLineTextField {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible() {
|
|
||||||
self.writeable.delete().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ use crate::{builder::validator::progressbar_info::ProgressBarInfo, prelude::*};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering::SeqCst},
|
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
|
atomic::{AtomicBool, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
|
|
||||||
|
@ -74,17 +74,17 @@ impl ProgressBarBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, gui_handler: Arc<GuiHandler>) -> Result<Arc<ProgressBar>> {
|
pub fn build(self, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<ProgressBar>> {
|
||||||
let framable = Framable::new(gui_handler, false)?;
|
let framable = Framable::new(gui_handler.width(), gui_handler.height(), false)?;
|
||||||
|
|
||||||
let background = self
|
let background = self
|
||||||
.background
|
.background
|
||||||
.map(|r#type| FillType::new(framable.clone(), r#type))
|
.map(|r#type| FillType::new(gui_handler, framable.clone(), r#type))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let foreground = self
|
let foreground = self
|
||||||
.foreground
|
.foreground
|
||||||
.map(|r#type| FillType::new(framable.clone(), r#type))
|
.map(|r#type| FillType::new(gui_handler, framable.clone(), r#type))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let textable_wrapper = TextableWrapper::new(
|
let textable_wrapper = TextableWrapper::new(
|
||||||
|
@ -95,7 +95,7 @@ impl ProgressBarBuilder {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(text) = self.text {
|
if let Some(text) = self.text {
|
||||||
textable_wrapper.set_text(&text, false)?;
|
textable_wrapper.set_text(gui_handler, &text, false)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Arc::new(ProgressBar {
|
Ok(Arc::new(ProgressBar {
|
||||||
|
@ -140,7 +140,7 @@ impl ProgressBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_progress(&self, mut progress: f32) -> Result<()> {
|
pub fn set_progress(&self, gui_handler: &mut GuiHandler<'_>, mut progress: f32) -> Result<()> {
|
||||||
if progress < 0.0 {
|
if progress < 0.0 {
|
||||||
progress = 0.0;
|
progress = 0.0;
|
||||||
} else if progress > 1.0 {
|
} else if progress > 1.0 {
|
||||||
|
@ -156,22 +156,22 @@ impl ProgressBar {
|
||||||
InnerFillType::Image(displayable) => {
|
InnerFillType::Image(displayable) => {
|
||||||
displayable.set_right_factor(progress);
|
displayable.set_right_factor(progress);
|
||||||
displayable.set_right_uv_factor(progress);
|
displayable.set_right_uv_factor(progress);
|
||||||
displayable.update_frame()?;
|
displayable.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
InnerFillType::Color(colorable) => {
|
InnerFillType::Color(colorable) => {
|
||||||
colorable.set_right_factor(progress);
|
colorable.set_right_factor(progress);
|
||||||
colorable.update_frame()?;
|
colorable.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GrowDirection::BottomToTop => match &foreground.inner {
|
GrowDirection::BottomToTop => match &foreground.inner {
|
||||||
InnerFillType::Image(displayable) => {
|
InnerFillType::Image(displayable) => {
|
||||||
displayable.set_top_factor(progress);
|
displayable.set_top_factor(progress);
|
||||||
displayable.set_top_uv_factor(progress);
|
displayable.set_top_uv_factor(progress);
|
||||||
displayable.update_frame()?;
|
displayable.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
InnerFillType::Color(colorable) => {
|
InnerFillType::Color(colorable) => {
|
||||||
colorable.set_top_factor(progress);
|
colorable.set_top_factor(progress);
|
||||||
colorable.update_frame()?;
|
colorable.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -181,25 +181,36 @@ impl ProgressBar {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||||
self.textable_wrapper.set_text(text, self.visible())
|
self.textable_wrapper
|
||||||
|
.set_text(gui_handler, text, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
|
pub fn set_text_color(
|
||||||
self.textable_wrapper.set_text_color(text_color)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_color: Color,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.textable_wrapper
|
||||||
|
.set_text_color(gui_handler, text_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_ratio(&self, ratio: f32) -> Result<()> {
|
pub fn set_text_ratio(&self, gui_handler: &mut GuiHandler<'_>, ratio: f32) -> Result<()> {
|
||||||
self.textable_wrapper.set_height_ratio(ratio)
|
self.textable_wrapper.set_height_ratio(gui_handler, ratio)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_alignment(&self, text_alignment: TextAlignment) -> Result<()> {
|
pub fn set_text_alignment(
|
||||||
self.textable_wrapper.set_alignment(text_alignment)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_alignment: TextAlignment,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.textable_wrapper
|
||||||
|
.set_alignment(gui_handler, text_alignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from(
|
pub fn try_from(
|
||||||
progress_bar_info: &ProgressBarInfo,
|
progress_bar_info: &ProgressBarInfo,
|
||||||
gui_handler: &Arc<GuiHandler>,
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
) -> Result<Arc<Self>> {
|
) -> Result<Arc<Self>> {
|
||||||
let mut progress_bar_builder = ProgressBar::builder()
|
let mut progress_bar_builder = ProgressBar::builder()
|
||||||
.set_text_alignment(progress_bar_info.text_alignment)
|
.set_text_alignment(progress_bar_info.text_alignment)
|
||||||
|
@ -227,7 +238,7 @@ impl ProgressBar {
|
||||||
progress_bar_builder = progress_bar_builder.set_grow_direction(dir);
|
progress_bar_builder = progress_bar_builder.set_grow_direction(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
progress_bar_builder.build(gui_handler.clone())
|
progress_bar_builder.build(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -235,25 +246,25 @@ impl ProgressBar {
|
||||||
*self.progress.lock().unwrap()
|
*self.progress.lock().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_base(&self) -> Result<()> {
|
fn disable_base(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
Framable::delete(&self.framable)?;
|
self.framable.delete(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = &self.background {
|
if let Some(background) = &self.background {
|
||||||
background.disable()?;
|
background.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(foreground) = &self.foreground {
|
if let Some(foreground) = &self.foreground {
|
||||||
foreground.disable()?;
|
foreground.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.textable_wrapper.disable()?;
|
self.textable_wrapper.disable(gui_handler)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiElementTraits for ProgressBar {
|
impl<'a> GuiElementTraits<'a> for ProgressBar {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +272,7 @@ impl GuiElementTraits for ProgressBar {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::ProgressBar(self))
|
Some(GuiElement::ProgressBar(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,24 +282,24 @@ impl Visibility for ProgressBar {
|
||||||
self.visible.load(SeqCst)
|
self.visible.load(SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
if visibility != self.visible() {
|
if visibility != self.visible() {
|
||||||
self.visible.store(visibility, SeqCst);
|
self.visible.store(visibility, SeqCst);
|
||||||
|
|
||||||
if visibility {
|
if visibility {
|
||||||
Framable::add(&self.framable)?;
|
self.framable.add(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = &self.background {
|
if let Some(background) = &self.background {
|
||||||
background.enable()?;
|
background.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(foreground) = &self.foreground {
|
if let Some(foreground) = &self.foreground {
|
||||||
foreground.enable()?;
|
foreground.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.textable_wrapper.enable()?;
|
self.textable_wrapper.enable(gui_handler)?;
|
||||||
} else {
|
} else {
|
||||||
self.disable_base()?;
|
self.disable_base(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,9 +307,10 @@ impl Visibility for ProgressBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gridable for ProgressBar {
|
impl<'a> Gridable<'a> for ProgressBar {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -306,22 +318,23 @@ impl Gridable for ProgressBar {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.framable.set_frame(x, y, w, h, vert_align, hori_align);
|
self.framable
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align);
|
||||||
|
|
||||||
if let Some(background) = &self.background {
|
if let Some(background) = &self.background {
|
||||||
background.update_frame()?;
|
background.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(foreground) = &self.foreground {
|
if let Some(foreground) = &self.foreground {
|
||||||
foreground.update_frame()?;
|
foreground.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.textable_wrapper.update()?;
|
self.textable_wrapper.update(gui_handler)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,11 +361,3 @@ impl Gridable for ProgressBar {
|
||||||
self.framable.position()
|
self.framable.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ProgressBar {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible.load(SeqCst) {
|
|
||||||
self.disable_base().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ use anyhow::Result;
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering::SeqCst},
|
|
||||||
Arc, RwLock,
|
Arc, RwLock,
|
||||||
|
atomic::{AtomicBool, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::fill_type::{FillType, InnerFillType};
|
use super::fill_type::{FillType, InnerFillType};
|
||||||
|
@ -48,17 +48,18 @@ impl TextFieldBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, gui_handler: Arc<GuiHandler>) -> Result<Arc<TextField>> {
|
pub fn build(self, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<TextField>> {
|
||||||
let framable = Framable::new(gui_handler.clone(), false)?;
|
let framable = Framable::new(gui_handler.width(), gui_handler.height(), false)?;
|
||||||
|
|
||||||
let background = RwLock::new(
|
let background = RwLock::new(
|
||||||
self.background
|
self.background
|
||||||
.clone()
|
.clone()
|
||||||
.map(|info| FillType::new(framable.clone(), info))
|
.map(|info| FillType::new(gui_handler, framable.clone(), info))
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
);
|
);
|
||||||
|
|
||||||
let textable = Textable::new(
|
let textable = Textable::new(
|
||||||
|
gui_handler,
|
||||||
framable.clone(),
|
framable.clone(),
|
||||||
match self.text {
|
match self.text {
|
||||||
Some(text) => text,
|
Some(text) => text,
|
||||||
|
@ -69,13 +70,9 @@ impl TextFieldBuilder {
|
||||||
self.text_color,
|
self.text_color,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let text_changed_executable = Executable::new(&gui_handler);
|
let text_changed_executable = Executable::new();
|
||||||
|
|
||||||
let writeable = Writeable::new(
|
let writeable = Writeable::new(textable.clone(), text_changed_executable.clone())?;
|
||||||
gui_handler,
|
|
||||||
textable.clone(),
|
|
||||||
text_changed_executable.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let text_field = Arc::new(TextField {
|
let text_field = Arc::new(TextField {
|
||||||
framable,
|
framable,
|
||||||
|
@ -117,7 +114,7 @@ impl TextField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from(info: &TextFieldInfo, gui_handler: &Arc<GuiHandler>) -> Result<Arc<Self>> {
|
pub fn try_from(info: &TextFieldInfo, gui_handler: &mut GuiHandler<'_>) -> Result<Arc<Self>> {
|
||||||
let text = info.text.read().unwrap().clone();
|
let text = info.text.read().unwrap().clone();
|
||||||
let color = info.text_color;
|
let color = info.text_color;
|
||||||
|
|
||||||
|
@ -137,7 +134,7 @@ impl TextField {
|
||||||
text_field_builder = text_field_builder.set_text(text);
|
text_field_builder = text_field_builder.set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
text_field_builder.build(gui_handler.clone())
|
text_field_builder.build(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_color_change(self: &Arc<Self>) {
|
fn update_color_change(self: &Arc<Self>) {
|
||||||
|
@ -148,17 +145,18 @@ impl TextField {
|
||||||
|
|
||||||
let weak_self = Arc::downgrade(self);
|
let weak_self = Arc::downgrade(self);
|
||||||
|
|
||||||
self.writeable.set_activation_changed(move |active| {
|
self.writeable
|
||||||
|
.set_activation_changed(move |gui_handler, active| {
|
||||||
if let Some(me) = weak_self.upgrade() {
|
if let Some(me) = weak_self.upgrade() {
|
||||||
if active {
|
if active {
|
||||||
if let Some(background) = &*me.background.read().unwrap() {
|
if let Some(background) = &*me.background.read().unwrap() {
|
||||||
if let InnerFillType::Color(colorable) = &background.inner {
|
if let InnerFillType::Color(colorable) = &background.inner {
|
||||||
colorable.set_color(focus_color)?;
|
colorable.set_color(gui_handler, focus_color)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(background) = &*me.background.read().unwrap() {
|
} else if let Some(background) = &*me.background.read().unwrap() {
|
||||||
if let InnerFillType::Color(colorable) = &background.inner {
|
if let InnerFillType::Color(colorable) = &background.inner {
|
||||||
colorable.set_color(normal_color)?;
|
colorable.set_color(gui_handler, normal_color)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,26 +174,36 @@ impl TextField {
|
||||||
self.text_changed_executable.set_callback(f);
|
self.text_changed_executable.set_callback(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
|
pub fn set_text_color(
|
||||||
self.textable.set_text_color(text_color)
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_color: Color,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.textable.set_text_color(gui_handler, text_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||||
self.textable.set_text(text)
|
self.textable.set_text(gui_handler, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text(&self) -> Option<String> {
|
pub fn text(&self) -> Option<String> {
|
||||||
let t = self.textable.text();
|
let t = self.textable.text();
|
||||||
|
|
||||||
if t.is_empty() {
|
if t.is_empty() { None } else { Some(t) }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(t)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_background(self: &Arc<Self>, background: impl Into<FillTypeInfo>) -> Result<()> {
|
pub fn set_background(
|
||||||
super::set_background(self.visible(), &self.framable, &self.background, background)?;
|
self: &Arc<Self>,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
background: impl Into<FillTypeInfo>,
|
||||||
|
) -> Result<()> {
|
||||||
|
super::set_background(
|
||||||
|
gui_handler,
|
||||||
|
self.visible(),
|
||||||
|
&self.framable,
|
||||||
|
&self.background,
|
||||||
|
background,
|
||||||
|
)?;
|
||||||
|
|
||||||
self.update_color_change();
|
self.update_color_change();
|
||||||
|
|
||||||
|
@ -212,33 +220,33 @@ impl TextField {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_letter(&self, letter: char) -> Result<()> {
|
pub fn add_letter(&self, gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<()> {
|
||||||
self.writeable.add_letter(letter)
|
self.writeable.add_letter(gui_handler, letter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_last(&self) -> Result<()> {
|
pub fn remove_last(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.writeable.remove_last()
|
self.writeable.remove_last(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus_input(&self) -> Result<()> {
|
pub fn focus_input(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.writeable.set_active()
|
self.writeable.set_active(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_base(&self) -> Result<()> {
|
fn disable_base(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
self.framable.delete()?;
|
self.framable.delete(gui_handler)?;
|
||||||
self.textable.delete()?;
|
self.textable.delete(gui_handler)?;
|
||||||
self.writeable.delete()?;
|
self.writeable.delete(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.disable()?;
|
background.disable(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiElementTraits for TextField {
|
impl<'a> GuiElementTraits<'a> for TextField {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable> {
|
fn gridable(&self) -> Option<&dyn Gridable<'a>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,14 +254,15 @@ impl GuiElementTraits for TextField {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
|
fn downcast(&'a self) -> Option<GuiElement<'a>> {
|
||||||
Some(GuiElement::TextField(self))
|
Some(GuiElement::TextField(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gridable for TextField {
|
impl<'a> Gridable<'a> for TextField {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -261,18 +270,19 @@ impl Gridable for TextField {
|
||||||
vert_align: VerticalAlign,
|
vert_align: VerticalAlign,
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.framable.set_frame(x, y, w, h, vert_align, hori_align);
|
self.framable
|
||||||
|
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align);
|
||||||
|
|
||||||
self.textable.update_text()?;
|
self.textable.update_text(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.update_frame()?;
|
background.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>> {
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,33 +314,23 @@ impl Visibility for TextField {
|
||||||
self.visible.load(SeqCst)
|
self.visible.load(SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()> {
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()> {
|
||||||
if visibility != self.visible() {
|
if visibility != self.visible() {
|
||||||
self.visible.store(visibility, SeqCst);
|
self.visible.store(visibility, SeqCst);
|
||||||
|
|
||||||
if visibility {
|
if visibility {
|
||||||
self.framable.add()?;
|
self.framable.add(gui_handler)?;
|
||||||
self.textable.add()?;
|
self.textable.add(gui_handler)?;
|
||||||
self.writeable.add()?;
|
self.writeable.add(gui_handler)?;
|
||||||
|
|
||||||
if let Some(background) = self.background.read().unwrap().as_ref() {
|
if let Some(background) = self.background.read().unwrap().as_ref() {
|
||||||
background.enable()?;
|
background.enable(gui_handler)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.disable_base()?;
|
self.disable_base(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for TextField {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.visible() {
|
|
||||||
self.disable_base().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.textable.clear_callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ use anyhow::Result;
|
||||||
use std::{any::Any, collections::HashMap, sync::Arc};
|
use std::{any::Any, collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
// simulate trait upcasting
|
// simulate trait upcasting
|
||||||
pub trait TopLevelGui: Send + Sync {
|
pub trait TopLevelGui<'a>: Send + Sync {
|
||||||
fn gui_traits(&self) -> &dyn GuiElementTraits;
|
fn gui_traits(&self) -> &dyn GuiElementTraits<'a>;
|
||||||
fn top_gui(&self) -> Option<&dyn TopGui>;
|
fn top_gui(&self) -> Option<&dyn TopGui>;
|
||||||
fn elements(&self) -> Option<&HashMap<String, UiElement>>;
|
fn elements(&self) -> Option<&HashMap<String, UiElement<'a>>>;
|
||||||
fn functionality(&self) -> Option<&dyn Functionality>;
|
fn functionality(&self) -> Option<&dyn Functionality>;
|
||||||
fn enable(&self) -> Result<()>;
|
fn enable(&self) -> Result<()>;
|
||||||
fn disable(&self) -> Result<()>;
|
fn disable(&self) -> Result<()>;
|
||||||
|
@ -45,15 +45,16 @@ pub trait Functionality {
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GuiElementTraits: Send + Sync {
|
pub trait GuiElementTraits<'a>: Send + Sync {
|
||||||
fn gridable(&self) -> Option<&dyn Gridable>;
|
fn gridable(&self) -> Option<&dyn Gridable<'a>>;
|
||||||
fn visibility(&self) -> Option<&dyn Visibility>;
|
fn visibility(&self) -> Option<&dyn Visibility>;
|
||||||
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>>;
|
fn downcast(&'a self) -> Option<GuiElement<'a>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Gridable {
|
pub trait Gridable<'a> {
|
||||||
fn set_frame(
|
fn set_frame(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
w: u32,
|
w: u32,
|
||||||
|
@ -62,7 +63,7 @@ pub trait Gridable {
|
||||||
hori_align: HorizontalAlign,
|
hori_align: HorizontalAlign,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
fn selectable(&self) -> Option<&Arc<Selectable>>;
|
fn selectable(&self) -> Option<&Arc<Selectable<'a>>>;
|
||||||
|
|
||||||
fn type_name(&self) -> &str;
|
fn type_name(&self) -> &str;
|
||||||
|
|
||||||
|
@ -73,15 +74,15 @@ pub trait Gridable {
|
||||||
|
|
||||||
pub trait Visibility {
|
pub trait Visibility {
|
||||||
fn visible(&self) -> bool;
|
fn visible(&self) -> bool;
|
||||||
fn set_visibility(&self, visibility: bool) -> Result<()>;
|
fn set_visibility(&self, gui_handler: &mut GuiHandler<'_>, visibility: bool) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum GuiElement<'a> {
|
pub enum GuiElement<'a> {
|
||||||
Button(&'a Button),
|
Button(&'a Button<'a>),
|
||||||
Grid(&'a Grid),
|
Grid(&'a Grid<'a>),
|
||||||
Label(&'a Label),
|
Label(&'a Label),
|
||||||
MultiLineLabel(&'a MultiLineLabel),
|
MultiLineLabel(&'a MultiLineLabel<'a>),
|
||||||
MultiLineTextField(&'a MultiLineTextField),
|
MultiLineTextField(&'a MultiLineTextField<'a>),
|
||||||
TextField(&'a TextField),
|
TextField(&'a TextField),
|
||||||
Icon(&'a Icon),
|
Icon(&'a Icon),
|
||||||
ProgressBar(&'a ProgressBar),
|
ProgressBar(&'a ProgressBar),
|
||||||
|
@ -91,14 +92,14 @@ pub enum GuiElement<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GuiElement<'a> {
|
impl<'a> GuiElement<'a> {
|
||||||
pub fn button(&self) -> Option<&Button> {
|
pub fn button(&self) -> Option<&Button<'a>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Button(button) => Some(button),
|
Self::Button(button) => Some(button),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grid(&self) -> Option<&Grid> {
|
pub fn grid(&self) -> Option<&Grid<'a>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Grid(grid) => Some(grid),
|
Self::Grid(grid) => Some(grid),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -112,14 +113,14 @@ impl<'a> GuiElement<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multi_line_label(&self) -> Option<&MultiLineLabel> {
|
pub fn multi_line_label(&self) -> Option<&MultiLineLabel<'a>> {
|
||||||
match self {
|
match self {
|
||||||
Self::MultiLineLabel(multi_line_label) => Some(multi_line_label),
|
Self::MultiLineLabel(multi_line_label) => Some(multi_line_label),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multi_line_text_field(&self) -> Option<&MultiLineTextField> {
|
pub fn multi_line_text_field(&self) -> Option<&MultiLineTextField<'a>> {
|
||||||
match self {
|
match self {
|
||||||
Self::MultiLineTextField(multi_line_text_field) => Some(multi_line_text_field),
|
Self::MultiLineTextField(multi_line_text_field) => Some(multi_line_text_field),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
|
@ -5,19 +5,19 @@ use std::collections::HashMap;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
pub enum UiElement {
|
pub enum UiElement<'a> {
|
||||||
Button(Weak<Button>),
|
Button(Weak<Button<'a>>),
|
||||||
Grid(Weak<Grid>),
|
Grid(Weak<Grid<'a>>),
|
||||||
Label(Weak<Label>),
|
Label(Weak<Label>),
|
||||||
MultiLineLabel(Weak<MultiLineLabel>),
|
MultiLineLabel(Weak<MultiLineLabel<'a>>),
|
||||||
MultiLineTextField(Weak<MultiLineTextField>),
|
MultiLineTextField(Weak<MultiLineTextField<'a>>),
|
||||||
TextField(Weak<TextField>),
|
TextField(Weak<TextField>),
|
||||||
Icon(Weak<Icon>),
|
Icon(Weak<Icon>),
|
||||||
ProgressBar(Weak<ProgressBar>),
|
ProgressBar(Weak<ProgressBar>),
|
||||||
GuiSnippet(Weak<GuiSnippet>),
|
GuiSnippet(Weak<GuiSnippet>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for UiElement {
|
impl<'a> Debug for UiElement<'a> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
UiElement::Button(_) => write!(f, "Button"),
|
UiElement::Button(_) => write!(f, "Button"),
|
||||||
|
@ -35,7 +35,7 @@ impl Debug for UiElement {
|
||||||
|
|
||||||
macro_rules! impl_from {
|
macro_rules! impl_from {
|
||||||
($data_type:ident $(< $($lt:lifetime),+ >)? ) => {
|
($data_type:ident $(< $($lt:lifetime),+ >)? ) => {
|
||||||
impl From<&Arc<$data_type$(<$($lt,)+>)?>> for UiElement {
|
impl<'a> From<&Arc<$data_type$(<$($lt,)+>)?>> for UiElement<'a> {
|
||||||
fn from(v: &Arc<$data_type$(<$($lt,)+>)?>) -> Self {
|
fn from(v: &Arc<$data_type$(<$($lt,)+>)?>) -> Self {
|
||||||
UiElement::$data_type(Arc::downgrade(v))
|
UiElement::$data_type(Arc::downgrade(v))
|
||||||
}
|
}
|
||||||
|
@ -43,11 +43,11 @@ macro_rules! impl_from {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_from!(Button);
|
impl_from!(Button<'a>);
|
||||||
impl_from!(Grid);
|
impl_from!(Grid<'a>);
|
||||||
impl_from!(Label);
|
impl_from!(Label);
|
||||||
impl_from!(MultiLineLabel);
|
impl_from!(MultiLineLabel<'a>);
|
||||||
impl_from!(MultiLineTextField);
|
impl_from!(MultiLineTextField<'a>);
|
||||||
impl_from!(TextField);
|
impl_from!(TextField);
|
||||||
impl_from!(Icon);
|
impl_from!(Icon);
|
||||||
impl_from!(ProgressBar);
|
impl_from!(ProgressBar);
|
||||||
|
@ -59,7 +59,7 @@ pub trait GetElement<T> {
|
||||||
|
|
||||||
macro_rules! impl_element {
|
macro_rules! impl_element {
|
||||||
($data_type:ident $(< $($lt:lifetime),+ >)? ) => {
|
($data_type:ident $(< $($lt:lifetime),+ >)? ) => {
|
||||||
impl GetElement<$data_type$(<$($lt,)+>)?> for HashMap<String, UiElement> {
|
impl<'a> GetElement<$data_type$(<$($lt,)+>)?> for HashMap<String, UiElement<'a>> {
|
||||||
fn element(&self, id: &str) -> Result<Arc<$data_type$(<$($lt,)+>)?>> {
|
fn element(&self, id: &str) -> Result<Arc<$data_type$(<$($lt,)+>)?>> {
|
||||||
match self.get(id) {
|
match self.get(id) {
|
||||||
Some(element) => match element {
|
Some(element) => match element {
|
||||||
|
@ -83,11 +83,11 @@ macro_rules! impl_element {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_element!(Button);
|
impl_element!(Button<'a>);
|
||||||
impl_element!(Grid);
|
impl_element!(Grid<'a>);
|
||||||
impl_element!(Label);
|
impl_element!(Label);
|
||||||
impl_element!(MultiLineLabel);
|
impl_element!(MultiLineLabel<'a>);
|
||||||
impl_element!(MultiLineTextField);
|
impl_element!(MultiLineTextField<'a>);
|
||||||
impl_element!(TextField);
|
impl_element!(TextField);
|
||||||
impl_element!(Icon);
|
impl_element!(Icon);
|
||||||
impl_element!(ProgressBar);
|
impl_element!(ProgressBar);
|
||||||
|
|
|
@ -4,8 +4,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicU32, Ordering::SeqCst},
|
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
|
atomic::{AtomicU32, Ordering::SeqCst},
|
||||||
};
|
};
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
@ -48,17 +48,26 @@ impl TextableWrapper {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_text_color(&self, text_color: Color) -> Result<()> {
|
pub(crate) fn set_text_color(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text_color: Color,
|
||||||
|
) -> Result<()> {
|
||||||
*self.color.lock().unwrap() = text_color;
|
*self.color.lock().unwrap() = text_color;
|
||||||
|
|
||||||
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
||||||
textable.set_text_color(text_color)?;
|
textable.set_text_color(gui_handler, text_color)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_text(&self, text: impl ToString, is_visible: bool) -> Result<()> {
|
pub(crate) fn set_text(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
text: impl ToString,
|
||||||
|
is_visible: bool,
|
||||||
|
) -> Result<()> {
|
||||||
let text = text.to_string();
|
let text = text.to_string();
|
||||||
let mut textable = self.textable.lock().unwrap();
|
let mut textable = self.textable.lock().unwrap();
|
||||||
|
|
||||||
|
@ -68,17 +77,18 @@ impl TextableWrapper {
|
||||||
current_textable.clear_callback();
|
current_textable.clear_callback();
|
||||||
|
|
||||||
if is_visible {
|
if is_visible {
|
||||||
current_textable.delete()?;
|
current_textable.delete(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
*textable = None;
|
*textable = None;
|
||||||
} else {
|
} else {
|
||||||
current_textable.set_text(text)?;
|
current_textable.set_text(gui_handler, text)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if !text.is_empty() {
|
if !text.is_empty() {
|
||||||
let new_textable = Textable::new(
|
let new_textable = Textable::new(
|
||||||
|
gui_handler,
|
||||||
self.framable.clone(),
|
self.framable.clone(),
|
||||||
text,
|
text,
|
||||||
*self.ratio.lock().unwrap(),
|
*self.ratio.lock().unwrap(),
|
||||||
|
@ -87,13 +97,13 @@ impl TextableWrapper {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if self.framable.is_framed() {
|
if self.framable.is_framed() {
|
||||||
new_textable.update_text()?;
|
new_textable.update_text(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_textable.set_ui_layer(self.framable.ui_layer());
|
new_textable.set_ui_layer(self.framable.ui_layer());
|
||||||
|
|
||||||
if is_visible {
|
if is_visible {
|
||||||
new_textable.add()?;
|
new_textable.add(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
*textable = Some(new_textable);
|
*textable = Some(new_textable);
|
||||||
|
@ -113,11 +123,15 @@ impl TextableWrapper {
|
||||||
.map(|textable| textable.text()))
|
.map(|textable| textable.text()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_height_ratio(&self, height_ratio: f32) -> Result<()> {
|
pub(crate) fn set_height_ratio(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
height_ratio: f32,
|
||||||
|
) -> Result<()> {
|
||||||
*self.ratio.lock().unwrap() = height_ratio;
|
*self.ratio.lock().unwrap() = height_ratio;
|
||||||
|
|
||||||
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
||||||
textable.set_size(height_ratio)?;
|
textable.set_size(gui_handler, height_ratio)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -127,35 +141,39 @@ impl TextableWrapper {
|
||||||
*self.ratio.lock().unwrap()
|
*self.ratio.lock().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_alignment(&self, alignment: TextAlignment) -> Result<()> {
|
pub(crate) fn set_alignment(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
alignment: TextAlignment,
|
||||||
|
) -> Result<()> {
|
||||||
*self.alignment.lock().unwrap() = alignment;
|
*self.alignment.lock().unwrap() = alignment;
|
||||||
|
|
||||||
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
||||||
textable.set_text_alignment(alignment)?;
|
textable.set_text_alignment(gui_handler, alignment)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update(&self) -> Result<()> {
|
pub(crate) fn update(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
||||||
textable.update_text()?;
|
textable.update_text(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enable(&self) -> Result<()> {
|
pub(crate) fn enable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
||||||
textable.add()?;
|
textable.add(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn disable(&self) -> Result<()> {
|
pub(crate) fn disable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
||||||
textable.delete()?;
|
textable.delete(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -180,13 +198,15 @@ pub(crate) struct IconizableWrapper {
|
||||||
|
|
||||||
impl IconizableWrapper {
|
impl IconizableWrapper {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
framable: Arc<Framable>,
|
framable: Arc<Framable>,
|
||||||
builder: Option<IconBuilderType>,
|
builder: Option<IconBuilderType>,
|
||||||
positioning: Option<IconizablePositioning>,
|
positioning: Option<IconizablePositioning>,
|
||||||
margin: u32,
|
margin: u32,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let iconizable: Option<Result<Arc<Iconizable>>> = builder.map(|content| {
|
let iconizable: Option<Result<Arc<Iconizable>>> = builder.map(|content| {
|
||||||
let iconizable = Iconizable::new(framable.clone(), content, positioning.clone())?;
|
let iconizable =
|
||||||
|
Iconizable::new(gui_handler, framable.clone(), content, positioning.clone())?;
|
||||||
|
|
||||||
iconizable.set_margin(margin)?;
|
iconizable.set_margin(margin)?;
|
||||||
|
|
||||||
|
@ -214,12 +234,16 @@ impl IconizableWrapper {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clear_icon(&self, is_visible: bool) -> Result<()> {
|
pub(crate) fn clear_icon(
|
||||||
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
|
is_visible: bool,
|
||||||
|
) -> Result<()> {
|
||||||
let mut iconizable = self.iconizable.lock().unwrap();
|
let mut iconizable = self.iconizable.lock().unwrap();
|
||||||
|
|
||||||
if let Some(iconizable) = iconizable.as_ref() {
|
if let Some(iconizable) = iconizable.as_ref() {
|
||||||
if is_visible {
|
if is_visible {
|
||||||
iconizable.delete()?;
|
iconizable.delete(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
iconizable.clear_callback();
|
iconizable.clear_callback();
|
||||||
|
@ -232,15 +256,17 @@ impl IconizableWrapper {
|
||||||
|
|
||||||
pub(crate) fn set_icon(
|
pub(crate) fn set_icon(
|
||||||
&self,
|
&self,
|
||||||
|
gui_handler: &mut GuiHandler<'_>,
|
||||||
icon_builder: impl Into<IconBuilderType>,
|
icon_builder: impl Into<IconBuilderType>,
|
||||||
is_visible: bool,
|
is_visible: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut iconizable = self.iconizable.lock().unwrap();
|
let mut iconizable = self.iconizable.lock().unwrap();
|
||||||
|
|
||||||
match iconizable.as_ref() {
|
match iconizable.as_ref() {
|
||||||
Some(iconizable) => iconizable.set_icon(icon_builder)?,
|
Some(iconizable) => iconizable.set_icon(gui_handler, icon_builder)?,
|
||||||
None => {
|
None => {
|
||||||
let new_iconizable = Iconizable::new(
|
let new_iconizable = Iconizable::new(
|
||||||
|
gui_handler,
|
||||||
self.framable.clone(),
|
self.framable.clone(),
|
||||||
icon_builder,
|
icon_builder,
|
||||||
self.positioning.clone(),
|
self.positioning.clone(),
|
||||||
|
@ -249,13 +275,13 @@ impl IconizableWrapper {
|
||||||
new_iconizable.set_margin(self.margin.load(SeqCst))?;
|
new_iconizable.set_margin(self.margin.load(SeqCst))?;
|
||||||
|
|
||||||
if self.framable.is_framed() {
|
if self.framable.is_framed() {
|
||||||
new_iconizable.update_frame()?;
|
new_iconizable.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_iconizable.set_ui_layer(self.framable.ui_layer());
|
new_iconizable.set_ui_layer(self.framable.ui_layer());
|
||||||
|
|
||||||
if is_visible {
|
if is_visible {
|
||||||
new_iconizable.add()?;
|
new_iconizable.add(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
*iconizable = Some(new_iconizable);
|
*iconizable = Some(new_iconizable);
|
||||||
|
@ -265,11 +291,11 @@ impl IconizableWrapper {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_margin(&self, margin: u32) -> Result<()> {
|
pub(crate) fn set_margin(&self, gui_handler: &mut GuiHandler<'_>, margin: u32) -> Result<()> {
|
||||||
if self.framable.is_framed() {
|
if self.framable.is_framed() {
|
||||||
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
||||||
iconizable.set_margin(margin)?;
|
iconizable.set_margin(margin)?;
|
||||||
iconizable.update_frame()?;
|
iconizable.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,25 +311,25 @@ impl IconizableWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enable(&self) -> Result<()> {
|
pub(crate) fn enable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
||||||
iconizable.add()?;
|
iconizable.add(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn disable(&self) -> Result<()> {
|
pub(crate) fn disable(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
||||||
iconizable.delete()?;
|
iconizable.delete(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_frame(&self) -> Result<()> {
|
pub(crate) fn update_frame(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||||
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
||||||
iconizable.update_frame()?;
|
iconizable.update_frame(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -3,19 +3,19 @@ use std::{slice::Iter, sync::Arc};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Elements {
|
pub struct Elements<'a> {
|
||||||
framables: Vec<Arc<Framable>>,
|
framables: Vec<Arc<Framable>>,
|
||||||
hoverables: Vec<Arc<Hoverable>>,
|
hoverables: Vec<Arc<Hoverable>>,
|
||||||
clickables: Vec<Arc<Clickable>>,
|
clickables: Vec<Arc<Clickable>>,
|
||||||
displayables: Vec<Arc<Displayable>>,
|
displayables: Vec<Arc<Displayable>>,
|
||||||
selectables: Vec<Arc<Selectable>>,
|
selectables: Vec<Arc<Selectable<'a>>>,
|
||||||
textables: Vec<Arc<Textable>>,
|
textables: Vec<Arc<Textable>>,
|
||||||
writeables: Vec<Arc<Writeable>>,
|
writeables: Vec<Arc<Writeable>>,
|
||||||
iconizables: Vec<Arc<Iconizable>>,
|
iconizables: Vec<Arc<Iconizable>>,
|
||||||
colorables: Vec<Arc<Colorable>>,
|
colorables: Vec<Arc<Colorable>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Elements {
|
impl<'a> Elements<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push_element<T>(vector: &mut Vec<Arc<T>>, element: Arc<T>) {
|
fn push_element<T>(vector: &mut Vec<Arc<T>>, element: Arc<T>) {
|
||||||
if cfg!(debug_assertions) && vector.iter().any(|e| Arc::ptr_eq(e, &element)) {
|
if cfg!(debug_assertions) && vector.iter().any(|e| Arc::ptr_eq(e, &element)) {
|
||||||
|
@ -75,11 +75,11 @@ impl Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
// selectable
|
// selectable
|
||||||
pub fn add_selectable(&mut self, selectable: Arc<Selectable>) {
|
pub fn add_selectable(&mut self, selectable: Arc<Selectable<'a>>) {
|
||||||
Self::push_element(&mut self.selectables, selectable);
|
Self::push_element(&mut self.selectables, selectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_selectable(&mut self, selectable: &Arc<Selectable>) -> bool {
|
pub fn delete_selectable(&mut self, selectable: &Arc<Selectable<'a>>) -> bool {
|
||||||
Self::erase_element(&mut self.selectables, selectable)
|
Self::erase_element(&mut self.selectables, selectable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ pub struct Clickable {
|
||||||
ui_layer: AtomicI32,
|
ui_layer: AtomicI32,
|
||||||
|
|
||||||
executable: Arc<Executable<()>>,
|
executable: Arc<Executable<()>>,
|
||||||
clicked_changed_callback: RwLock<Option<Box<dyn Fn() -> Result<()> + Send + Sync>>>,
|
clicked_changed_callback:
|
||||||
|
RwLock<Option<Box<dyn Fn(&mut GuiHandler<'_>) -> Result<()> + Send + Sync>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clickable {
|
impl Clickable {
|
||||||
|
@ -89,7 +90,9 @@ impl Clickable {
|
||||||
/// * `clicked_changed_callback` is a `Option<Box<Callback>>`
|
/// * `clicked_changed_callback` is a `Option<Box<Callback>>`
|
||||||
pub fn set_clicked_changed_callback(
|
pub fn set_clicked_changed_callback(
|
||||||
&self,
|
&self,
|
||||||
clicked_changed_callback: Option<Box<dyn Fn() -> Result<()> + Send + Sync>>,
|
clicked_changed_callback: Option<
|
||||||
|
Box<dyn Fn(&mut GuiHandler<'_>) -> Result<()> + Send + Sync>,
|
||||||
|
>,
|
||||||
) {
|
) {
|
||||||
*self.clicked_changed_callback.write().unwrap() = clicked_changed_callback;
|
*self.clicked_changed_callback.write().unwrap() = clicked_changed_callback;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +109,7 @@ impl Clickable {
|
||||||
if let Some(clicked_changed_callback) =
|
if let Some(clicked_changed_callback) =
|
||||||
self.clicked_changed_callback.read().unwrap().as_ref()
|
self.clicked_changed_callback.read().unwrap().as_ref()
|
||||||
{
|
{
|
||||||
clicked_changed_callback()?;
|
clicked_changed_callback(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.clicked() {
|
if self.clicked() {
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl Colorable {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `color` defines the color
|
/// * `color` defines the color
|
||||||
pub fn set_color(&self, color: Color, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
pub fn set_color(&self, gui_handler: &mut GuiHandler<'_>, color: Color) -> Result<()> {
|
||||||
let set = gui_handler.color_descriptor(color)?;
|
let set = gui_handler.color_descriptor(color)?;
|
||||||
|
|
||||||
*self.color.write().unwrap() = color;
|
*self.color.write().unwrap() = color;
|
||||||
|
|
|
@ -19,7 +19,8 @@ pub struct Writeable {
|
||||||
modifyable: Arc<dyn ModifyText>,
|
modifyable: Arc<dyn ModifyText>,
|
||||||
text_change_executable: Arc<Executable<Option<String>>>,
|
text_change_executable: Arc<Executable<Option<String>>>,
|
||||||
|
|
||||||
activation_changed_executable: RwLock<Option<Box<dyn Fn(bool) -> Result<()> + Send + Sync>>>,
|
activation_changed_executable:
|
||||||
|
RwLock<Option<Box<dyn Fn(&mut GuiHandler<'_>, bool) -> Result<()> + Send + Sync>>>,
|
||||||
|
|
||||||
ui_layer: AtomicI32,
|
ui_layer: AtomicI32,
|
||||||
}
|
}
|
||||||
|
@ -60,7 +61,7 @@ impl Writeable {
|
||||||
|
|
||||||
pub fn set_activation_changed<F>(&self, f: F)
|
pub fn set_activation_changed<F>(&self, f: F)
|
||||||
where
|
where
|
||||||
F: Fn(bool) -> Result<()> + Send + Sync + 'static,
|
F: Fn(&mut GuiHandler<'_>, bool) -> Result<()> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
*self.activation_changed_executable.write().unwrap() = Some(Box::new(f));
|
*self.activation_changed_executable.write().unwrap() = Some(Box::new(f));
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,7 +229,7 @@ pub struct GuiHandler<'a> {
|
||||||
hover_sound: Option<AssetPath>,
|
hover_sound: Option<AssetPath>,
|
||||||
|
|
||||||
// ----- gui handling -----
|
// ----- gui handling -----
|
||||||
layers: Vec<(i32, Elements)>,
|
layers: Vec<(i32, Elements<'a>)>,
|
||||||
|
|
||||||
mouse_x: u32,
|
mouse_x: u32,
|
||||||
mouse_y: u32,
|
mouse_y: u32,
|
||||||
|
@ -1087,7 +1087,7 @@ impl<'a> GuiHandler<'a> {
|
||||||
pub(crate) fn add_selectable(
|
pub(crate) fn add_selectable(
|
||||||
&mut self,
|
&mut self,
|
||||||
layer: i32,
|
layer: i32,
|
||||||
selectable: Arc<Selectable<'_>>,
|
selectable: Arc<Selectable<'a>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
add_element!(self.layers, layer, selectable);
|
add_element!(self.layers, layer, selectable);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub struct Keyboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Keyboard {
|
impl Keyboard {
|
||||||
pub fn new(gui_handler: &Arc<GuiHandler<'a>>) -> Result<Arc<Self>> {
|
pub fn new(gui_handler: &GuiHandler<'a>) -> Result<Arc<Self>> {
|
||||||
let text_field_gui: Arc<GuiBuilder> =
|
let text_field_gui: Arc<GuiBuilder> =
|
||||||
GuiBuilder::from_str(gui_handler, include_str!("text_field.xml"))?;
|
GuiBuilder::from_str(gui_handler, include_str!("text_field.xml"))?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue