rust gui开发 根据官网例子学习orbtk(2)

2023-05-16

orbtk基础组件

效果图
在这里插入图片描述
依赖

orbtk = "0.3.1-alpha3"
serde_derive = "1.0.106"

代码

use std::collections::HashSet;

use orbtk::prelude::*;

#[derive(Debug, Copy, Clone)]
enum Action {
    AddItem,
    ClearText,
    EntryActivated(Entity),
    IncrementCounter,
    RemoveItem,
    ToggleTheme(Entity),
}

#[derive(AsAny)]
pub struct MainViewState {
    action: Option<Action>,
}

impl Default for MainViewState {
    fn default() -> Self {
        MainViewState { action: None }
    }
}

impl MainViewState {
    fn action(&mut self, action: impl Into<Option<Action>>) {
        self.action = action.into();
    }
}

impl State for MainViewState {
    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        if let Some(action) = self.action {
            match action {
                Action::AddItem => {
                    let len = main_view(ctx.widget()).list().len();

                    if len < 5 {
                        main_view(ctx.widget())
                            .list_mut()
                            .push(format!("Item {}", len + 1));
                        ctx.child("items").clone_or_default::<usize>("Item");
                        items_widget(ctx.child("items")).set_count(len + 1);
                        button(ctx.child("remove-item-button")).set_enabled(true);
                        button(ctx.child("remove-item-button")).set_visibility(Visibility::Visible);

                        if len == 4 {
                            button(ctx.child("add-item-button")).set_enabled(false);
                            button(ctx.child("add-item-button"))
                                .set_visibility(Visibility::Collapsed);
                        }
                    }
                }
                Action::RemoveItem => {
                    let len = main_view(ctx.widget()).list().len();
                    if len > 0 {
                        main_view(ctx.widget()).list_mut().remove(len - 1);
                        items_widget(ctx.child("items")).set_count(len - 1);
                        button(ctx.child("add-item-button")).set_enabled(true);
                        button(ctx.child("add-item-button")).set_visibility(Visibility::Visible);

                        if len == 1 {
                            button(ctx.child("remove-item-button")).set_enabled(false);
                            button(ctx.child("remove-item-button"))
                                .set_visibility(Visibility::Collapsed);
                        }
                    }
                }
                Action::IncrementCounter => {
                    *main_view(ctx.widget()).counter_mut() += 1;

                    let counter = *main_view(ctx.widget()).counter();

                    main_view(ctx.widget())
                        .set_result(String16::from(format!("Button count: {}", counter)));
                }
                Action::ClearText => {
                    main_view(ctx.widget()).set_text_one(String16::default());
                    main_view(ctx.widget()).set_text_two(String16::default());
                }
                Action::EntryActivated(entity) => {
                    let mut text_box = text_box(ctx.get_widget(entity));
                    let text = text_box.text_mut();
                    println!("submitting {}", text);
                    text.clear();
                }
                Action::ToggleTheme(entity) => {
                    let light = *ctx.get_widget(entity).get::<bool>("selected");

                    let theme = if light { light_theme() } else { dark_theme() };
                    ctx.switch_theme(theme);
                }
            }

            self.action = None;
        }
    }

    fn update_post_layout(&mut self, _: &mut Registry, ctx: &mut Context) {
        let mut selection_string = "Selected:".to_string();

        for index in &main_view(ctx.widget()).selected_indices().0 {
            selection_string = format!("{} {}", selection_string, index);
        }

        text_block(ctx.child("selection")).set_text(selection_string);
    }
}

fn create_header(ctx: &mut BuildContext, text: &str) -> Entity {
    TextBlock::new().text(text).style("header").build(ctx)
}

type List = Vec<String>;

widget!(
    MainView<MainViewState> {
        selected_indices: SelectedIndices,
        counter: usize,
        list_count: usize,
        combo_box_list_count: usize,
        list: List,
        selection_list: List,
        combo_box_list: List,
        selection_list_count: usize,
        text_one: String16,
        text_two: String16,
        result: String16
    }
);

