Skip to content
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
6 changes: 5 additions & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ edition = "2021"

[dependencies]
tipc = { path = "../tipc/" }
tmui = { path = "../tmui/", features = ["font_awesome", "win_popup"] }
tmui = { path = "../tmui/", features = [
"font_awesome",
"win_tooltip",
"win_dialog",
] }

widestring = "1.0.2"
log = "0.4"
Expand Down
49 changes: 49 additions & 0 deletions examples/border/border_with_child.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use log::info;
use tmui::{
prelude::*,
tlib::object::{ObjectImpl, ObjectSubclass},
widget::WidgetImpl,
};

#[extends(Widget, Layout(HBox))]
#[derive(Childrenable)]
pub struct BorderWithChild {
#[children]
widget_left: Tr<Widget>,
#[children]
widget_right: Tr<Widget>,
}

impl ObjectSubclass for BorderWithChild {
const NAME: &'static str = "BorderWithChild";
}

impl ObjectImpl for BorderWithChild {
fn initialize(&mut self) {
self.set_background(Color::GREY_LIGHT);
self.set_halign(Align::Center);
self.enable_bubble(EventBubble::MOUSE_MOVE);

self.set_margin_top(5);
self.set_border_radius(6.);

self.widget_left.width_request(25);
self.widget_left.height_request(25);

self.widget_right.width_request(25);
self.widget_right.height_request(25);
self.widget_right.set_mouse_tracking(true);
}
}

impl WidgetImpl for BorderWithChild {
fn on_mouse_enter(&mut self, _: &MouseEvent) {
info!("Mouse entered.");
self.set_background(Color::GREY_MEDIUM);
}

fn on_mouse_leave(&mut self, _: &MouseEvent) {
info!("Mouse leaved.");
self.set_background(Color::GREY_LIGHT);
}
}
13 changes: 12 additions & 1 deletion examples/border/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
pub mod border_with_child;

use border_with_child::BorderWithChild;
use tmui::{application::Application, application_window::ApplicationWindow, prelude::*};

