From ea4d66451118614607fe237df5a9156a1aa13b8b Mon Sep 17 00:00:00 2001 From: Ryan McGrath Date: Wed, 20 Jun 2018 19:18:38 -0400 Subject: [PATCH] Slight refactoring --- examples/layout/Cargo.toml | 2 +- examples/layout/src/styles/default.json | 3 + src/{text.rs => label.rs} | 47 +++++---- src/view.rs | 130 +++++++++++++----------- 4 files changed, 100 insertions(+), 82 deletions(-) rename src/{text.rs => label.rs} (58%) diff --git a/examples/layout/Cargo.toml b/examples/layout/Cargo.toml index f4a4600..3d171b5 100644 --- a/examples/layout/Cargo.toml +++ b/examples/layout/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "layout" +name = "shinekit-layout-example" version = "0.1.0" authors = ["Ryan McGrath "] diff --git a/examples/layout/src/styles/default.json b/examples/layout/src/styles/default.json index 7a93b4c..d6cf6b6 100644 --- a/examples/layout/src/styles/default.json +++ b/examples/layout/src/styles/default.json @@ -12,6 +12,7 @@ "sidebar": { "backgroundColor": {"r": 5, "g": 5, "b": 5}, "width": 200, + "height": 400, "top": "root.top", "left": "root.left", "bottom": "root.bottom" @@ -19,6 +20,8 @@ "content": { "backgroundColor": {"r": 35, "g": 108, "b": 218}, + "width": 100, + "height": 300, "top": "root.top", "left": "sidebar.right", "right": "root.right", diff --git a/src/text.rs b/src/label.rs similarity index 58% rename from src/text.rs rename to src/label.rs index 603aaf0..e2d2bce 100644 --- a/src/text.rs +++ b/src/label.rs @@ -17,10 +17,29 @@ use cocoa::foundation::NSString; use shinekit::color::Color; use shinekit::util::empty_frame; -use shinekit::layout::{Layout, add_autolayout_ivars}; -pub struct Text { - pub backing_node: Id +pub struct Label; + +impl Label { + pub fn named(name: &str) -> Self { + View::named_of_kind_with_backing_node(name, ViewKind::Label, unsafe { + let alloc: id = msg_send![register_text_class(), alloc]; + let view: id = msg_send![alloc, initWithFrame:empty_frame()]; + msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO]; + msg_send![view, setEditable:NO]; + msg_send![view, setBezeled:NO]; + msg_send![view, setBordered:NO]; + msg_send![view, setDrawsBackground:YES]; + msg_send![view, setAllowsEditingTextAttributes:NO]; + msg_send![view, setContentCompressionResistancePriority:250 forOrientation:0]; + + let cell: id = msg_send![view, cell]; + msg_send![cell, setUsesSingleLineMode:NO]; + msg_send![cell, setWraps:YES]; + msg_send![cell, setLineBreakMode:0]; + Id::from_ptr(view) + }) + } } #[allow(dead_code)] @@ -28,21 +47,6 @@ impl Text { pub fn new() -> Self { Text { backing_node: unsafe { - let alloc: id = msg_send![register_text_class(), alloc]; - let view: id = msg_send![alloc, initWithFrame:empty_frame()]; - msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO]; - msg_send![view, setEditable:NO]; - msg_send![view, setBezeled:NO]; - msg_send![view, setBordered:NO]; - msg_send![view, setDrawsBackground:YES]; - msg_send![view, setAllowsEditingTextAttributes:NO]; - msg_send![view, setContentCompressionResistancePriority:250 forOrientation:0]; - - let cell: id = msg_send![view, cell]; - msg_send![cell, setUsesSingleLineMode:NO]; - msg_send![cell, setWraps:YES]; - msg_send![cell, setLineBreakMode:0]; - Id::from_ptr(view) } } } @@ -68,18 +72,13 @@ impl Text { } } -impl Layout for Text { - fn get_root_backing_node(&self) -> &Object { &*self.backing_node } - fn set_constraint_ivar(&mut self, ivar: &str, constraint: id) { unsafe { self.backing_node.set_ivar(ivar, constraint); } } -} - fn register_text_class() -> *const Class { static mut text_class: *const Class = 0 as *const Class; static INIT: Once = ONCE_INIT; INIT.call_once(|| unsafe { let superclass = Class::get("NSTextField").unwrap(); - let mut decl = ClassDecl::new("shinekitTextLabel", superclass).unwrap(); + let mut decl = ClassDecl::new("ShineKitLabel", superclass).unwrap(); //decl.add_method(sel!(wantsUpdateLayer), enforce_normalcy as extern fn(&Object, _) -> BOOL); //decl.add_method(sel!(updateLayer), update_layer as extern fn(&Object, _)); add_autolayout_ivars(&mut decl); diff --git a/src/view.rs b/src/view.rs index 6d2d2ea..a806695 100644 --- a/src/view.rs +++ b/src/view.rs @@ -33,38 +33,35 @@ pub struct View { pub subviews: Vec } -unsafe fn create_view_backing_node() -> Id { - let alloc: id = msg_send![register_view_class(), alloc]; - let view: id = msg_send![alloc, initWithFrame:empty_frame()]; - msg_send![view, setWantsLayer:YES]; - msg_send![view, setLayerContentsRedrawPolicy:1]; - msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO]; - Id::from_ptr(view) -} - impl View { - pub fn named(name: &str) -> Self { + pub fn named_of_kind_with_backing_node(name: &str, kind: ViewKind, backing_node: Id) -> Self { View { name: name.into(), - kind: ViewKind::View, - backing_node: unsafe { create_view_backing_node() }, + kind: kind, + backing_node: backing_node, subviews: vec![] } } + pub fn named(name: &str) -> Self { + View::named_of_kind_with_backing_node(name, ViewKind::View, unsafe { + let alloc: id = msg_send![register_view_class(), alloc]; + let view: id = msg_send![alloc, initWithFrame:empty_frame()]; + msg_send![view, setWantsLayer:YES]; + msg_send![view, setLayerContentsRedrawPolicy:1]; + msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO]; + Id::from_ptr(view) + }) + } + pub fn subviews(self, views: Vec) -> Self { let mut subviews = vec![]; - unsafe { - for view in views.into_iter() { - msg_send![&*self.backing_node, addSubview:&*view.backing_node]; - subviews.push(view); - } + for view in views.into_iter() { + unsafe { msg_send![&*self.backing_node, addSubview:&*view.backing_node]; } + subviews.push(view); } - View { - subviews: subviews, - ..self - } + View { subviews: subviews, ..self } } pub fn set_background_color(&mut self, color: &Color) { @@ -73,19 +70,14 @@ impl View { msg_send![&*self.backing_node, setNeedsDisplay:YES]; } } - - pub fn apply_styles(&mut self, styles: &mut Map) { - let bg_color = Color::from_json(&styles[&self.name]["backgroundColor"]); - self.set_background_color(&bg_color); - - for view in &mut self.subviews { - view.apply_styles(styles); - } - } pub fn get_root_backing_node(&self) -> &Object { &*self.backing_node } pub fn get_subviews(&self) -> &Vec { &self.subviews } - pub fn set_constraint_ivar(&mut self, ivar: &str, constraint: id) { unsafe { self.backing_node.set_ivar(ivar, constraint); } } + pub fn set_ivar(&mut self, ivar: &str, constraint: id) { + unsafe { + self.backing_node.set_ivar(ivar, constraint); + } + } pub fn add_subview(&self, view: &View) { unsafe { @@ -100,19 +92,19 @@ impl View { } } - pub fn width(&mut self, width: i32) { + pub fn set_width(&mut self, width: f64) { unsafe { let anchor: id = msg_send![self.get_root_backing_node(), widthAnchor]; - let constraint: id = msg_send![anchor, constraintEqualToConstant:width as f64]; - self.set_constraint_ivar("shinekitConstraintWidth", constraint); + let constraint: id = msg_send![anchor, constraintEqualToConstant:width]; + self.set_ivar("shinekitConstraintWidth", constraint); } } - pub fn height(&mut self, height: i32) { + pub fn set_height(&mut self, height: f64) { unsafe { let anchor: id = msg_send![self.get_root_backing_node(), heightAnchor]; - let constraint: id = msg_send![anchor, constraintEqualToConstant:height as f64]; - self.set_constraint_ivar("shinekitConstraintHeight", constraint); + let constraint: id = msg_send![anchor, constraintEqualToConstant:height]; + self.set_ivar("shinekitConstraintHeight", constraint); } } @@ -121,7 +113,7 @@ impl View { let top_anchor: id = msg_send![self.get_root_backing_node(), topAnchor]; let view_top_anchor: id = msg_send![view.get_root_backing_node(), topAnchor]; let constraint: id = msg_send![top_anchor, constraintEqualToAnchor:view_top_anchor constant:margin as f64]; - self.set_constraint_ivar("shinekitConstraintTop", constraint); + self.set_ivar("shinekitConstraintTop", constraint); } } @@ -130,7 +122,7 @@ impl View { let leading_anchor: id = msg_send![self.get_root_backing_node(), leadingAnchor]; let view_leading_anchor: id = msg_send![view.get_root_backing_node(), leadingAnchor]; let constraint: id = msg_send![leading_anchor, constraintEqualToAnchor:view_leading_anchor constant:margin as f64]; - self.set_constraint_ivar("shinekitConstraintLeading", constraint); + self.set_ivar("shinekitConstraintLeading", constraint); } } @@ -140,7 +132,7 @@ impl View { let trailing_anchor: id = msg_send![self.get_root_backing_node(), trailingAnchor]; let view_trailing_anchor: id = msg_send![view.get_root_backing_node(), trailingAnchor]; let constraint: id = msg_send![trailing_anchor, constraintEqualToAnchor:view_trailing_anchor constant:m]; - self.set_constraint_ivar("shinekitConstraintTrailing", constraint); + self.set_ivar("shinekitConstraintTrailing", constraint); } } @@ -150,28 +142,52 @@ impl View { let bottom_anchor: id = msg_send![self.get_root_backing_node(), bottomAnchor]; let view_bottom_anchor: id = msg_send![view.get_root_backing_node(), bottomAnchor]; let constraint: id = msg_send![bottom_anchor, constraintEqualToAnchor:view_bottom_anchor constant:m]; - self.set_constraint_ivar("shinekitConstraintBottom", constraint); + self.set_ivar("shinekitConstraintBottom", constraint); } } pub fn activate_constraints(&self) { - unsafe { - let mut anchors: Vec = vec![]; - - let ivars = [ - "shinekitConstraintWidth", "shinekitConstraintHeight", - "shinekitConstraintTop", "shinekitConstraintLeading", - "shinekitConstraintTrailing", "shinekitConstraintBottom" - ]; - - let view = self.get_root_backing_node(); - for ivar in &ivars { - let constraint: id = *view.get_ivar(ivar); - if constraint != nil { anchors.push(constraint); } + let mut constraints: Vec = vec![]; + + let ivars = [ + "shinekitConstraintWidth", "shinekitConstraintHeight", + "shinekitConstraintTop", "shinekitConstraintLeading", + "shinekitConstraintTrailing", "shinekitConstraintBottom" + ]; + + for ivar in &ivars { + let constraint: id; + unsafe { constraint = *self.backing_node.get_ivar(ivar); } + + if constraint != nil { + constraints.push(constraint); } - - let constraints = NSArray::arrayWithObjects(nil, &anchors); - msg_send![class("NSLayoutConstraint"), activateConstraints:constraints]; + } + + if constraints.len() > 0 { + unsafe { + let bundle = NSArray::arrayWithObjects(nil, &constraints); + msg_send![class("NSLayoutConstraint"), activateConstraints:bundle]; + } + } + } + + pub fn apply_styles(&mut self, styles: &mut Map) { + let bg_color = Color::from_json(&styles[&self.name]["backgroundColor"]); + self.set_background_color(&bg_color); + + match styles[&self.name]["width"].as_f64() { + Some(width) => self.set_width(width), + None => () + } + + match styles[&self.name]["height"].as_f64() { + Some(width) => self.set_width(width), + None => () + } + + for view in &mut self.subviews { + view.apply_styles(styles); } } }