Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add nest dom manager and implement the basic example #15

Merged
merged 1 commit into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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