diff --git a/scripts/build-ohos-example-arm64.sh b/scripts/build-ohos-example-arm64.sh new file mode 100755 index 0000000..c863dbc --- /dev/null +++ b/scripts/build-ohos-example-arm64.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +export LLVM_BIN_PATH=$OHOS_SDK_HOME/native/llvm/bin +export LIBCLANG_PATH=$OHOS_SDK_HOME/native/llvm/lib +export PATH=$LLVM_BIN_PATH:$PATH + +export CLANG_PATH=$LLVM_BIN_PATH/clang++ +export CXXSTDLIB_AARCH64_UNKNOWN_LINUX_OHOS=c++ + +export TARGET_CC=$LLVM_BIN_PATH/clang +export TARGET_CXX=$LLVM_BIN_PATH/clang++ +export TARGET_AR=$LLVM_BIN_PATH/llvm-ar +export TARGET_OBJDUMP=$LLVM_BIN_PATH/llvm-objdump +export TARGET_OBJCOPY=$LLVM_BIN_PATH/llvm-objcopy +export TARGET_NM=$LLVM_BIN_PATH/llvm-nm +export TARGET_AS=$LLVM_BIN_PATH/llvm-as +export TARGET_LD=$LLVM_BIN_PATH/ld.lld +export TARGET_RANLIB=$LLVM_BIN_PATH/llvm-ranlib +export TARGET_STRIP=$LLVM_BIN_PATH/llvm-strip + +export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_OHOS_LINKER=$TARGET_CC +export CARGO_ENCODED_RUSTFLAGS="-Clink-args=--target=aarch64-linux-ohos --sysroot=$OHOS_SDK_HOME/native/sysroot -D__MUSL__" + +cargo build --target aarch64-unknown-linux-ohos --release --example mobile_demo diff --git a/src/element/common/editable.rs b/src/element/common/editable.rs index cf1b44e..01ea70e 100644 --- a/src/element/common/editable.rs +++ b/src/element/common/editable.rs @@ -5,11 +5,7 @@ use crate::canvas_util::CanvasHelper; use crate::element::edit_history::{EditHistory, EditOpType}; use crate::element::util::is_form_event; use crate::element::{Element, ElementBackend, ElementWeak}; -use crate::event::{ - BlurEvent, BoundsChangeEvent, CaretChangeEvent, Event, FocusEvent, KeyDownEvent, - KeyEventDetail, MouseDownEvent, MouseLeaveEvent, ScrollEvent, TextChangeEvent, TextInputEvent, - TextUpdateEvent, KEY_MOD_CTRL, KEY_MOD_SHIFT, -}; +use crate::event::{BlurEvent, BoundsChangeEvent, CaretChangeEvent, Event, FocusEvent, KeyDownEvent, KeyEventDetail, MouseDownEvent, MouseLeaveEvent, PreeditEvent, ScrollEvent, TextChangeEvent, TextInputEvent, TextUpdateEvent, KEY_MOD_CTRL, KEY_MOD_SHIFT}; use crate::event_loop::create_event_loop_proxy; use crate::js::{FromJsValue, ToJsValue}; use crate::number::DeNan; @@ -632,6 +628,25 @@ impl Editable { } } else if let Some(e) = KeyDownEvent::cast(event) { self.handle_key_down(&e.0); + } else if let Some(e) = PreeditEvent::cast(event) { + self.handle_input(&e.content); + if !e.content.is_empty() { + let end_caret = self.paragraph.get_caret(); + let content_chars_count = e.content.chars_count() as isize; + if let Some(start_caret) = self.paragraph.calculate_caret(-content_chars_count) { + self.paragraph.select(start_caret, end_caret); + if let Some(offset) = e.offset { + let char_offset = if offset == 0 { + 0 + } else { + e.content[0..offset].chars_count() + } as isize; + if char_offset < content_chars_count { + self.paragraph.move_caret( char_offset - content_chars_count) + } + } + } + } } false } diff --git a/src/event.rs b/src/event.rs index caa0583..4a172fd 100644 --- a/src/event.rs +++ b/src/event.rs @@ -720,6 +720,12 @@ pub fn named_key_to_str(key: &NamedKey) -> &'static str { #[event] pub struct TextInputEvent(pub String); +#[event] +pub struct PreeditEvent { + pub content: String, + pub offset: Option, +} + #[event] pub struct ClickEvent(pub MouseDetail); diff --git a/src/text/textbox.rs b/src/text/textbox.rs index c1e39ff..e78ab96 100644 --- a/src/text/textbox.rs +++ b/src/text/textbox.rs @@ -555,13 +555,18 @@ impl TextBox { } } - pub fn move_caret(&mut self, mut delta: isize) { + pub fn move_caret(&mut self, delta: isize) { + if let Some(caret) = self.calculate_caret(delta) { + self.update_caret_value(caret, false); + } + } + pub fn calculate_caret(&self, mut delta: isize) -> Option { let mut row = self.caret.0; let mut col = self.caret.1 as isize; loop { let lines = self.get_lines(); let line = match lines.get(row) { - None => return, + None => return None, Some(ln) => ln, }; let atom_count = line.atom_count() as isize; @@ -573,7 +578,7 @@ impl TextBox { continue; } else if col < 0 { if row == 0 { - return; + return None; } delta += -col; row -= 1; @@ -582,8 +587,7 @@ impl TextBox { continue; } else { let new_caret = (row, col as usize); - self.update_caret_value(TextCoord::new(new_caret), false); - break; + return Some(TextCoord::new(new_caret)); } } } diff --git a/src/window.rs b/src/window.rs index 298c784..5153b60 100644 --- a/src/window.rs +++ b/src/window.rs @@ -13,14 +13,7 @@ use crate::element::body::Body; use crate::element::util::get_tree_level; use crate::element::{Element, ElementBackend, ElementParent}; use crate::error::{DeftError, DeftResult}; -use crate::event::{ - build_modifier, named_key_to_str, str_to_named_key, BlurEvent, ClickEvent, ClickEventListener, - ContextMenuEvent, DragOverEvent, DragStartEvent, DropEvent, DroppedFileEvent, FocusEvent, - FocusShiftEvent, HoveredFileEvent, KeyDownEvent, KeyEventDetail, KeyUpEvent, MouseDownEvent, - MouseEnterEvent, MouseLeaveEvent, MouseMoveEvent, MouseUpEvent, MouseWheelEvent, - TextInputEvent, TouchCancelEvent, TouchEndEvent, TouchMoveEvent, TouchStartEvent, KEY_MOD_ALT, - KEY_MOD_CTRL, KEY_MOD_META, KEY_MOD_SHIFT, -}; +use crate::event::{build_modifier, named_key_to_str, str_to_named_key, BlurEvent, ClickEvent, ClickEventListener, ContextMenuEvent, DragOverEvent, DragStartEvent, DropEvent, DroppedFileEvent, FocusEvent, FocusShiftEvent, HoveredFileEvent, KeyDownEvent, KeyEventDetail, KeyUpEvent, MouseDownEvent, MouseEnterEvent, MouseLeaveEvent, MouseMoveEvent, MouseUpEvent, MouseWheelEvent, PreeditEvent, TextInputEvent, TouchCancelEvent, TouchEndEvent, TouchMoveEvent, TouchStartEvent, KEY_MOD_ALT, KEY_MOD_CTRL, KEY_MOD_META, KEY_MOD_SHIFT}; use crate::event_loop::run_with_event_loop; use crate::ext::ext_window::{ WindowAttrs, MODAL_TO_OWNERS, WINDOWS, WINDOW_TYPE_MENU, WINDOW_TYPE_NORMAL, WINIT_TO_WINDOW, @@ -297,6 +290,11 @@ impl Window { height: attrs.height.unwrap_or(default_height) as f64, }; attributes.inner_size = Some(Size::Logical(size)); + } else { + attributes.inner_size = Some(Size::Logical(LogicalSize { + width: 1.0, + height: 1.0, + })) } #[cfg(x11_platform)] { @@ -614,6 +612,15 @@ impl Window { } } + pub fn handle_ime_preedit(&mut self, content: String, offset: Option) { + if let Some(focusing) = &self.focusing { + focusing.emit(PreeditEvent{ + content, + offset, + }); + } + } + pub fn handle_key( &mut self, modifiers: u32, @@ -659,7 +666,9 @@ impl Window { WindowEvent::ModifiersChanged(new_modifiers) => self.modifiers = new_modifiers, WindowEvent::Ime(ime) => match ime { Ime::Enabled => {} - Ime::Preedit(_, _) => {} + Ime::Preedit(content, offset) => { + self.handle_ime_preedit(content, offset.map(|v| v.0)); + } Ime::Commit(str) => { self.handle_input(&str); } @@ -707,7 +716,7 @@ impl Window { ); } WindowEvent::MouseInput { button, state, .. } => { - // debug!("mouse:{:?}:{:?}", button, state); + self.window.commit_ime(); if let Some((dir, _)) = self.get_resize_direction() { if let Err(e) = self.window.drag_resize_window(dir) { error!("Failed to drag resize window: {:?}", e); @@ -1785,9 +1794,10 @@ impl Window { impl Drop for Window { fn drop(&mut self) { - WIN_STATE_MANAGER.with_borrow_mut(|wsm| { + let _ = WIN_STATE_MANAGER.try_with(|wsm| { + let mut wsm = wsm.borrow_mut(); wsm.remove_state(&self.handle.state); - }) + }); } }