Skip to content

Commit

Permalink
feat: add nest dom manager and implement the basic example
Browse files Browse the repository at this point in the history
  • Loading branch information
richerfu committed Nov 7, 2024
1 parent 3733bb8 commit e93fd3a
Show file tree
Hide file tree
Showing 17 changed files with 364 additions and 55 deletions.
2 changes: 2 additions & 0 deletions crates/arkui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ napi-sys-ohos = { workspace = true }
napi-ohos = { workspace = true }
enum_macro = { workspace = true }
thiserror = { workspace = true }

ohos-hilog-binding = {workspace = true}
28 changes: 26 additions & 2 deletions crates/arkui/src/common/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ pub enum ArkUIError {
/// This type is used for ArkUI result.
pub type ArkUIResult = Result<(), ArkUIError>;

#[doc(hidden)]
#[macro_export]
macro_rules! check_arkui_status {
() => {};
}
($code:expr) => {{
let c = $code;
match c {
$crate::sys::Status::napi_ok => Ok(()),
_ => Err($crate::Error::new($crate::Status::from(c), "".to_owned())),
}
}};

($code:expr, $($msg:tt)*) => {{
let c = $code;
match c {
$crate::sys::Status::napi_ok => Ok(()),
_ => Err($crate::Error::new($crate::Status::from(c), format!($($msg)*))),
}
}};

($code:expr, $msg:expr, $env:expr, $val:expr) => {{
let c = $code;
match c {
$crate::sys::Status::napi_ok => Ok(()),
_ => Err($crate::Error::new($crate::Status::from(c), format!($msg, $crate::type_of!($env, $val)?))),
}
}};
}
50 changes: 50 additions & 0 deletions crates/arkui/src/common/native_node_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,54 @@ impl ArkUINativeNodeAPI1 {
}
}
}

pub fn add_child(&self, parent: &ArkUINode, child: &ArkUINode) -> Result<()> {
unsafe {
if let Some(add_child) = (*self.0).addChild {
add_child(parent.raw(), child.raw());
Ok(())
} else {
Err(Error::from_reason(
"ArkUI_NativeNodeAPI_1::addChild is None",
))
}
}
}

pub fn remove_child(&self, parent: &ArkUINode, child: &ArkUINode) -> Result<()> {
unsafe {
if let Some(remove_child) = (*self.0).removeChild {
remove_child(parent.raw(), child.raw());
Ok(())
} else {
Err(Error::from_reason(
"ArkUI_NativeNodeAPI_1::removeChild is None",
))
}
}
}

pub fn insert_child(&self, parent: &ArkUINode, child: &ArkUINode, index: i32) -> Result<()> {
unsafe {
if let Some(insert_child_at) = (*self.0).insertChildAt {
insert_child_at(parent.raw(), child.raw(), index);
Ok(())
} else {
Err(Error::from_reason(
"ArkUI_NativeNodeAPI_1::insertChild is None",
))
}
}
}

pub fn dispose(&self, node: &ArkUINode) -> Result<()> {
unsafe {
if let Some(dispose_node) = (*self.0).disposeNode {
dispose_node(node.raw());
Ok(())
} else {
Err(Error::from_reason("ArkUI_NativeNodeAPI_1::dispose is None"))
}
}
}
}
25 changes: 11 additions & 14 deletions crates/arkui/src/common/node.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use napi_ohos::bindgen_prelude::{check_status, FromNapiValue, TypeName, ValidateNapiValue};
use napi_sys_ohos as sys;
use ohos_arkui_sys::{ArkUI_NodeHandle, OH_ArkUI_GetNodeHandleFromNapiValue};
use ohos_hilog_binding::hilog_info;
use std::ptr;

use crate::ArkUINodeType;

use super::ARK_UI_NATIVE_NODE_API_1;