impl Template for MainView {
    fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
        let slider = Slider::new()
            .min(0.0)
            .max(1.0)
            // .on_changed(move |states, entity| {
            //     state(id, states).action(Action::ValueChanged(entity));
            // })
            .build(ctx);

        self.name("MainView")
            .result("Button count: 0")
            .counter(0)
            .selected_indices(HashSet::new())
            .list(vec![
                "Item 1".to_string(),
                "Item 2".to_string(),
                "Item 3".to_string(),
            ])
            .list_count(3)
            .selection_list(vec![
                "Select Item 1".to_string(),
                "Select Item 2".to_string(),
                "Select Item 3".to_string(),
                "Select Item 4".to_string(),
                "Select Item 5".to_string(),
                "Select Item 6".to_string(),
                "Select Item 7".to_string(),
                "Select Item 8".to_string(),
                "Select Item 9".to_string(),
                "Select Item 10".to_string(),
            ])
            .combo_box_list(vec![
                "CB 1".to_string(),
                "CB 2".to_string(),
                "CB 3".to_string(),
                "CB 4".to_string(),
                "CB 5".to_string(),
                "CB 6".to_string(),
                "CB 7".to_string(),
                "CB 8".to_string(),
                "CB 9".to_string(),
                "CB 10".to_string(),
            ])
            .selection_list_count(10)
            .combo_box_list_count(10)
            .child(
                Grid::new()
                    .margin(8)
                    .columns(
                        Columns::create()
                            .push(132)
                            .push(16)
                            .push(132)
                            .push(16)
                            .push(132),
                    )
                    .rows(Rows::create().push("*").push(32))
                    .child(
                        Stack::new()
                            .attach(Grid::column(0))
                            .attach(Grid::row(0))
                            // Column 0
                            .child(create_header(ctx, "Buttons"))
                            .child(
                                Button::new()
                                    .text("Button")
                                    .margin((0, 8, 0, 0))
                                    .icon(material_icons_font::MD_CHECK)
                                    .attach(Grid::column(0))
                                    .attach(Grid::row(1))
                                    .on_click(move |states, _| {
                                        state(id, states).action(Action::IncrementCounter);
                                        true
                                    })
                                    .build(ctx),
                            )
                            .child(
                                Button::new()
                                    .text("Primary")
                                    .style("button_primary")
                                    .margin((0, 8, 0, 0))
                                    .icon(material_icons_font::MD_360)
                                    .attach(Grid::column(0))
                                    .attach(Grid::row(2))
                                    .build(ctx),
                            )
                            .child(
                                ToggleButton::new()
                                    .style("button_single_content")
                                    .text("ToggleButton")
                                    .margin((0, 8, 2, 0))
                                    .icon(material_icons_font::MD_ALARM_ON)
                                    .attach(Grid::column(0))
                                    .attach(Grid::row(3))
                                    .build(ctx),
                            )
                            .child(
                                CheckBox::new()
                                    .text("CheckBox")
                                    .margin((0, 8, 0, 0))
                                    .attach(Grid::column(0))
                                    .attach(Grid::row(4))
                                    .build(ctx),
                            )
                            .child(
                                Switch::new()
                                    .margin((0, 8, 0, 0))
                                    .attach(Grid::column(0))
                                    .attach(Grid::row(5))
                                    .build(ctx),
                            )
                            .child(slider)
                            .child(
                                ProgressBar::new()
                                    .val(slider)
                                    .margin((0, 8, 0, 0))
                                    .build(ctx),
                            )
                            .build(ctx),
                    )
                    .child(
                        Stack::new()
                            .attach(Grid::column(2))
                            .attach(Grid::row(0))
                            .child(create_header(ctx, "Text"))
                            .child(
                                TextBlock::new()
                                    .style("body")
                                    .text(("result", id))
                                    .margin((0, 8, 0, 0))
                                    .attach(Grid::column(2))
                                    .attach(Grid::row(1))
                                    .build(ctx),
                            )
                            .child(
                                TextBox::new()
                                    .water_mark("TextBox...")
                                    .text(("text_one", id))
                                    .margin((0, 8, 0, 0))
                                    .attach(Grid::column(2))
                                    .attach(Grid::row(2))
                                    .on_activate(move |states, entity| {
                                        state(id, states).action(Action::EntryActivated(entity));
                                    })
                                    .build(ctx),
                            )
                            .child(
                                TextBox::new()
                                    .water_mark("TextBox...")
                                    .text(("text_two", id))
                                    .margin((0, 8, 0, 0))
                                    .attach(Grid::column(2))
                                    .attach(Grid::row(2))
                                    .on_activate(move |states, entity| {
                                        state(id, states).action(Action::EntryActivated(entity));
                                    })
                                    .build(ctx),
                            )
                            .child(
                                Button::new()
                                    .margin((0, 8, 0, 0))
                                    .style("button_single_content")
                                    .text("clear text")
                                    .icon(material_icons_font::MD_CLEAR)
                                    .on_click(move |states, _| {
                                        state(id, states).action(Action::ClearText);
                                        true
                                    })
                                    .build(ctx),
                            )
                            .child(
                                NumericBox::new()
                                    .margin((0, 8, 0, 0))
                                    .max(123)
                                    .step(0.123)
                                    .val(0.123)
                                    .build(ctx),
                            )
                            .build(ctx),
                    )
                    .child(
                        Grid::new()
                            .rows(
                                Rows::create()
                                    .push("auto")
                                    .push(32)
                                    .push(16)
                                    .push(204)
                                    .push("auto")
                                    .push(192)
                                    .push("auto"),
                            )
                            .columns(Columns::create().push("*").push(4).push("*"))
                            .attach(Grid::column(4))
                            .attach(Grid::row(0))
                            .child(
                                TextBlock::new()
                                    .text("Items")
                                    .style("header")
                                    .attach(Grid::column(0))
                                    .attach(Grid::column_span(3))
                                    .attach(Grid::row(0))
                                    .build(ctx),
                            )
                            .child(
                                ComboBox::new()
                                    .items_builder(move |bc, index| {
                                        let text = bc
                                            .get_widget(id)
                                            .get::<Vec<String>>("combo_box_list")[index]
                                            .clone();
                                        TextBlock::new()
                                            .style("small_text")
                                            .margin((0, 0, 0, 2))
                                            .v_align("center")
                                            .text(text)
                                            .build(bc)
                                    })
                                    .selected_index(0)
                                    .attach(Grid::column(0))
                                    .attach(Grid::column_span(3))
                                    .attach(Grid::row(1))
                                    .margin((0, 8, 0, 0))
                                    .count(("combo_box_list_count", id))
                                    .build(ctx),
                            )
                            .child(
                                ItemsWidget::new()
                                    .id("items")
                                    .padding((4, 4, 4, 2))
                                    .attach(Grid::column(0))
                                    .attach(Grid::column_span(3))
                                    .attach(Grid::row(3))
                                    .margin((0, 0, 0, 8))
                                    // bc = build-context
                                    .items_builder(move |bc, index| {
                                        let text = bc.get_widget(id).get::<Vec<String>>("list")
                                            [index]
                                            .clone();

                                        Button::new().margin((0, 0, 0, 2)).text(text).build(bc)
                                    })
                                    .count(("list_count", id))
                                    .build(ctx),
                            )
                            .child(
                                Button::new()
                                    .style("button_single_content")
                                    .id("remove-item-button")
                                    .icon(material_icons_font::MD_REMOVE_CIRCLE)
                                    .on_click(move |states, _| {
                                        state(id, states).action(Action::RemoveItem);
                                        true
                                    })
                                    .min_width(0)
                                    .attach(Grid::column(0))
                                    .attach(Grid::row(4))
                                    .build(ctx),
                            )
                            .child(
                                Button::new()
                                    .style("button_single_content")
                                    .id("add-item-button")
                                    .icon(material_icons_font::MD_ADD_CIRCLE)
                                    .on_click(move |states, _| {
                                        state(id, states).action(Action::AddItem);
                                        true
                                    })
                                    .min_width(0)
                                    .attach(Grid::column(2))
                                    .attach(Grid::row(4))
                                    .build(ctx),
                            )
                            .child(
                                ListView::new()
                                    .attach(Grid::column(0))
                                    .attach(Grid::column_span(3))
                                    .attach(Grid::row(5))
                                    .selected_indices(id)
                                    .margin((0, 16, 0, 8))
                                    .items_builder(move |bc, index| {
                                        let text = bc
                                            .get_widget(id)
                                            .get::<Vec<String>>("selection_list")[index]
                                            .clone();
                                        TextBlock::new()
                                            .margin((0, 0, 0, 2))
                                            .v_align("center")
                                            .text(text)
                                            .build(bc)
                                    })
                                    .on_selection_changed(|_, _, _| println!("Selection changed"))
                                    .count(("selection_list_count", id))
                                    .build(ctx),
                            )
                            .child(
                                // todo: wrong text width????
                                TextBlock::new()
                                    .style("body")
                                    .id("selection")
                                    .max_width(120)
                                    .attach(Grid::column(0))
                                    .attach(Grid::column_span(3))
                                    .attach(Grid::row(6))
                                    .text("Selected:")
                                    .build(ctx),
                            )
                            .build(ctx),
                    )
                    .child(
                        Stack::new()
                            .orientation("horizontal")
                            .attach(Grid::row(1))
                            .attach(Grid::column(0))
                            .child(
                                TextBlock::new()
                                    .style("body")
                                    .text("Toggle theme: ")
                                    .v_align("center")
                                    .margin((0, 0, 4, 0))
                                    .build(ctx),
                            )
                            .child(
                                Switch::new()
                                    .on_changed(move |states, entity, _| {
                                        state(id, states).action(Action::ToggleTheme(entity));
                                    })
                                    .v_align("center")
                                    .build(ctx),
                            )
                            .build(ctx),
                    )
                    .build(ctx),
            )
    }
}

