Skip to content

Commit

Permalink
Bring back image support after react renderer parsing rework
Browse files Browse the repository at this point in the history
  • Loading branch information
Exidex committed Nov 10, 2024
1 parent 579e296 commit e132fe1
Show file tree
Hide file tree
Showing 9 changed files with 382 additions and 68 deletions.
15 changes: 12 additions & 3 deletions rust/client/src/ui/client_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,19 @@ impl ClientContext {
self.view.get_entrypoint_id()
}

pub fn replace_view(&mut self, render_location: UiRenderLocation, container: RootWidget, plugin_id: &PluginId, plugin_name: &str, entrypoint_id: &EntrypointId, entrypoint_name: &str) {
pub fn replace_view(
&mut self,
render_location: UiRenderLocation,
container: RootWidget,
images: HashMap<UiWidgetId, bytes::Bytes>,
plugin_id: &PluginId,
plugin_name: &str,
entrypoint_id: &EntrypointId,
entrypoint_name: &str
) {
match render_location {
UiRenderLocation::InlineView => self.get_mut_inline_view_container(plugin_id).replace_view(container, plugin_id, plugin_name, entrypoint_id, entrypoint_name),
UiRenderLocation::View => self.get_mut_view_container().replace_view(container, plugin_id, plugin_name, entrypoint_id, entrypoint_name)
UiRenderLocation::InlineView => self.get_mut_inline_view_container(plugin_id).replace_view(container, images, plugin_id, plugin_name, entrypoint_id, entrypoint_name),
UiRenderLocation::View => self.get_mut_view_container().replace_view(container, images, plugin_id, plugin_name, entrypoint_id, entrypoint_name)
}
}

Expand Down
4 changes: 3 additions & 1 deletion rust/client/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2007,13 +2007,15 @@ async fn request_loop(
entrypoint_name,
render_location,
top_level_view,
container
container,
images
} => {
let has_children = container.content.is_some();

client_context.replace_view(
render_location,
container,
images,
&plugin_id,
&plugin_name,
&entrypoint_id,
Expand Down
71 changes: 41 additions & 30 deletions rust/client/src/ui/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use iced::alignment::{Horizontal, Vertical};
use iced::font::Weight;
use iced::widget::text::Shaping;
use iced::widget::tooltip::Position;
use iced::widget::{button, checkbox, column, container, horizontal_rule, horizontal_space, mouse_area, pick_list, row, scrollable, text, text_input, tooltip, vertical_rule, Space};
use iced::widget::{button, checkbox, column, container, horizontal_rule, horizontal_space, image, mouse_area, pick_list, row, scrollable, text, text_input, tooltip, vertical_rule, Space};
use iced::{Alignment, Font, Length};
use iced::widget::image::Handle;
use iced_aw::core::icons;
use iced_aw::date_picker::Date;
use iced_aw::floating_element::Offset;
Expand Down Expand Up @@ -38,14 +39,20 @@ use crate::ui::AppMsg;
#[derive(Debug)]
pub struct ComponentWidgets<'b> {
root_widget: &'b mut Option<RootWidget>,
state: &'b mut HashMap<UiWidgetId, ComponentWidgetState>
state: &'b mut HashMap<UiWidgetId, ComponentWidgetState>,
images: &'b HashMap<UiWidgetId, bytes::Bytes>
}

impl<'b> ComponentWidgets<'b> {
pub fn new(root_widget: &'b mut Option<RootWidget>, state: &'b mut HashMap<UiWidgetId, ComponentWidgetState>) -> ComponentWidgets<'b> {
pub fn new(
root_widget: &'b mut Option<RootWidget>,
state: &'b mut HashMap<UiWidgetId, ComponentWidgetState>,
images: &'b HashMap<UiWidgetId, bytes::Bytes>
) -> ComponentWidgets<'b> {
Self {
root_widget,
state
state,
images
}
}

Expand Down Expand Up @@ -653,7 +660,7 @@ impl<'b> ComponentWidgets<'b> {

fn render_image_widget<'a>(&self, widget: &ImageWidget, centered: bool) -> Element<'a, ComponentWidgetEvent> {
// TODO image size, height and width
let content: Element<_> = render_image(&widget.source, None);
let content: Element<_> = self.render_image(widget.__id__, &widget.source, None);

let mut content = container(content)
.width(Length::Fill);
Expand Down Expand Up @@ -1066,7 +1073,7 @@ impl<'b> ComponentWidgets<'b> {
fn render_empty_view_widget<'a>(&self, widget: &EmptyViewWidget) -> Element<'a, ComponentWidgetEvent> {
let image: Option<Element<_>> = widget.image
.as_ref()
.map(|image| render_image(image, Some(TextStyle::EmptyViewSubtitle)));
.map(|image| self.render_image(widget.__id__, image, Some(TextStyle::EmptyViewSubtitle)));

let title: Element<_> = text(&widget.title)
.shaping(Shaping::Advanced)
Expand Down Expand Up @@ -1112,7 +1119,7 @@ impl<'b> ComponentWidgets<'b> {
}

fn render_icon_accessory<'a>(&self, widget: &IconAccessoryWidget) -> Element<'a, ComponentWidgetEvent> {
let icon = render_image(&widget.icon, Some(TextStyle::IconAccessory));
let icon = self.render_image(widget.__id__, &widget.icon, Some(TextStyle::IconAccessory));

let content = container(icon)
.center_x()
Expand All @@ -1135,7 +1142,7 @@ impl<'b> ComponentWidgets<'b> {
fn render_text_accessory<'a>(&self, widget: &TextAccessoryWidget) -> Element<'a, ComponentWidgetEvent> {
let icon: Option<Element<_>> = widget.icon
.as_ref()
.map(|icon| render_image(icon, Some(TextStyle::TextAccessory)));
.map(|icon| self.render_image(widget.__id__, icon, Some(TextStyle::TextAccessory)));

let text_content: Element<_> = text(&widget.text)
.shaping(Shaping::Advanced)
Expand Down Expand Up @@ -1302,7 +1309,7 @@ impl<'b> ComponentWidgets<'b> {
fn render_list_item_widget<'a>(&self, widget: &ListItemWidget) -> Element<'a, ComponentWidgetEvent> {
let icon: Option<Element<_>> = widget.icon
.as_ref()
.map(|icon| render_image(icon, None));
.map(|icon| self.render_image(widget.__id__, icon, None));

let title: Element<_> = text(&widget.title)
.shaping(Shaping::Advanced)
Expand Down Expand Up @@ -1640,29 +1647,33 @@ impl<'b> ComponentWidgets<'b> {
}
}
}
}

fn render_image<'a>(image: &Image, icon_style: Option<TextStyle>) -> Element<'a, ComponentWidgetEvent> {
match image {
Image::ImageSource(source) => {
// TODO image support
// image(Handle::from_memory(bytes.clone()))
// .into()

horizontal_space()
.into()
}
Image::Icons(icon) => {
match icon_style {
None => {
text(icon_to_bootstrap(icon))
.font(icons::BOOTSTRAP_FONT)
.into()
fn render_image<'a>(&self, widget_id: UiWidgetId, image_data: &Image, icon_style: Option<TextStyle>) -> Element<'a, ComponentWidgetEvent> {
match image_data {
Image::ImageSource(_) => {
match self.images.get(&widget_id) {
Some(bytes) => {
image(Handle::from_memory(bytes.clone()))
.into()
}
None => {
horizontal_space()
.into()
}
}
Some(icon_style) => {
text(icon_to_bootstrap(icon))
.font(icons::BOOTSTRAP_FONT)
.themed(icon_style)
}
Image::Icons(icon) => {
match icon_style {
None => {
text(icon_to_bootstrap(icon))
.font(icons::BOOTSTRAP_FONT)
.into()
}
Some(icon_style) => {
text(icon_to_bootstrap(icon))
.font(icons::BOOTSTRAP_FONT)
.themed(icon_style)
}
}
}
}
Expand Down
29 changes: 20 additions & 9 deletions rust/client/src/ui/widget_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
pub struct PluginWidgetContainer {
root_widget: Arc<Mutex<Option<RootWidget>>>,
state: Arc<Mutex<HashMap<UiWidgetId, ComponentWidgetState>>>,
images: HashMap<UiWidgetId, bytes::Bytes>,
plugin_id: Option<PluginId>,
plugin_name: Option<String>,
entrypoint_id: Option<EntrypointId>,
Expand All @@ -23,6 +24,7 @@ impl PluginWidgetContainer {
Self {
root_widget: Arc::new(Mutex::new(None)),
state: Arc::new(Mutex::new(HashMap::new())),
images: HashMap::new(),
plugin_id: None,
plugin_name: None,
entrypoint_id: None,
Expand All @@ -38,13 +40,22 @@ impl PluginWidgetContainer {
self.entrypoint_id.clone().expect("entrypoint id should always exist after render")
}

pub fn replace_view(&mut self, container: RootWidget, plugin_id: &PluginId, plugin_name: &str, entrypoint_id: &EntrypointId, entrypoint_name: &str) {
pub fn replace_view(
&mut self,
container: RootWidget,
images: HashMap<UiWidgetId, bytes::Bytes>,
plugin_id: &PluginId,
plugin_name: &str,
entrypoint_id: &EntrypointId,
entrypoint_name: &str
) {
tracing::trace!("replace_view is called. container: {:?}", container);

self.plugin_id = Some(plugin_id.clone());
self.plugin_name = Some(plugin_name.to_string());
self.entrypoint_id = Some(entrypoint_id.clone());
self.entrypoint_name = Some(entrypoint_name.to_string());
self.images = images;

let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");
Expand Down Expand Up @@ -81,57 +92,57 @@ impl PluginWidgetContainer {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state)
ComponentWidgets::new(&mut root_widget, &mut state, &self.images)
.render_root_widget(plugin_view_state, self.entrypoint_name.as_ref(), action_shortcuts)
}

pub fn render_inline_root_widget<'a>(&self) -> Element<'a, ComponentWidgetEvent> {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state)
ComponentWidgets::new(&mut root_widget, &mut state, &self.images)
.render_root_inline_widget(self.plugin_name.as_ref(), self.entrypoint_name.as_ref())
}

pub fn toggle_action_panel(&self) {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state).toggle_action_panel()
ComponentWidgets::new(&mut root_widget, &mut state, &self.images).toggle_action_panel()
}

pub fn get_action_ids(&self) -> Vec<UiWidgetId> {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state).get_action_ids()
ComponentWidgets::new(&mut root_widget, &mut state, &self.images).get_action_ids()
}

pub fn get_action_panel(&self, action_shortcuts: &HashMap<String, PhysicalShortcut>) -> Option<ActionPanel> {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state).get_action_panel(action_shortcuts)
ComponentWidgets::new(&mut root_widget, &mut state, &self.images).get_action_panel(action_shortcuts)
}

pub fn keyboard_navigation_width(&self) -> Option<usize> {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state).keyboard_navigation_width()
ComponentWidgets::new(&mut root_widget, &mut state, &self.images).keyboard_navigation_width()
}

pub fn keyboard_navigation_total(&self) -> usize {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state).keyboard_navigation_total()
ComponentWidgets::new(&mut root_widget, &mut state, &self.images).keyboard_navigation_total()
}

pub fn has_search_bar(&self) -> bool {
let mut root_widget = self.root_widget.lock().expect("lock is poisoned");
let mut state = self.state.lock().expect("lock is poisoned");

ComponentWidgets::new(&mut root_widget, &mut state).has_search_bar()
ComponentWidgets::new(&mut root_widget, &mut state, &self.images).has_search_bar()
}
}
Loading

0 comments on commit e132fe1

Please sign in to comment.