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
768 changes: 477 additions & 291 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ path = "multi_window/main.rs"
name = "non_strict_clip"
path = "non_strict_clip/main.rs"

[[bin]]
name = "padding_demo"
path = "padding_demo/main.rs"

[[bin]]
name = "pane_layout"
path = "pane_layout/main.rs"
Expand Down
4 changes: 2 additions & 2 deletions examples/list_view/list_view_holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl ObjectImpl for ListViewHolder {
println!("List view prepare async add node.");
async_do!(move {
let mut list = arc.lock();
for i in 10..1000000 {
for i in 10..100 {
list.add_node(&Node {
name: format!("Node_{}", i),
});
Expand Down Expand Up @@ -166,7 +166,7 @@ impl ObjectImpl for ListViewHolder {
println!("Build list 3 in thread {:?}", thread::current().id());
let mut list = arc.lock();

for i in 0..1000 {
for i in 0..100 {
list.add_node(&Node {
name: format!("Node_{}", i),
});
Expand Down
1 change: 1 addition & 0 deletions examples/list_view/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl ListViewObject for Node {
.cell_render(
TextCellRender::builder()
.color(Color::BLACK)
.selection_color(Some(Color::WHITE))
.halign(Align::Center)
.valign(Align::Center)
.build(),
Expand Down
22 changes: 22 additions & 0 deletions examples/padding_demo/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pub mod padding_widget;

use padding_widget::PaddingWidget;
use tmui::{application::Application, application_window::ApplicationWindow, prelude::*};

fn main() {
log4rs::init_file("examples/log4rs.yaml", Default::default()).unwrap();

let app = Application::builder()
.width(1280)
.height(800)
.title("Padding Demo")
.build();

app.connect_activate(build_ui);

app.run();
}

fn build_ui(window: &mut ApplicationWindow) {
window.child(PaddingWidget::new_alloc());
}
33 changes: 33 additions & 0 deletions examples/padding_demo/padding_widget.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use tmui::{
prelude::*,
tlib::object::{ObjectImpl, ObjectSubclass},
widget::WidgetImpl,
};

#[extends(Widget)]
#[derive(Childable)]
pub struct PaddingWidget {
#[child]
child: Tr<Widget>,
}

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

impl ObjectImpl for PaddingWidget {
fn initialize(&mut self) {
self.set_background(Color::RED);
self.width_request(500);
self.height_request(500);
self.set_halign(Align::Center);
self.set_valign(Align::Center);
self.set_paddings(10, 10, 10, 10);

self.child.set_background(Color::BLUE);
self.child.set_hexpand(true);
self.child.set_vexpand(true);
}
}

impl WidgetImpl for PaddingWidget {}
Empty file removed tlib/src/figure/font.rs
Empty file.
15 changes: 9 additions & 6 deletions tmui/src/font/mgr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use ahash::AHashMap;
use derivative::Derivative;
use log::error;
use std::{cell::RefCell, io::Read};
use tlib::{
skia_safe::FontMgr,
Expand Down Expand Up @@ -52,12 +53,14 @@ impl FontManager {
.unwrap_or_else(|| panic!("Load ttf file `{}` failed.", font))
.data;

let tf = manager
.system_mgr
.new_from_data(&data, None)
.unwrap_or_else(|| {
panic!("Make font typeface failed, ttf file: {}.", font)
});
let tf = manager.system_mgr.new_from_data(&data, None);

if tf.is_none() {
error!("Make font typeface failed, ttf file: {}.", font);
continue;
}

let tf = tf.unwrap();

manager.fonts.insert(tf.family_name(), tf);
}
Expand Down
2 changes: 2 additions & 0 deletions tmui/src/platform/platform_win_op.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(windows_platform)]
use crate::prelude::{RawWindowHandle5, RawWindowHandle6};
use tlib::typedef::WinitWindow;

Expand Down Expand Up @@ -30,6 +31,7 @@ impl HwndGetter for RawWindowHandle6 {
}

#[inline]
#[allow(unused_variables)]
pub(crate) fn set_undecoration_window(window: &WinitWindow) {
#[cfg(windows_platform)]
{
Expand Down
48 changes: 39 additions & 9 deletions tmui/src/views/cell/cell_render.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(dead_code)]
use crate::{graphics::painter::Painter, icons::svg_dom::SvgDom};
use crate::{graphics::painter::Painter, icons::svg_dom::SvgDom, views::node::Status};
use derivative::Derivative;
use log::warn;
use std::fmt::Debug;
Expand All @@ -25,7 +25,7 @@ pub enum CellRenderType {
}

pub trait CellRender: Debug + 'static + Send + Sync {
fn render(&self, painter: &mut Painter, geometry: FRect, val: Option<&Value>);
fn render(&self, painter: &mut Painter, geometry: FRect, val: Option<&Value>, node_status: Status);

fn border(&self) -> (f32, f32, f32, f32);

Expand Down Expand Up @@ -264,18 +264,33 @@ macro_rules! impl_cell_render_common {
}

type OptSvgDom = Option<SvgDom>;
type OptColor = Option<Color>;

cell_render_struct!(TextCellRender, TextCellRenderBuilder, Text, color:Color, letter_spacing:f32);
cell_render_struct!(TextCellRender, TextCellRenderBuilder, Text, color:Color, hover_color:OptColor, selection_color:OptColor, letter_spacing:f32);
cell_render_struct!(ImageCellRender, ImageCellRenderBuilder, Image);
cell_render_struct!(SvgCellRender, SvgCellRenderBuilder, Svg, dom:OptSvgDom);
cell_render_struct!(SvgCellRender, SvgCellRenderBuilder, Svg, dom:OptSvgDom, hover_dom:OptSvgDom, selection_dom:OptSvgDom);

impl CellRender for TextCellRender {
fn render(&self, painter: &mut Painter, geometry: FRect, val: Option<&Value>) {
fn render(&self, painter: &mut Painter, geometry: FRect, val: Option<&Value>, status: Status) {
painter.save();
painter.save_pen();
painter.clip_rect(geometry, ClipOp::Intersect);

painter.set_color(self.color);
if status.contains(Status::Selected) {
if let Some(color) = self.selection_color {
painter.set_color(color);
} else {
painter.set_color(self.color);
}
} else if status.contains(Status::Hovered) {
if let Some(color) = self.hover_color {
painter.set_color(color);
} else {
painter.set_color(self.color);
}
} else {
painter.set_color(self.color);
}

if let Some(background) = self.background {
painter.fill_rect(geometry, background);
Expand Down Expand Up @@ -413,14 +428,29 @@ impl TextCellRender {
}

impl CellRender for ImageCellRender {
fn render(&self, _painter: &mut Painter, _geometry: FRect, _val: Option<&Value>) {}
fn render(&self, _painter: &mut Painter, _geometry: FRect, _val: Option<&Value>, _status: Status) {}

impl_cell_render_common!();
}

impl CellRender for SvgCellRender {
fn render(&self, painter: &mut Painter, rect: FRect, _: Option<&Value>) {
if let Some(dom) = self.dom.as_ref() {
fn render(&self, painter: &mut Painter, rect: FRect, _: Option<&Value>, status: Status) {
let dom = if status.contains(Status::Selected) {
if self.selection_dom.is_some() {
self.selection_dom.as_ref()
} else {
self.dom.as_ref()
}
} else if status.contains(Status::Hovered) {
if self.hover_dom.is_some() {
self.hover_dom.as_ref()
} else {
self.dom.as_ref()
}
} else {
self.dom.as_ref()
};
if let Some(dom) = dom {
let view_size = dom.get_size();
let (x1, y1, w1, h1) = (rect.x(), rect.y(), rect.width(), rect.height());
let (w2, h2) = (view_size.width() as f32, view_size.height() as f32);
Expand Down
40 changes: 21 additions & 19 deletions tmui/src/views/cell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use self::cell_render::{CellRender, CellRenderType, CellRenderType::*};
use crate::graphics::painter::Painter;
use tlib::{figure::FRect, types::StaticType, values::ToValue, Type, Value};

use super::node::Status;

/// The data cell of a TreeNode, one TreeNode represents one row of an image,
/// and one Cell corresponds to one column of the image.
///
Expand All @@ -31,70 +33,70 @@ pub enum Cell {
}

macro_rules! common_cell_render_clause {
($render:ident, $painter:ident, $geometry:ident, $val:ident) => {
($render:ident, $painter:ident, $geometry:ident, $val:ident, $status:ident) => {
if let Some(render) = $render {
render.render($painter, $geometry, Some($val));
render.render($painter, $geometry, Some($val), $status);
}
};
}

impl Cell {
pub(crate) fn render_cell(&self, painter: &mut Painter, geometry: FRect) {
pub(crate) fn render_cell(&self, painter: &mut Painter, geometry: FRect, status: Status) {
match self {
Self::String { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::Bool { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::U8 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::I8 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::U16 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::I16 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::U32 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::I32 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::U64 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::I64 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::U128 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::I128 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::F32 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::F64 { val, render, .. } => {
common_cell_render_clause!(render, painter, geometry, val);
common_cell_render_clause!(render, painter, geometry, val, status);
}
Self::Image {
image_address,
render,
..
} => {
if let Some(render) = render {
render.render(painter, geometry, Some(image_address));
render.render(painter, geometry, Some(image_address), status);
}
}
Self::Svg { render, .. } => {
if let Some(render) = render {
render.render(painter, geometry, None);
render.render(painter, geometry, None, status);
}
}
Self::Value { .. } => {}
Expand Down
3 changes: 2 additions & 1 deletion tmui/src/views/list_view/list_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl ListItem for ListNode {

let gapping = geometry.width() / self.render_cell_size() as f32;
let mut offset = geometry.x();
let status = self.status();

for cell in self.cells.iter() {
if let Some(cell_render) = cell.get_render() {
Expand All @@ -232,7 +233,7 @@ impl ListItem for ListNode {

offset += cell_rect.width();

cell.render_cell(painter, cell_rect);
cell.render_cell(painter, cell_rect, status);
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions tmui/src/views/list_view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ impl WidgetImpl for ListView {
fn enable_focus(&self) -> bool {
true
}

#[inline]
fn font_changed(&mut self) {
let font = self.font().clone();
self.get_image_mut().set_font(font);
}
}

impl ListView {
Expand Down
3 changes: 2 additions & 1 deletion tmui/src/views/tree_view/tree_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ impl TreeNode {

let gapping = geometry.width() / self.render_cell_size() as f32;
let mut offset = geometry.x();
let status = self.status;

for cell in self.cells.iter() {
if let Some(cell_render) = cell.get_render() {
Expand All @@ -371,7 +372,7 @@ impl TreeNode {

offset += cell_rect.width();

cell.render_cell(painter, cell_rect);
cell.render_cell(painter, cell_rect, status);
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion tmui/src/widget/widget_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,8 +1057,14 @@ impl<T: WidgetImpl> WidgetExt for T {
#[inline]
fn borderless_rect(&self) -> Rect {
let mut rect = self.rect();
let paddings = self.paddings();
let (top, right, bottom, left) = self.borders().ceil();
let (top, right, bottom, left) = (top as i32, right as i32, bottom as i32, left as i32);
let (top, right, bottom, left) = (
(top as i32).max(paddings.0),
(right as i32).max(paddings.1),
(bottom as i32).max(paddings.2),
(left as i32).max(paddings.3),
);

if rect.width() >= (right + left) {
rect.set_x(rect.x() + left);
Expand Down