#[derive(Clone)]
pub struct ArkUINode {
pub(crate) raw: ArkUI_NodeHandle,
Expand All @@ -25,20 +28,14 @@ impl ArkUINode {
self.raw
}

pub fn remove_child(&mut self, index: usize) -> Option<Box<ArkUINode>> {
if index < self.children().len() {
Some(self.children_mut().remove(index))
} else {
None
}
}

pub fn add_child(&mut self, child: Box<ArkUINode>) {
self.children_mut().push(child);
}

pub fn insert_child(&mut self, child: Box<ArkUINode>, index: usize) {
self.children_mut().insert(index, child);
/// Clear dom
/// We can't use drop impl, because it will be called when the object is dropped.
pub fn dispose(&mut self) {
ARK_UI_NATIVE_NODE_API_1.dispose(self);
self.children.iter_mut().for_each(|child| {
child.dispose();
});
self.children.clear();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,36 @@ use crate::{
ArkUINode, ArkUINodeAttributeItem, ArkUINodeAttributeNumber, ARK_UI_NATIVE_NODE_API_1,
};

/// This trait is used to set common attribute for node.
/// Every node should implement this trait, include the custom node.
pub trait ArkUICommonAttribute {
pub trait ArkUIAttributeBasic {
/// Make sure every node can get ArkUINode for built-in method with current trait
fn raw(&self) -> &ArkUINode;

fn borrow_mut(&mut self) -> &mut ArkUINode;
}

/// This trait is used to set common attribute for node.
/// Every node should implement this trait, include the custom node.
pub trait ArkUICommonAttribute: ArkUIAttributeBasic {
/// Set node height
fn set_width(&self, width: f32) -> Result<()> {
let width_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(width)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
self.raw(),
crate::ArkUINodeAttributeType::Width,
width_property,
)?;
Ok(())
}

/// Set node height
fn set_height(&self, height: f32) -> Result<()> {
let percent_width_property =
let height_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(height)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
self.raw(),
crate::ArkUINodeAttributeType::Height,
percent_width_property,
height_property,
)?;
Ok(())
}
Expand Down Expand Up @@ -57,4 +73,32 @@ pub trait ArkUICommonAttribute {
)?;
Ok(())
}

/// Remove child node
fn remove_child(&mut self, index: usize) -> Option<Box<ArkUINode>> {
let mut children = self.borrow_mut();
if index < children.children().len() {
let removed_node = children.children_mut().remove(index);
ARK_UI_NATIVE_NODE_API_1.remove_child(self.raw(), &removed_node);
Some(removed_node)
} else {
None
}
}

fn add_child<T: Into<ArkUINode>>(&mut self, child: T) {
let child_handle = child.into();
ARK_UI_NATIVE_NODE_API_1.add_child(self.raw(), &child_handle);
self.borrow_mut()
.children_mut()
.push(Box::new(child_handle));
}

fn insert_child<T: Into<ArkUINode>>(&mut self, child: T, index: usize) {
let child_handle = child.into();
ARK_UI_NATIVE_NODE_API_1.insert_child(self.raw(), &child_handle, index as i32);
self.borrow_mut()
.children_mut()
.insert(index, Box::new(child_handle));
}
}
29 changes: 29 additions & 0 deletions crates/arkui/src/component/attribute/font.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use napi_ohos::Result;

use crate::{ArkUINodeAttributeItem, ArkUINodeAttributeNumber, ARK_UI_NATIVE_NODE_API_1};

use super::ArkUIAttributeBasic;

pub trait ArkUICommonFontAttribute: ArkUIAttributeBasic {
fn set_font_size(&self, font_size: f32) -> Result<()> {
let font_size_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Float(font_size)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
self.raw(),
crate::ArkUINodeAttributeType::FontSize,
font_size_property,
)?;
Ok(())
}

fn set_font_color(&self, font_color: u32) -> Result<()> {
let font_color_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Uint(font_color)]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
self.raw(),
crate::ArkUINodeAttributeType::FontColor,
font_color_property,
)?;
Ok(())
}
}
5 changes: 5 additions & 0 deletions crates/arkui/src/component/attribute/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod common;
mod font;

pub use common::*;
pub use font::*;
48 changes: 48 additions & 0 deletions crates/arkui/src/component/built_in_component/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use napi_ohos::Result;

use crate::{
ArkUIAttributeBasic, ArkUICommonAttribute, ArkUINode, ArkUINodeAttributeItem,
ArkUINodeAttributeNumber, ArkUINodeType, ScrollBarDisplayMode, ARK_UI_NATIVE_NODE_API_1,
};

pub struct List(ArkUINode);

impl List {
pub fn new() -> Result<Self> {
let list = ARK_UI_NATIVE_NODE_API_1.create_node(ArkUINodeType::List)?;
Ok(Self(ArkUINode {
raw: list,
children: Vec::new(),
tag: ArkUINodeType::List,
}))
}

pub fn set_scroll_bar_state(&mut self, mode: ScrollBarDisplayMode) -> Result<()> {
let scroll_bar_display_mode_property =
ArkUINodeAttributeItem::NumberValue(vec![ArkUINodeAttributeNumber::Int(mode.into())]);
ARK_UI_NATIVE_NODE_API_1.set_attribute(
&self.0,
crate::ArkUINodeAttributeType::ScrollBarDisplayMode,
scroll_bar_display_mode_property,
)?;
Ok(())
}
}

impl From<List> for ArkUINode {
fn from(list: List) -> Self {
list.0
}
}

impl ArkUIAttributeBasic for List {
fn raw(&self) -> &ArkUINode {
&self.0
}

fn borrow_mut(&mut self) -> &mut ArkUINode {
&mut self.0
}
}

impl ArkUICommonAttribute for List {}
36 changes: 36 additions & 0 deletions crates/arkui/src/component/built_in_component/list_item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use napi_ohos::Result;

use crate::{
ArkUIAttributeBasic, ArkUICommonAttribute, ArkUINode, ArkUINodeType, ARK_UI_NATIVE_NODE_API_1,
};

pub struct ListItem(ArkUINode);

impl ListItem {
pub fn new() -> Result<Self> {
let list_item = ARK_UI_NATIVE_NODE_API_1.create_node(ArkUINodeType::ListItem)?;
Ok(Self(ArkUINode {
raw: list_item,
children: Vec::new(),
tag: ArkUINodeType::ListItem,
}))
}
}

impl From<ListItem> for ArkUINode {
fn from(list_item: ListItem) -> Self {
list_item.0
}
}

impl ArkUIAttributeBasic for ListItem {
fn raw(&self) -> &ArkUINode {
&self.0
}

fn borrow_mut(&mut self) -> &mut ArkUINode {
&mut self.0
}
}

impl ArkUICommonAttribute for ListItem {}
4 changes: 4 additions & 0 deletions crates/arkui/src/component/built_in_component/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
mod list;
mod list_item;
mod text;

pub use list::*;
pub use list_item::*;
pub use text::*;
Loading

0 comments on commit e93fd3a

Please sign in to comment.