fn main() {
Expand All @@ -15,6 +18,8 @@ fn main() {
}

fn build_ui(window: &mut ApplicationWindow) {
let mut vbox = VBox::new();

let mut hbox = HBox::new();
let mut widget1 = Widget::new_alloc();
let mut widget2 = Widget::new_alloc();
Expand Down Expand Up @@ -47,5 +52,11 @@ fn build_ui(window: &mut ApplicationWindow) {
hbox.height_request(400);
hbox.set_background(Color::RED);

window.child(hbox);
vbox.set_halign(Align::Center);
vbox.set_valign(Align::Center);
vbox.add_child(hbox);
vbox.set_content_halign(Align::Center);
vbox.add_child(BorderWithChild::new_alloc());

window.child(vbox);
}
8 changes: 7 additions & 1 deletion examples/child_window/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use tlib::figure::OptionSize;
use tmui::{
application::Application,
application_window::ApplicationWindow,
graphics::styles::Styles,
label::Label,
prelude::*,
tooltip::Tooltip,
Expand Down Expand Up @@ -48,6 +49,11 @@ fn build_ui(window: &mut ApplicationWindow) {
window.register_mouse_released(|_, evt| {
let mut pos: Point = evt.position().into();
pos.offset(-100, -100);
Tooltip::show("Test tooltip overlap", pos, OptionSize::none(), None);
Tooltip::show(
"Test tooltip overlap",
pos,
OptionSize::none(),
Some(Styles::default().with_border(Border::default().with_border_radius(6.))),
);
});
}
1 change: 0 additions & 1 deletion examples/input_element/holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ impl ObjectSubclass for Holder {

impl ObjectImpl for Holder {
fn construct(&mut self) {
Select::<String>::new_alloc();
self.parent_construct();
self.add_popup(InputPopup::new().to_dyn_popup_tr());
}
Expand Down
2 changes: 1 addition & 1 deletion tmui/src/application_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ impl ApplicationWindow {
for (_, overlaid) in self.overlaids.iter_mut() {
let overlaid = nonnull_mut!(overlaid);
if let Some(popup) = cast_mut!(overlaid as PopupImpl) {
if !popup.hide_on_click() {
if !popup.hide_on_click() || evt.mouse_button() != popup.click_hide_button() {
continue;
}
if popup.handle_global_mouse_pressed(evt) {
Expand Down
59 changes: 51 additions & 8 deletions tmui/src/graphics/border.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,48 @@ impl Border {
}
}

#[inline]
pub fn with_style(mut self, style: BorderStyle) -> Self {
self.style = style;
self
}

#[inline]
pub fn with_width(mut self, width: f32) -> Self {
self.width = (width, width, width, width);
self
}

#[inline]
pub fn with_width_sep(mut self, top: f32, right: f32, bottom: f32, left: f32) -> Self {
self.width = (top, right, bottom, left);
self
}

#[inline]
pub fn with_color(mut self, color: Color) -> Self {
self.border_color = (color, color, color, color);
self
}

#[inline]
pub fn with_color_sep(mut self, top: Color, right: Color, bottom: Color, left: Color) -> Self {
self.border_color = (top, right, bottom, left);
self
}

#[inline]
pub fn with_border_radius(mut self, radius: f32) -> Self {
self.border_radius = (radius, radius, radius, radius);
self
}

#[inline]
pub fn with_border_radius_sep(mut self, lt: f32, rt: f32, rb: f32, lb: f32) -> Self {
self.border_radius = (lt, rt, rb, lb);
self
}

pub(crate) fn render(&self, painter: &mut Painter, geometry: FRect) {
painter.save_pen();

Expand Down Expand Up @@ -284,6 +326,7 @@ impl Border {
geometry.offset(left / 2., top / 2.);
geometry.set_width(geometry.width() - right);
geometry.set_height(geometry.height() - bottom);
painter.set_antialiasing(true);
painter.draw_round_rect(geometry, self.border_radius);

painter.reset();
Expand Down Expand Up @@ -341,11 +384,11 @@ impl Border {
let (start_width, mid_width, end_width) = (left, (left + top) / 2., top);
if left > 0. {
painter.set_color(self.border_color.3);
painter.draw_varying_arc(lt, 180., 45., start_width, mid_width, 8);
painter.draw_varying_arc(lt, 180., 45., start_width, mid_width, 16);
}
if top > 0. {
painter.set_color(self.border_color.0);
painter.draw_varying_arc(lt, 225., 45., mid_width, end_width, 8);
painter.draw_varying_arc(lt, 225., 45., mid_width, end_width, 16);
}

let dimension = 2. * self.border_radius.1;
Expand All @@ -358,11 +401,11 @@ impl Border {
let (start_width, mid_width, end_width) = (top, (top + right) / 2., right);
if top > 0. {
painter.set_color(self.border_color.0);
painter.draw_varying_arc(rt, 270., 45., start_width, mid_width, 8);
painter.draw_varying_arc(rt, 270., 45., start_width, mid_width, 16);
}
if right > 0. {
painter.set_color(self.border_color.1);
painter.draw_varying_arc(rt, 315., 45., mid_width, end_width, 8);
painter.draw_varying_arc(rt, 315., 45., mid_width, end_width, 16);
}

let dimension = 2. * self.border_radius.2;
Expand All @@ -375,11 +418,11 @@ impl Border {
let (start_width, mid_width, end_width) = (right, (bottom + right) / 2., bottom);
if right > 0. {
painter.set_color(self.border_color.1);
painter.draw_varying_arc(rb, 0., 45., start_width, mid_width, 8);
painter.draw_varying_arc(rb, 0., 45., start_width, mid_width, 16);
}
if bottom > 0. {
painter.set_color(self.border_color.2);
painter.draw_varying_arc(rb, 45., 45., mid_width, end_width, 8);
painter.draw_varying_arc(rb, 45., 45., mid_width, end_width, 16);
}

let dimension = 2. * self.border_radius.3;
Expand All @@ -392,11 +435,11 @@ impl Border {
let (start_width, mid_width, end_width) = (bottom, (bottom + left) / 2., left);
if bottom > 0. {
painter.set_color(self.border_color.2);
painter.draw_varying_arc(lb, 90., 45., start_width, mid_width, 8);
painter.draw_varying_arc(lb, 90., 45., start_width, mid_width, 16);
}
if left > 0. {
painter.set_color(self.border_color.3);
painter.draw_varying_arc(lb, 135., 45., mid_width, end_width, 8);
painter.draw_varying_arc(lb, 135., 45., mid_width, end_width, 16);
}

painter.reset();
Expand Down
2 changes: 2 additions & 0 deletions tmui/src/input/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ impl InputDialog {
if let Some(styles) = styles {
input.set_styles(styles);
};
let radius = input.border_ref().border_radius;
self.set_border_radius_sep(radius.0, radius.1, radius.2, radius.3);

self.switch_index(idx);
self.current = input_type;
Expand Down
8 changes: 7 additions & 1 deletion tmui/src/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
widget::WidgetImpl,
};
use std::ptr::NonNull;
use tlib::{events::MouseEvent, nonnull_mut, nonnull_ref};
use tlib::{events::MouseEvent, namespace::MouseButton, nonnull_mut, nonnull_ref};

#[extends(Widget)]
#[cfg(win_popup)]
Expand Down Expand Up @@ -150,6 +150,12 @@ pub trait PopupImpl: WidgetImpl + PopupExt + Overlaid {
true
}

/// The mouse button of mouse to clicking hide the component.
#[inline]
fn click_hide_button(&self) -> MouseButton {
MouseButton::LeftButton
}

/// If true, popup will move postion by mouse dragging.
///
/// Default value is [`false`]
Expand Down
9 changes: 7 additions & 2 deletions tmui/src/runtime/wed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ pub(crate) fn win_evt_dispatch(window: &mut ApplicationWindow, evt: Event) -> Op
}

window.check_mouse_leave(&pos, &evt);
let mut mouse_move_handled = false;

for (_id, widget_opt) in widgets_map.iter_mut() {
let widget = nonnull_mut!(widget_opt);
Expand All @@ -177,8 +178,12 @@ pub(crate) fn win_evt_dispatch(window: &mut ApplicationWindow, evt: Event) -> Op
if !widget.visible() {
continue;
}

window.check_mouse_enter(widget, &pos, &evt);

if mouse_move_handled {
continue;
}
let widget_position = widget.map_to_widget(&pos);

if widget.point_effective(&evt.position().into()) {
Expand Down Expand Up @@ -237,9 +242,9 @@ pub(crate) fn win_evt_dispatch(window: &mut ApplicationWindow, evt: Event) -> Op
widget.on_mouse_move(evt.as_ref());

if widget.super_type().is_a(SharedWidget::static_type()) {
event = Some(evt);
event = Some(evt.clone());
}
break;
mouse_move_handled = true;
}
}

Expand Down
5 changes: 4 additions & 1 deletion tmui/src/widget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,10 @@ impl<T: WidgetImpl + WidgetExt + WidgetInnerExt + ShadowRender> ElementImpl for
self.clip_child_region(&mut painter);
}
if let Some(parent) = self.get_parent_ref() {
if cast!(parent as ContainerImpl).is_some() {
if parent.border_ref().should_draw_radius() {
let radius = parent.border_ref().border_radius;
painter.clip_round_rect_global(parent.rect(), radius, ClipOp::Intersect);
} else {
painter.clip_rect_global(parent.contents_rect(None), ClipOp::Intersect);
}
}
Expand Down
4 changes: 4 additions & 0 deletions tmui/src/widget/win_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub(crate) fn handle_win_widget_create(win_widget: &mut dyn WinWidget, inner: bo
window.map_to_client(&rect.top_left())
};

let radius = win_widget.border_ref().border_radius;

let child_proc_fn = win_widget.child_process_fn();
window.create_window(
WindowBuilder::new()
Expand All @@ -74,6 +76,8 @@ pub(crate) fn handle_win_widget_create(win_widget: &mut dyn WinWidget, inner: bo
.win_widget_id(win_widget.id())
.on_activate(move |win| {
win.set_transparency(0);
win.set_border_radius_sep(radius.0, radius.1, radius.2, radius.3);

child_proc_fn(win);
}),
)
Expand Down