### Install Ninja Build System Source: https://github.com/allendang/wxdragon/blob/main/rust/wxdragon/README.md Install the Ninja build system on Windows using winget. ```bash winget install --id=Ninja-build.Ninja -e ``` -------------------------------- ### Run wxDragon Gallery Example Source: https://github.com/allendang/wxdragon/blob/main/rust/wxdragon/README.md Execute the gallery example to view all available widgets provided by the wxDragon library. ```bash # Run the gallery to see all widgets in action cargo run -p gallery ``` -------------------------------- ### Custom Widget Setup Implementation Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Illustrates the setup implementation for a custom widget, including setting background style, and configuring paint and mouse event handlers. ```rust setup_impl: |config, panel| { // 1. Configure the panel for custom drawing panel.set_background_style(BackgroundStyle::Paint); // 2. Set up event handlers panel.on_paint(move |event| { // Custom drawing code let dc = AutoBufferedPaintDC::new(&panel); // ... drawing implementation event.skip(true); }); // 3. Add mouse/keyboard event handlers panel.on_mouse_left_down(|event| { println!("Widget clicked!"); event.skip(true); // Important: allow event propagation }); } ``` -------------------------------- ### Run Custom Widget Example Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Command to run the custom widget example project using Cargo. ```bash cargo run -p custom_widget ``` -------------------------------- ### Cross-Compilation Setup for Windows Source: https://github.com/allendang/wxdragon/blob/main/README.md Commands to set up the environment for cross-compiling a Windows application from macOS, including installing the MinGW-w64 toolchain and adding the Windows target for Cargo. ```bash # Install MinGW-w64 toolchain (Homebrew may not always match the required version) brew install mingw-w64 # Or download and use WinLibs GCC 15.1.0 UCRT manually for ABI compatibility # Add Windows target rustup target add x86_64-pc-windows-gnu # Build for Windows cargo build --target=x86_64-pc-windows-gnu --release ``` -------------------------------- ### Custom Widget Example Documentation Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Enhanced documentation for the custom_widget example, including a README and GIF demonstration. ```rust custom_widget example ``` -------------------------------- ### Install Linux Dependencies Source: https://github.com/allendang/wxdragon/blob/main/README.md Install required system libraries for building wxDragon on Ubuntu/Debian or Fedora/RHEL distributions. ```bash # Ubuntu/Debian sudo apt-get install libclang-dev pkg-config libgtk-3-dev libpng-dev libjpeg-dev libgl1-mesa-dev libglu1-mesa-dev libxkbcommon-dev libexpat1-dev libtiff-dev # Fedora/RHEL sudo dnf install clang-devel pkg-config gtk3-devel libpng-devel libjpeg-devel mesa-libGL-devel mesa-libGLU-devel libxkbcommon-devel expat-devel libtiff-devel ``` -------------------------------- ### Install Fedora/RHEL Dependencies Source: https://github.com/allendang/wxdragon/blob/main/rust/wxdragon/README.md Install required development libraries and tools on Fedora or RHEL systems. ```bash sudo dnf install clang-devel pkg-config gtk3-devel libpng-devel libjpeg-devel mesa-libGL-devel mesa-libGLU-devel libxkbcommon-devel expat-devel libtiff-devel ``` -------------------------------- ### Install Linux Dependencies Source: https://github.com/allendang/wxdragon/blob/main/rust/wxdragon/README.md Install required system packages for Linux development. ```bash # Ubuntu/Debian sudo apt-get install libclang-dev pkg-config libgtk-3-dev libpng-dev libjpeg-dev libgl1-mesa-dev libglu1-mesa-dev libxkbcommon-dev libexpat1-dev libtiff-dev ``` -------------------------------- ### Process and Draw Chart Data in Rust Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Example of processing raw data into a drawable format and storing it in shared state for rendering within a paint handler. Includes setup for data visualization widgets. ```rust fields: { labels: Vec = vec!["A".to_string(), "B".to_string()], values: Vec = vec![30.0, 70.0], colors: Vec = vec![], }, setup_impl: |config, panel| { let processed_data = process_chart_data(&config.labels, &config.values); let chart_data = Rc::new(RefCell::new(processed_data)); let chart_data_paint = chart_data.clone(); panel.on_paint(move |event| { let data = chart_data_paint.borrow(); draw_chart(&panel, &data); event.skip(true); }); } ``` -------------------------------- ### CollapsiblePane Widget Demonstration Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Updates the gallery example to include a demonstration of the CollapsiblePane widget, showcasing its configurable expand/collapse behavior and integration with the layout system. ```rust gallery example ``` -------------------------------- ### Custom Widget Configuration Fields Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Example of defining configurable fields for a custom widget, including appearance and animation settings. ```rust fields: { // Basic appearance text: String = "Button".to_string(), background_color: Colour = Colour::new(240, 240, 240, 255), border_color: Colour = Colour::new(100, 100, 100, 255), border_width: i32 = 2, // Animation settings animation_duration: Duration = Duration::from_millis(300), // Data (for data visualization widgets) data_values: Vec = vec![10, 20, 30], } ``` -------------------------------- ### Define XRC UI Layout Source: https://context7.com/allendang/wxdragon/llms.txt An example XML structure for defining wxWidgets components in an XRC file. ```xml \n\n \n XRC Demo\n 400,300\n \n \n \n 50,50\n \n \n Enter text here...\n 50,100\n 200,25\n \n \n \n 50,150\n \n \n \n ``` -------------------------------- ### Custom DataView Renderer Example Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Showcases custom cell rendering and editing capabilities for DataView, demonstrating integration with custom data models and practical use cases for advanced customization. ```rust custom_dataview_renderer ``` -------------------------------- ### StyledTextCtrl Widget Example Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Demonstrates the functionality of the comprehensive StyledTextCtrl widget, a full-featured text editor component with syntax highlighting support. ```rust simple_stc_test ``` -------------------------------- ### Custom Widget Drawing Implementation Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Provides an example of custom drawing within a widget's paint event handler, including clearing the background and drawing text. ```rust panel.on_paint(move |event| { let dc = AutoBufferedPaintDC::new(&panel); let size = panel.get_size(); // Clear background dc.set_brush(config.background_color, BrushStyle::Solid); dc.draw_rectangle(0, 0, size.width, size.height); // Draw custom content dc.set_text_foreground(config.text_color); dc.draw_text(&config.text, 10, 10); event.skip(true); }); ``` -------------------------------- ### DataView Event Fix Verification Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md This example demonstrates the fix for the DataView event system, specifically verifying correct row index reporting in virtual list models. It includes console output for clicked rows. ```rust on_item_activated ``` -------------------------------- ### Basic Custom Widget Macro Structure Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Defines the basic structure for a custom widget using the custom_widget! macro, including name, fields, and setup implementation. ```rust use wxdragon::prelude::*; use std::cell::RefCell; use std::rc::Rc; custom_widget!( name: MyCustomWidget, fields: { // Widget configuration fields text: String = "Default Text".to_string(), background_color: Colour = Colour::new(240, 240, 240, 255), text_color: Colour = Colour::new(0, 0, 0, 255), }, setup_impl: |config, panel| { // Widget initialization code goes here } ); ``` -------------------------------- ### Initialize Application with wxdragon::main Source: https://context7.com/allendang/wxdragon/llms.txt Use the main entry point to initialize the framework, configure application metadata, and launch the event loop. ```rust use wxdragon::prelude::*;\n\nfn main() {\n // Disable manifest check on Windows for development\n SystemOptions::set_option_by_int("msw.no-manifest-check", 1);\n\n let _ = wxdragon::main(|app| {\n // Configure application settings\n app.set_app_name("MyApp");\n app.set_vendor_name("MyCompany");\n\n // Handle macOS-specific file open events\n app.on_open_files(|files| {\n println!("Opening files: {:?}", files);\n });\n\n // Create the main window\n let frame = Frame::builder()\n .with_title("My Application")\n .with_size(Size::new(800, 600))\n .build();\n\n frame.show(true);\n frame.centre();\n\n // wxWidgets manages frame lifetime after show()\n });\n} ``` -------------------------------- ### Initialize and Build wxDragon Project Source: https://github.com/allendang/wxdragon/blob/main/README.md Create a new project, add the wxdragon dependency, and build the application. ```bash # Clone and build cargo new my-gui-app cd my-gui-app # Add wxdragon to Cargo.toml cargo add wxdragon # Build (pre-built wxWidgets libraries will be downloaded automatically) cargo build # Run cargo run ``` -------------------------------- ### Create a simple GUI application Source: https://github.com/allendang/wxdragon/blob/main/README.md Programmatically build a window with a button using the builder pattern. ```rust use wxdragon::prelude::*; fn main() { SystemOptions::set_option_by_int("msw.no-manifest-check", 1); let _ = wxdragon::main(|_| { let frame = Frame::builder() .with_title("Hello, World!") .with_size(Size::new(300, 200)) .build(); let sizer = BoxSizer::builder(Orientation::Vertical).build(); let button = Button::builder(&frame).with_label("Click me").build(); button.on_click(|_| { println!("Button clicked"); }); sizer.add( &button, 1, SizerFlag::AlignCenterHorizontal | SizerFlag::AlignCenterVertical, 0, ); frame.set_sizer(sizer, true); frame.show(true); frame.centre(); }); } ``` -------------------------------- ### Create a Simple GUI Programmatically Source: https://github.com/allendang/wxdragon/blob/main/rust/wxdragon/README.md Build a basic window with a button using the programmatic builder pattern. ```rust use wxdragon::prelude::*; fn main() { let _ = wxdragon::main(|_| { let frame = Frame::builder() .with_title("Hello, World!") .with_size(Size::new(300, 200)) .build(); let sizer = BoxSizer::builder(Orientation::Vertical).build(); let button = Button::builder(&frame).with_label("Click me").build(); button.on_click(|_| { println!("Button clicked"); }); sizer.add( &button, 1, SizerFlag::AlignCenterHorizontal | SizerFlag::AlignCenterVertical, 0, ); frame.set_sizer(sizer, true); frame.show(true); frame.centre(); }); } ``` -------------------------------- ### Run Tab Order Demo Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/tab_order_demo/README.md Commands to execute the tab order demonstration application. ```bash cd examples/rust/tab_order_demo cargo run ``` -------------------------------- ### Enable Windows Theming with build.rs Source: https://github.com/allendang/wxdragon/blob/main/README.md Add this build script to your project root to enable native Windows theming, dark mode, high-DPI awareness, and UTF-8 support. It checks the target environment and embeds a manifest with specific settings. ```rust use embed_manifest::manifest::{ActiveCodePage, Setting, SupportedOS::*}; use embed_manifest::{embed_manifest, new_manifest}; fn main() { // Check if we're building for Windows (either natively or cross-compiling) let target = std::env::var("TARGET").unwrap_or_default(); if target.contains("windows") { // Create a comprehensive manifest for Windows theming and modern features let manifest = new_manifest("YourApp.Name") // Enable modern Windows Common Controls (v6) for theming .supported_os(Windows7..=Windows10) // Set UTF-8 as active code page for better Unicode support .active_code_page(ActiveCodePage::Utf8) // Enable heap type optimization for better performance (if available) .heap_type(embed_manifest::manifest::HeapType::SegmentHeap) // Enable high-DPI awareness for crisp displays .dpi_awareness(embed_manifest::manifest::DpiAwareness::PerMonitorV2) // Enable long path support (if configured in Windows) .long_path_aware(Setting::Enabled); // Embed the manifest - this works even when cross-compiling! if let Err(e) = embed_manifest(manifest) { println!("cargo:warning=Failed to embed manifest: {}", e); println!("cargo:warning=The application will still work but may lack optimal Windows theming"); } // Tell Cargo to rerun this build script if the build script changes println!("cargo:rerun-if-changed=build.rs"); } } ``` -------------------------------- ### Implement Notebook Tab Controls in Rust Source: https://context7.com/allendang/wxdragon/llms.txt Shows how to initialize a Notebook widget, add pages with icons, and handle page change events. ```rust use wxdragon::prelude::*; fn create_notebook_example(parent: &dyn WxWidget) { let notebook = Notebook::builder(parent).build(); // Create image list for tab icons let image_list = ImageList::new(16, 16, true, 3); if let Some(info_icon) = ArtProvider::get_bitmap(ArtId::Information, ArtClient::Menu, Some(Size::new(16, 16))) { image_list.add_bitmap(&info_icon); } notebook.set_image_list(image_list); // Create tab panels let tab1 = Panel::builder(¬ebook).build(); let label1 = StaticText::builder(&tab1).with_label("Content for Tab 1").build(); let sizer1 = BoxSizer::builder(Orientation::Vertical).build(); sizer1.add(&label1, 1, SizerFlag::Expand | SizerFlag::All, 10); tab1.set_sizer(sizer1, true); let tab2 = Panel::builder(¬ebook).build(); let button2 = Button::builder(&tab2).with_label("Button in Tab 2").build(); let sizer2 = BoxSizer::builder(Orientation::Vertical).build(); sizer2.add(&button2, 0, SizerFlag::All, 10); tab2.set_sizer(sizer2, true); // Add pages to notebook notebook.add_page(&tab1, "General", true, Some(0)); // Selected by default, with icon notebook.add_page(&tab2, "Settings", false, None); // Handle page change events notebook.on_page_changed(move |event| { let new_page = event.get_selection().unwrap_or(0); let old_page = event.get_old_selection().unwrap_or(0); println!("Switched from page {} to page {}", old_page, new_page); }); let main_sizer = BoxSizer::builder(Orientation::Vertical).build(); main_sizer.add(¬ebook, 1, SizerFlag::Expand | SizerFlag::All, 5); parent.set_sizer(main_sizer, true); } ``` -------------------------------- ### Build Project with MSVC Source: https://github.com/allendang/wxdragon/blob/main/README.md Standard build command for projects using MSVC on Windows. ```bash cargo build ``` -------------------------------- ### Get Raw Window Style Flags Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Retrieve the current window style flags as a raw i64 value using `get_style_raw`. This is useful for debugging or when interacting with C APIs. ```rust let raw_style = widget.get_style_raw(); ``` -------------------------------- ### Create Buttons and Event Handlers in Rust Source: https://context7.com/allendang/wxdragon/llms.txt Demonstrates how to build standard buttons, toggle buttons, and buttons with bitmap icons using the builder pattern. Widgets implement Copy, allowing them to be captured in closures without explicit cloning. ```rust use wxdragon::prelude::*; fn create_buttons(parent: &dyn WxWidget) { let panel = Panel::builder(parent).build(); let sizer = BoxSizer::builder(Orientation::Vertical).build(); // Simple button with click handler let button = Button::builder(&panel) .with_label("Click Me") .with_size(Size::new(120, 40)) .build(); // Widgets are Copy - no clone needed! button.on_click(move |_event| { println!("Button clicked!"); button.set_label("Clicked!"); }); // Button with bitmap using ArtProvider let icon_button = Button::builder(&panel) .with_label("Open") .build(); if let Some(bitmap) = ArtProvider::get_bitmap(ArtId::FileOpen, ArtClient::Button, None) { icon_button.set_bitmap(&bitmap, ButtonBitmapPosition::Left); } // Toggle button let toggle = ToggleButton::builder(&panel) .with_label("Toggle Feature") .build(); toggle.on_toggle(move |event| { let is_pressed = event.is_checked().unwrap_or(false); println!("Toggle state: {}", if is_pressed { "ON" } else { "OFF" }); }); sizer.add(&button, 0, SizerFlag::All, 5); sizer.add(&icon_button, 0, SizerFlag::All, 5); sizer.add(&toggle, 0, SizerFlag::All, 5); panel.set_sizer(sizer, true); } ``` -------------------------------- ### Get Window Style via C API Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Retrieve the current window style flags as a raw i64 value using the C API function `wxd_Window_GetWindowStyle`. This is useful for interoperability with C code. ```c i64 style = wxd_Window_GetWindowStyle(window_ptr); ``` -------------------------------- ### Tokio Async Demo with Idle Event Control Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Demonstrates async runtime integration using tokio channels with the GUI. It shows efficient idle event usage with `request_more()` for optimal CPU usage and `ProcessSpecified` idle mode with per-window control. ```rust tokio_async_demo ``` -------------------------------- ### Add wxdragon-sys dependency Source: https://github.com/allendang/wxdragon/blob/main/rust/wxdragon-sys/README.md Include this crate in your Cargo.toml to access raw FFI bindings for wxWidgets. ```toml [dependencies] wxdragon-sys = "0.1.0" # Replace with the desired version from crates.io ``` -------------------------------- ### Construct Frames and Menus with Builders Source: https://context7.com/allendang/wxdragon/llms.txt Create complex window layouts including menu bars and status bars using the fluent builder pattern. ```rust use wxdragon::prelude::*;\n\nfn create_main_frame() {\n let frame = Frame::builder()\n .with_title("wxDragon Application")\n .with_size(Size::new(1024, 768))\n .with_style(FrameStyle::DefaultFrameStyle)\n .build();\n\n // Create menu bar\n let file_menu = Menu::builder()\n .append_item(ID_EXIT, "E&xit\tAlt-X", "Quit the application")\n .build();\n let help_menu = Menu::builder()\n .append_item(ID_ABOUT, "&About...", "Show about dialog")\n .build();\n let menubar = MenuBar::builder()\n .append(file_menu, "&File")\n .append(help_menu, "&Help")\n .build();\n frame.set_menu_bar(menubar);\n\n // Create status bar with 3 fields\n StatusBar::builder(&frame)\n .with_fields_count(3)\n .with_status_widths(vec![-1, 150, 100])\n .add_initial_text(0, "Ready")\n .build();\n\n // Handle menu events\n frame.on_menu(move |event| {\n match event.get_id() {\n id if id == ID_EXIT => frame.close(true),\n id if id == ID_ABOUT => {\n show_about_box(AboutDialogInfo::new()\n .with_name("My App")\n .with_version("1.0.0")\n .with_description("A wxDragon application"));\n }\n _ => event.skip(true),\n }\n });\n\n frame.show(true);\n frame.centre();\n} ``` -------------------------------- ### Build and Use a Custom Widget in Rust Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Shows how to instantiate, configure, and integrate a custom widget into the application layout, including binding external events. ```rust let my_widget = MyCustomWidget::builder(&parent) .with_text("Hello World!".to_string()) .with_background_color(Colour::new(200, 200, 255, 255)) .with_size(Size::new(200, 100)) .build(); // Add to layout sizer.add(&my_widget, 0, SizerFlag::All, 10); // Bind external events my_widget.on_mouse_left_down(|event| { println!("Widget was clicked!"); event.skip(true); }); ``` -------------------------------- ### Create UI Layouts with Sizers in Rust Source: https://context7.com/allendang/wxdragon/llms.txt Demonstrates the use of BoxSizer, FlexGridSizer, and GridBagSizer to organize widgets within a parent container. ```rust use wxdragon::prelude::*; fn create_layout_example(parent: &dyn WxWidget) { // Vertical box sizer let main_sizer = BoxSizer::builder(Orientation::Vertical).build(); // Horizontal row with buttons let button_row = BoxSizer::builder(Orientation::Horizontal).build(); let btn1 = Button::builder(parent).with_label("Button 1").build(); let btn2 = Button::builder(parent).with_label("Button 2").build(); let btn3 = Button::builder(parent).with_label("Button 3").build(); button_row.add(&btn1, 1, SizerFlag::Expand | SizerFlag::All, 5); button_row.add(&btn2, 1, SizerFlag::Expand | SizerFlag::All, 5); button_row.add(&btn3, 1, SizerFlag::Expand | SizerFlag::All, 5); // Flex grid sizer for form layout let form_sizer = FlexGridSizer::builder() .with_cols(2) .with_vgap(5) .with_hgap(10) .build(); form_sizer.add_growable_col(1, 1); // Second column expands let label1 = StaticText::builder(parent).with_label("Name:").build(); let input1 = TextCtrl::builder(parent).build(); let label2 = StaticText::builder(parent).with_label("Email:").build(); let input2 = TextCtrl::builder(parent).build(); form_sizer.add(&label1, 0, SizerFlag::AlignRight | SizerFlag::AlignCenterVertical, 0); form_sizer.add(&input1, 1, SizerFlag::Expand, 0); form_sizer.add(&label2, 0, SizerFlag::AlignRight | SizerFlag::AlignCenterVertical, 0); form_sizer.add(&input2, 1, SizerFlag::Expand, 0); // Grid bag sizer for precise positioning let grid_bag = GridBagSizer::builder() .with_vgap(5) .with_hgap(5) .build(); let wide_button = Button::builder(parent).with_label("Spans 2 columns").build(); grid_bag.add(&wide_button, GBPosition::new(0, 0), GBSpan::new(1, 2), SizerFlag::Expand, 0); // Combine all sizers main_sizer.add_sizer(&button_row, 0, SizerFlag::Expand | SizerFlag::All, 10); main_sizer.add_sizer(&form_sizer, 0, SizerFlag::Expand | SizerFlag::All, 10); main_sizer.add_sizer(&grid_bag, 0, SizerFlag::Expand | SizerFlag::All, 10); main_sizer.add_stretch_spacer(1); parent.set_sizer(main_sizer, true); } ``` -------------------------------- ### Menu System Integration for TaskBarIcon Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Enhanced Menu widget with `from_ptr()` method for FFI pointer conversion, enabling seamless integration with TaskBarIcon popup menus and existing event handling. ```python - Added `from_ptr()` method to Menu for FFI pointer conversion support - Seamless integration between TaskBarIcon popup menus and existing menu event handling ``` -------------------------------- ### Add wxDragon dependency Source: https://github.com/allendang/wxdragon/blob/main/README.md Include the wxdragon crate in your Cargo.toml file. ```toml [dependencies] wxdragon = "*" ``` -------------------------------- ### Create Text and Numeric Input Widgets in Rust Source: https://context7.com/allendang/wxdragon/llms.txt Shows how to implement single-line, multi-line, search, and spin controls. These widgets support event listeners for tracking user input changes. ```rust use wxdragon::prelude::*; fn create_text_inputs(parent: &dyn WxWidget) { let sizer = BoxSizer::builder(Orientation::Vertical).build(); // Single-line text control let text_input = TextCtrl::builder(parent) .with_value("Enter text here...") .with_size(Size::new(200, -1)) .build(); text_input.on_text_updated(move |_event| { let value = text_input.get_value(); println!("Text changed: {}", value); }); // Multi-line text control let multiline = TextCtrl::builder(parent) .with_style(TextCtrlStyle::MultiLine | TextCtrlStyle::WordWrap) .with_size(Size::new(300, 150)) .build(); multiline.set_value("This is a multi-line\ntext control with\nword wrapping enabled."); // Search control with search button let search = SearchCtrl::builder(parent) .with_size(Size::new(200, -1)) .build(); search.on_search_button_clicked(move |_event| { let query = search.get_value(); println!("Searching for: {}", query); }); // Spin control for numeric input let spin = SpinCtrl::builder(parent) .with_range(0, 100) .with_initial_value(50) .build(); spin.on_value_changed(move |event| { println!("Spin value: {}", event.get_value()); }); sizer.add(&text_input, 0, SizerFlag::Expand | SizerFlag::All, 5); sizer.add(&multiline, 1, SizerFlag::Expand | SizerFlag::All, 5); sizer.add(&search, 0, SizerFlag::Expand | SizerFlag::All, 5); sizer.add(&spin, 0, SizerFlag::All, 5); parent.set_sizer(sizer, true); } ``` -------------------------------- ### Configure CMake for wxWidgets Source: https://github.com/allendang/wxdragon/blob/main/examples/cpp/minimal_cpp/CMakeLists.txt Sets up the project environment, defines wxWidgets build paths, and configures the executable for cross-platform support. ```cmake cmake_minimum_required(VERSION 3.16) project(taskbar_test) # Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(WXWIDGETS_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../target/debug/wxWidgets CACHE PATH "Path to the wxWidgets libraries") message(STATUS "Using wxWidgets libraries source from: ${WXWIDGETS_LIB_DIR}") # wxWidgets build directory set(WXWIDGETS_BUILD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../target/wxwidgets_cmake_build CACHE PATH "Path to the wxWidgets build directory") message(STATUS "Building wxWidgets binaries to: ${WXWIDGETS_BUILD_DIR}") set(wxBUILD_SHARED OFF CACHE BOOL "Build wxWidgets as static libraries") set(wxBUILD_MONOLITHIC OFF CACHE BOOL "Build wxWidgets as monolithic library") set(wxBUILD_SAMPLES OFF CACHE BOOL "Do not build wxWidgets samples") set(wxBUILD_TESTS OFF CACHE BOOL "Do not build wxWidgets tests") set(wxBUILD_DEMOS OFF CACHE BOOL "Do not build wxWidgets demos") set(wxBUILD_BENCHMARKS OFF CACHE BOOL "Do not build wxWidgets benchmarks") set(wxUSE_EXCEPTIONS ON CACHE BOOL "Enable wxWidgets exceptions") add_subdirectory(${WXWIDGETS_LIB_DIR} ${WXWIDGETS_BUILD_DIR}) if(CMAKE_SYSTEM_NAME MATCHES Darwin) set(COMPILE_OPTIONS "MACOSX_BUNDLE") elseif(CMAKE_SYSTEM_NAME MATCHES Windows) set(COMPILE_OPTIONS "WIN32") elseif(CMAKE_SYSTEM_NAME MATCHES Linux) set(COMPILE_OPTIONS "") else() message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() add_executable(taskbar_test ${COMPILE_OPTIONS} main.cpp) target_link_libraries(taskbar_test PRIVATE wx::base wx::core) # target_link_libraries(taskbar_test PRIVATE wx::adv wx::aui wx::gl wx::html wx::media wx::net wx::propgrid) # target_link_libraries(taskbar_test PRIVATE wx::qa wx::ribbon wx::richtext wx::stc wx::webview wx::xrc wx::xml) # On macOS, create an app bundle if(APPLE) set_target_properties(taskbar_test PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" ) endif() message(STATUS "taskbar_test configured successfully") ``` -------------------------------- ### Bind toolbar and menu events Source: https://github.com/allendang/wxdragon/blob/main/docs/events.md Shows how to bind events to toolbar tools or specific menu IDs. ```rust use wxdragon::event::EventType; let tool = toolbar.find_tool("open"); // example; adjust to your API let _tok = tool.on_click(|_e| { // On Windows it goes through MENU; on macOS/Linux it goes through TOOL }); let _menu_tok = frame.bind_with_id_internal(EventType::MENU, MY_ID, |_e| { // Bind a specific menu/tool event by ID }); ``` -------------------------------- ### Build for Windows 7 Targets Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Commands for building the project for Windows 7 using direct target specification or environment variable overrides. ```bash cargo build --target i686-win7-windows-msvc ``` ```bash WXDRAGON_TARGET_OVERRIDE=i686-win7-windows-msvc cargo build --target i686-pc-windows-msvc ``` -------------------------------- ### Define UI with XRC Source: https://github.com/allendang/wxdragon/blob/main/README.md Create a layout using XML resources for visual UI design. ```xml wxDragon XRC Demo 400,300 50,50 Enter text here... 50,100 200,25 50,150 ``` -------------------------------- ### TaskBarIcon Widget Implementation Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Introduces a cross-platform TaskBarIcon widget for system tray integration. It supports platform-aware implementations, automatic popup menus, and a comprehensive event system. ```python **TaskBarIcon Widget**: Added comprehensive system tray/taskbar icon widget with full cross-platform support - **Platform-Aware Implementation**: Intelligent platform detection for optimal user experience - **Windows**: Shows in system tray (notification area) with full event support - **macOS**: Shows in dock or menu bar (CustomStatusItem) with native click behavior - **Linux**: Shows in system tray with GTK backend integration (varies by desktop environment) - **Icon Type Management**: Flexible icon type configuration with `TaskBarIconType` enum - `Default`: Platform-appropriate default behavior (CustomStatusItem on macOS, Dock elsewhere) - `Dock`: Traditional dock icon placement (typically macOS dock) - `CustomStatusItem`: Menu bar/system tray placement (macOS menu bar, Windows system tray) - **Automatic Popup Menus**: Native popup menu functionality using wxWidgets' `CreatePopupMenu()` override - `set_popup_menu()` and `get_popup_menu()` methods for menu management - Automatic menu display when taskbar icon is clicked (platform-specific behavior) - Menu creates copies for wxWidgets ownership while preserving original template - **Event Handling System**: Comprehensive event system with platform-specific conditional compilation - Menu events handled directly by TaskBarIcon via `on_menu()` method (not routed to parent frame) - Cross-platform basic events: left click, double-click (Windows/Linux only) - Windows-specific events: mouse movement, right-click, balloon tooltips with proper conditional compilation - Platform events gracefully degrade on unsupported platforms (return `wxEVT_NULL`) - **Builder Pattern Integration**: Full wxDragon builder pattern with fluent API - `with_icon_type()`, `with_icon()`, `with_icon_bundle()`, `with_tooltip()` configuration methods - Immediate icon setting during construction for streamlined initialization ``` -------------------------------- ### Create a custom button widget Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/custom_widget/README.md Implements a button with state-dependent styling and mouse interaction using the custom_widget! macro. ```rust custom_widget!( name: SimpleButton, fields: { text: String = "Click Me".to_string(), is_pressed: bool = false, }, setup_impl: |config, panel| { panel.set_background_style(BackgroundStyle::Paint); let pressed_state = Rc::new(RefCell::new(false)); // Draw the button let config_paint = config.clone(); let pressed_paint = pressed_state.clone(); panel.on_paint(move |event| { let dc = AutoBufferedPaintDC::new(&panel); let size = panel.get_size(); let is_pressed = *pressed_paint.borrow(); // Choose colors based on state let bg_color = if is_pressed { Colour::new(180, 180, 180, 255) } else { Colour::new(220, 220, 220, 255) }; // Draw background dc.set_brush(bg_color, BrushStyle::Solid); dc.draw_rectangle(0, 0, size.width, size.height); // Draw text dc.set_text_foreground(Colour::new(0, 0, 0, 255)); let text_size = dc.get_text_extent(&config_paint.text); let x = (size.width - text_size.0) / 2; let y = (size.height - text_size.1) / 2; dc.draw_text(&config_paint.text, x, y); event.skip(true); }); // Handle mouse press let pressed_down = pressed_state.clone(); panel.on_mouse_left_down(move |event| { *pressed_down.borrow_mut() = true; panel.refresh(false, None); event.skip(true); }); // Handle mouse release let pressed_up = pressed_state.clone(); panel.on_mouse_left_up(move |event| { *pressed_up.borrow_mut() = false; panel.refresh(false, None); event.skip(true); }); } ); ``` -------------------------------- ### Create Custom Widgets with wxdragon Source: https://context7.com/allendang/wxdragon/llms.txt Define custom widgets using the custom_widget! macro and handle paint events with AutoBufferedPaintDC for custom drawing. Use a builder pattern for widget instantiation. ```rust use wxdragon::prelude::*; // Define a custom widget using the custom_widget! macro custom_widget!( /// A simple custom button with animated fill effect struct MyCustomWidget { base: Panel, label: String, hover_progress: f32, } ); impl MyCustomWidget { pub fn builder(parent: &dyn WxWidget) -> MyCustomWidgetBuilder { MyCustomWidgetBuilder::new(parent) } fn new(parent: &dyn WxWidget, label: String, size: Size) -> Self { let panel = Panel::builder(parent) .with_size(size) .with_style(PanelStyle::FullRepaintOnResize) .build(); let widget = Self { base: panel, label, hover_progress: 0.0, }; // Handle paint event panel.on_paint(move |_| { let dc = AutoBufferedPaintDC::new(&panel); // Draw background dc.set_brush(BrushStyle::Solid, Colour::new(240, 240, 240)); let size = panel.get_size(); dc.draw_rectangle(0, 0, size.width, size.height); // Draw border dc.set_pen(PenStyle::Solid, 1, Colour::new(100, 100, 100)); dc.draw_rectangle(0, 0, size.width - 1, size.height - 1); // Draw text centered dc.set_text_foreground(Colour::new(0, 0, 0)); let (text_width, text_height) = dc.get_text_extent("Custom Widget"); let x = (size.width - text_width) / 2; let y = (size.height - text_height) / 2; dc.draw_text("Custom Widget", x, y); }); widget } } pub struct MyCustomWidgetBuilder<'a> { parent: &'a dyn WxWidget, label: String, size: Size, } impl<'a> MyCustomWidgetBuilder<'a> { pub fn new(parent: &'a dyn WxWidget) -> Self { Self { parent, label: String::new(), size: Size::new(100, 50), } } pub fn with_label(mut self, label: &str) -> Self { self.label = label.to_string(); self } pub fn with_size(mut self, size: Size) -> Self { self.size = size; self } pub fn build(self) -> MyCustomWidget { MyCustomWidget::new(self.parent, self.label, self.size) } } ``` -------------------------------- ### Implement Embedded XRC UI Source: https://github.com/allendang/wxdragon/blob/main/examples/rust/simple_xrc_test/README.md Demonstrates defining a UI struct from an embedded XRC file and initializing it within the main application loop. ```rust // Define the UI struct from embedded XRC wxdragon::include_xrc!("ui.xrc", MyUI); fn main() { wxdragon::main(|_| { // Create UI from embedded XRC let ui = MyUI::new(); // Access the embedded XRC data println!("XRC size: {} bytes", MyUI::XRC_DATA.len()); ui.button.on_click(|_| { // add event logic }); ui.main_frame.show(true); }); } ``` -------------------------------- ### Configure DataViewCtrl in Rust Source: https://context7.com/allendang/wxdragon/llms.txt Create a DataViewCtrl with custom columns and event handlers for selection, activation, and context menus. ```rust use wxdragon::prelude::*; use std::rc::Rc; use std::cell::RefCell; fn create_dataview_example(parent: &dyn WxWidget) { let dataview = DataViewCtrl::builder(parent) .with_size(Size::new(500, 300)) .with_style(DataViewStyle::RowLines | DataViewStyle::VerticalRules) .build(); // Create columns with text renderers let col1 = DataViewColumn::new( "Name", &DataViewTextRenderer::new(VariantType::String, DataViewCellMode::Inert, DataViewAlign::Left), 0, // model column index 200, DataViewAlign::Left, DataViewColumnFlags::Resizable | DataViewColumnFlags::Sortable, ); let col2 = DataViewColumn::new( "Value", &DataViewTextRenderer::new(VariantType::String, DataViewCellMode::Inert, DataViewAlign::Left), 1, 150, DataViewAlign::Left, DataViewColumnFlags::Resizable, ); dataview.append_column(&col1); dataview.append_column(&col2); // Handle selection changes dataview.on_selection_changed(move |event| { if let Some(item) = event.get_item() { println!("Selected item changed"); } }); // Handle double-click activation dataview.on_item_activated(move |event| { if let Some(item) = event.get_item() { println!("Item double-clicked"); } }); // Context menu on right-click dataview.on_item_context_menu(move |event| { if let Some(item) = event.get_item() { let mut menu = Menu::builder() .append_item(ID_HIGHEST + 1, "Edit", "Edit this item") .append_item(ID_HIGHEST + 2, "Delete", "Delete this item") .build(); menu.on_selected(move |ev| { match ev.get_id() { id if id == ID_HIGHEST + 1 => println!("Edit selected"), id if id == ID_HIGHEST + 2 => println!("Delete selected"), _ => {} } }); dataview.popup_menu(&mut menu, event.get_position()); } }); } ``` -------------------------------- ### Configure MinGW Linker on Windows Source: https://github.com/allendang/wxdragon/blob/main/README.md Set the environment variable for the Rust linker when using the WinLibs GCC toolchain. ```bash setx CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER "C:\mingw64\mingw64\bin\gcc.exe" ``` -------------------------------- ### Event Propagation and Consumption Source: https://github.com/allendang/wxdragon/blob/main/docs/events.md Demonstrates how to control event propagation by calling skip(false) to consume an event or allowing default behavior to continue. ```rust event.skip(false) ``` ```rust event.skip(true) ``` -------------------------------- ### Implement File Dialogs in Rust Source: https://context7.com/allendang/wxdragon/llms.txt Use FileDialog to handle opening single files, multiple files, or saving files with specific wildcards and styles. ```rust use wxdragon::prelude::*; fn show_file_dialogs(parent: &dyn WxWidget) { // Open file dialog let open_dialog = FileDialog::builder(parent) .with_message("Select a file to open") .with_default_dir("/home/user/documents") .with_wildcard("Text files (*.txt)|*.txt|All files (*.*)|*.*") .with_style(FileDialogStyle::Open | FileDialogStyle::FileMustExist) .build(); if open_dialog.show_modal() == ID_OK { if let Some(path) = open_dialog.get_path() { println!("Selected file: {}", path); } } // Open multiple files let multi_dialog = FileDialog::builder(parent) .with_message("Select files") .with_wildcard("Images (*.png;*.jpg)|*.png;*.jpg") .with_style(FileDialogStyle::Open | FileDialogStyle::Multiple) .build(); if multi_dialog.show_modal() == ID_OK { let files = multi_dialog.get_paths(); for file in files { println!("Selected: {}", file); } } // Save file dialog let save_dialog = FileDialog::builder(parent) .with_message("Save file as") .with_default_file("document.txt") .with_wildcard("Text files (*.txt)|*.txt") .with_style(FileDialogStyle::Save | FileDialogStyle::OverwritePrompt) .build(); if save_dialog.show_modal() == ID_OK { if let Some(path) = save_dialog.get_path() { println!("Saving to: {}", path); } } } ``` -------------------------------- ### TaskBarIcon Platform Support Details Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Details the TaskBarIcon support across Windows, macOS, and Linux, including specific features like balloon tooltips on Windows and menu bar integration on macOS. ```markdown - ✅ **Windows (MSVC/MinGW)**: Complete system tray support with balloon tooltips and full event system - ✅ **macOS**: Native menu bar integration with CustomStatusItem support and automatic popup menus - ✅ **Linux (GTK)**: System tray integration with desktop environment compatibility - ✅ **Cross-Compilation**: Fixed Windows cross-compilation from macOS with proper event constant handling ``` -------------------------------- ### Configure Git Proxy Source: https://github.com/allendang/wxdragon/blob/main/README.md Set a global HTTP proxy for git to resolve connectivity issues when downloading dependencies from GitHub. ```bash git config --global http.proxy http://your-proxy:port ``` -------------------------------- ### Add Window Styles Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Employ the `add_style` method to incorporate new `WindowStyle` flags into the existing window style. This operation preserves all previously set styles. ```rust widget.add_style(WindowStyle::MINIMIZE_BOX); ``` -------------------------------- ### Window Style Management API Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Methods provided by the WxWidget trait to manage window styles. ```APIDOC ## Window Style Management API ### Description Methods for managing window style flags on widgets, supporting type-safe bitwise operations. ### Methods - **set_style(style: WindowStyle)**: Sets window style flags. - **set_style_raw(style: i64)**: Sets raw style flags for advanced usage. - **get_style_raw() -> i64**: Returns current style flags as a raw value. - **has_style(style: WindowStyle) -> bool**: Checks if specific style flags are set. - **add_style(style: WindowStyle)**: Adds styles while preserving existing ones. - **remove_style(style: WindowStyle)**: Removes specific styles without affecting others. ``` -------------------------------- ### Cross-Platform FFI Layer Enhancements Source: https://github.com/allendang/wxdragon/blob/main/CHANGELOG.md Improved C++ binding layer with robust platform detection, custom `wxdTaskBarIcon` class, intelligent icon type selection, and enhanced event mapping for better cross-platform compatibility. ```cpp // TaskBarIcon C++ Class: Custom `wxdTaskBarIcon` class extending `wxTaskBarIcon` with automatic popup menu support // Platform-Specific Icon Type Mapping: Intelligent default icon type selection based on platform capabilities // Event Type Safety: Enhanced event mapping with individual constant checking to prevent compilation errors // Memory Management: Proper menu copying and ownership handling for wxWidgets integration ```