fn main() {
    // use this only if you want to run it as web application.
    orbtk::initialize();

    Application::new()
        .window(|ctx| {
            Window::new()
                .title("OrbTk - widgets example")
                .position((100, 100))
                .size(468, 730)
                .resizeable(true)
                .child(MainView::new().build(ctx))
                .build(ctx)
        })
        .run();
}

// helper to request MainViewState
fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut MainViewState {
    states.get_mut(id)
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

rust gui开发 根据官网例子学习orbtk(2) 的相关文章

随机推荐

  • 网络编程POSIX规范要求数据类型

    数据类型 说明 来源 int8 t 带符号8位整数 lt sys types h gt uint8 t 无符号8位整数 lt sys types h gt int16 t 带符号16位整数 lt sys types h gt uint16
  • 解决ajax的delete、put方法接受不到参数的问题

    通过修改配置文件来实现Put和Delete请求的参数传递的问题 在web xml中添加如下代码 xff1a lt filter gt lt filter name gt HttpMethodFilter lt filter name gt
  • - Dockerfile 指令、构建过程

    查看Dockerfile中可以使用的全部指令 xff1a lt http docs docker com reference builder gt 制作Docker image 有两种方式 xff1a 一是使用 Docker contain
  • python正则表达式匹配邮箱地址是否合法

    题目 xff1a 1 xff09 请尝试写一个验证Email地址的正则表达式 版本一应该可以验证出类似的Email xff1a someone 64 gmail com bill gates 64 microsoft com 2 xff09
  • 公网IP和内网IP的区别? 什么是127.0.0.1?

    IP地址是设备在网络上的唯一标识符 xff0c 比如无线路由器有两个IP xff0c 公网IP xff08 例如100 78 118 73 连接互联网 xff0c 私有 xff08 内网 xff09 IP xff08 如192 168 1
  • 计算机网络课程设计之Tracert与Ping 程序设计与实现

    一 预备知识 ICMP ICMP的报文是封装在IP数据部分中的 按照我的理解 xff0c ICMP就是在网络层中 xff0c 反馈一些转发 访问等操作时的附带信息 ICMP分为两种 xff0c ICMP差错报告报文 xff08 IP传输时的
  • 计算机网络课程设计之网络聊天程序的设计与实现

    TCP和UDP在接收方的区别 xff08 实际上本实验中用不着 xff09 UDP 协议 User Datagram Protocol 用户数据报协议 xff0c 是一 种保护消息边界的 xff0c 不保障可靠数据的传输 就是指传输协议把数
  • 计算机网络课程设计之嗅探器实现

    资料来源网络 xff0c 侵权请联系删除 原理 简单说明一下什么是网络嗅探器 xff0c 网络嗅探器是一个抓取所有经过网卡数据的软件 xff0c 在一般使用电脑时 xff0c 网卡只接受到发送至本机的数据 xff0c 那是因为这是网卡是非混
  • 牛客网高级项目总结

    1 注册和登陆 登陆和注册成功之后 xff0c 在cookie里添加上token xff0c 另外在数据库中插入包含token userId的表 xff0c 用于登陆状态检验 具体检验是在拦截器上进行 xff0c 拦截器的实现过程 xff1
  • 设计模式

    面向对象设计原则 每个对象是拥有独立责任的抽象体 真正的复用是源代码不做修改 xff0c 编译 43 测试之后就不会再修改 设计原则 1 依赖倒置原则 xff08 DIP xff09 1 xff09 高层模块 xff08 稳定 xff09
  • Redis面试

    1 更新操作 https coolshell cn articles 17416 html 不可以先删除缓存 xff0c 再更新数据库 因为并发操作下 xff0c 一个更新操作删掉了缓存 xff0c 此时一个读操作进来 xff0c 读取了旧
  • 【关系代数习题】纸上得来终觉浅——数据库学习之路(4)

    题A 设有如下所示的关系S S SNAME AGE SEX C C CNAME TEACHER 和SC S C GRADE xff0c 用关系代数表达式表示下列查询语句 xff1a 1 检索 程军 老师所授课程的课程号 C 和课程名 CNA
  • 线程池

    public ThreadPoolExecutor int corePoolSize int maximumPoolSize long keepAliveTime TimeUnit unit BlockingQueue lt Runnabl
  • 爬取3499手游网下载地址信息

    爬取3499手游网下载地址信息 爬取游戏的下载地址和信息 xff0c 爬取的信息存入到数据库中 1 首先需要安装第三方库 requests xff0c lxml xff0c MySQLdb 2 先创建down software数据库 创建y
  • %d几种输出方式

    d就是普通的输出了 2d是将数字按宽度为2 xff0c 采用右对齐方式输出 xff0c 如果数据位数不到2位 xff0c 则左边补空格 2d是将数字按宽度为2 xff0c 采用左对齐方式输出 xff0c 如果数据位数不到2位 xff0c 则
  • qt开启线程界面假死问题解决

    一 前言 在 使用qt高速读取传感器数据时 xff0c 如果想要将数据实时刷新在界面 xff0c 就需要开启一个线程单独去跑读取数据函数 xff0c 并反馈给主程序 xff0c 否则在主程序中读取和刷新界面会很卡很卡 xff0c 但是在开启
  • Ubuntu Qt安装arm指定的交叉编译环境SDK方式(概述篇)

    一 前言 苦心研究了几天交叉编译环境的安装 xff0c 因为工作需要 xff0c 要在一个arm系统上运行程序 xff0c 正常已经搭配好环境了 xff0c 见此贴 xff0c 后来改为SDK的方式更好使用 xff0c 但是SDK的方式对环
  • Jetson Xavier ubuntu18.04配置vnc进行远程桌面连接

    NVIDIA Jetson Xavier开发板装不上基于gnome桌面的VNC 由于ubuntu上有多个版本的VNC 尝试了vnc4server 43 xfce4后可远程控制 xff0c 因此记录下来方便后面继续装环境 1 安装 span
  • rust gui开发 根据官网例子学习orbtk(1)

    orbtk计算器例子 效果图 依赖 orbtk span class token operator 61 span span class token string 34 0 3 1 alpha3 34 span serde derive s
  • rust gui开发 根据官网例子学习orbtk(2)

    orbtk基础组件 效果图 依赖 orbtk span class token operator 61 span span class token string 34 0 3 1 alpha3 34 span serde derive sp