Browse Source

Finish Frame implementation.

Kestrel 4 months ago
parent
commit
7f638e7456
5 changed files with 72 additions and 24 deletions
  1. 20 6
      examples/table_layout.rs
  2. 2 6
      src/layout/arr/table.rs
  3. 14 0
      src/widget.rs
  4. 34 10
      src/widget/frame.rs
  5. 2 2
      src/window.rs

+ 20 - 6
examples/table_layout.rs

@@ -14,12 +14,26 @@ impl TableWindow {
         let mut group = widget::PlainGroup::new_table(uih);
         group.extend(
             vec![
-                Box::new(
-                    widget::Label::new_with_text(uih, "r1c1").with_table_cell(TableCell::new(0, 0)),
-                ) as Box<dyn Widget<Self>>,
-                Box::new(
-                    widget::Label::new_with_text(uih, "r2c1").with_table_cell(TableCell::new(0, 1)),
-                ),
+                widget::Label::new_with_text(uih, "r1c1")
+                    .framed()
+                    .with_table_cell(TableCell::new(0, 0))
+                    .boxed(),
+                widget::Label::new_with_text(uih, "r2c1")
+                    .framed()
+                    .with_table_cell(TableCell::new(0, 1))
+                    .boxed(),
+                widget::Label::new_with_text(uih, "r2c2")
+                    .framed()
+                    .with_table_cell(TableCell::new(1, 1))
+                    .boxed(),
+                widget::Label::new_with_text(uih, "r2c2")
+                    .framed()
+                    .with_table_cell(TableCell::new(1, 2))
+                    .boxed(),
+                widget::Label::new_with_text(uih, "r3c2")
+                    .framed()
+                    .with_table_cell(TableCell::new(3, 2))
+                    .boxed(),
             ]
             .into_iter(),
         );

+ 2 - 6
src/layout/arr/table.rs

@@ -42,14 +42,10 @@ impl TableArrangement {
             };
 
             if cell.x >= tstate.col_policies.len() {
-                tstate
-                    .col_policies
-                    .resize(cell.x + 1, SizePolicy::default());
+                tstate.col_policies.resize(cell.x + 1, SizePolicy::zero());
             }
             if cell.y >= tstate.row_policies.len() {
-                tstate
-                    .row_policies
-                    .resize(cell.y + 1, SizePolicy::default());
+                tstate.row_policies.resize(cell.y + 1, SizePolicy::zero());
             }
 
             let child_policy = node

+ 14 - 0
src/widget.rs

@@ -27,6 +27,20 @@ pub trait Widget<C: Component> {
 }
 
 pub trait WidgetExt<C: Component>: Widget<C> {
+    fn boxed(self) -> Box<dyn Widget<C>>
+    where
+        Self: 'static + Sized,
+    {
+        Box::new(self)
+    }
+
+    fn framed(self) -> Frame<C>
+    where
+        Self: 'static + Sized,
+    {
+        Frame::wrap_widget(self)
+    }
+
     fn clear_table_cell(&mut self) {
         self.layout_node_mut().set_table_cell(None);
     }

+ 34 - 10
src/widget/frame.rs

@@ -13,7 +13,6 @@ use super::Widget;
 pub struct Frame<C: Component> {
     layout: LayoutNode,
     child: Option<Box<dyn Widget<C>>>,
-    _ghost: std::marker::PhantomData<C>,
 }
 
 impl<C: Component> Frame<C> {
@@ -25,7 +24,23 @@ impl<C: Component> Frame<C> {
         Self {
             layout: nnode,
             child: None,
-            _ghost: Default::default(),
+        }
+    }
+
+    pub fn new_with_child(uih: &UIHandle, child: Box<dyn Widget<C>>) -> Self {
+        let mut fr = Self::new(uih);
+        fr.set_child(child);
+        fr
+    }
+
+    pub fn wrap_widget<W: 'static + Widget<C>>(child: W) -> Self {
+        let mut nnode = LayoutNode::new(child.layout_node().cache().clone());
+        nnode
+            .set_height_policy(SizePolicy::expanding(1))
+            .set_width_policy(SizePolicy::expanding(1));
+        Self {
+            layout: nnode,
+            child: Some(Box::new(child)),
         }
     }
 
@@ -58,10 +73,14 @@ impl<C: Component> LayoutNodeContainer for Frame<C> {
 impl<C: Component> Widget<C> for Frame<C> {
     fn poll(
         &mut self,
-        _uih: &mut UIHandle,
-        _input_state: Option<&crate::input::InputState>,
+        uih: &mut UIHandle,
+        input_state: Option<&crate::input::InputState>,
     ) -> Vec<C::Msg> {
-        vec![]
+        if let Some(child) = self.child.as_mut() {
+            child.poll(uih, input_state)
+        } else {
+            vec![]
+        }
     }
     fn layout_node(&self) -> LayoutNodeAccess {
         LayoutNodeAccess::new(self)
@@ -72,10 +91,15 @@ impl<C: Component> Widget<C> for Frame<C> {
     fn render(&self, theme: &Theme, target: &mut kahlo::BitmapMut<RenderFormat>) {
         let area = self.layout.render_area().unwrap();
 
-        target.fill_region(area, theme.border);
-        target.fill_region(
-            area.inner_box(PixelSideOffsets::new_all_same(theme.border_width as i32)),
-            theme.panel,
-        );
+        if self.layout.render_check() {
+            target.rectangle(area, theme.border_width, theme.border);
+            target.fill_region(
+                area.inner_box(PixelSideOffsets::new_all_same(theme.border_width as i32)),
+                theme.panel,
+            );
+        }
+        if let Some(child) = self.child.as_ref() {
+            child.render(theme, target);
+        }
     }
 }

+ 2 - 2
src/window.rs

@@ -116,7 +116,7 @@ impl<WC: WindowComponent> WindowState<WC> {
         // now put the pre-render layout dump on the window
         // again, we're doing this the dumb way
         let mut offset = 0;
-        for text in pre_render_dump.split('\n') {
+        /*for text in pre_render_dump.split('\n') {
             if text.is_empty() {
                 continue;
             }
@@ -131,7 +131,7 @@ impl<WC: WindowComponent> WindowState<WC> {
             );
 
             offset += line.height() as i32 + 1;
-        }
+        }*/
 
         buf.present().unwrap();
     }