diff --git a/.gitignore b/.gitignore index 87d81c7..32a0705 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,13 @@ -# 编译生成文件 -*.exe -*.ilk -*.obj -*.pdb -*.o -*.a -*.lib -*.dll -*.exp -*.so -*.dylib +# 编译输出目录 +/build/ +/bin/ +/lib/ -# 构建目录 -build/ -bin/ -obj/ -Debug/ -Release/ -x64/ -x86/ -Win32/ +# CMake 生成文件 +/CMakeFiles/ +/CMakeCache.txt +/cmake_install.cmake +/Makefile # Visual Studio 文件 .vs/ @@ -27,51 +15,15 @@ Win32/ *.vcxproj *.vcxproj.filters *.vcxproj.user -*.suo -*.ncb -*.user -*.sdf -ipch/ -*.aps -*.res -*.tlog -*.lastbuildstate -*.idb -*.pch -# CMake 生成文件 -CMakeFiles/ -CMakeCache.txt -cmake_install.cmake -Makefile -*.cmake -*.cmake.* -CTestTestfile.cmake -Testing/ -_deps/ - -# 文档生成 -docs/html/ -docs/latex/ -docs/man/ -docs/rtf/ -docs/xml/ +# 编译产物 +*.obj +*.pdb +*.log +*.exe +*.dll +*.lib # 临时文件 -*.tmp -*.temp -*.log -*.swp -*.swo - -# EasyX 临时文件 -*.jpg -*.bmp -*.png -*.tga - -# 其他 -.DS_Store -Thumbs.db -ehthumbs.db -Desktop.ini \ No newline at end of file +*.cache +*.zip diff --git a/CHANGELOG.md b/CHANGELOG.md index 17aa46e..98f0255 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,104 @@ StellarX 项目所有显著的变化都将被记录在这个文件中。 格式基于 [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 并且本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。 + + +## [v2.0.0] - 2025-09-21 + +### 概述 +v2.0.0 为一次重大升级(major release)。本次发布新增对话框与消息框工厂(Dialog / MessageBox),并对事件分发、API语义与内部资源管理做了若干重要修复和改进。 + +部分 API/行为发生不向后兼容的变化(breaking changes)。 + +### 新增 +- **对话框系统**: + - 新增 `Dialog` 类,继承自 `Canvas`,用于构建模态与非模态对话框 + - 新增 `MessageBox` 工厂类,提供 `ShowModal`(同步阻塞)与 `ShowAsync`(异步回调)两种便捷API + - 支持六种标准消息框类型:`OK`, `OKCancel`, `YesNo`, `YesNoCancel`, `RetryCancel`, `AbortRetryIgnore` + - 自动处理对话框布局、背景保存与恢复、事件传播和生命周期管理 + +- **事件系统增强**: + - 所有控件的 `handleEvent` 方法现在返回 `bool` 类型,表示是否消费了事件 + - 引入事件消费机制,支持更精细的事件传播控制 + - Window 类的事件循环现在优先处理对话框事件 + +- **控件状态管理**: + - Control 基类新增 `dirty` 标志和 `setDirty()` 方法,统一管理重绘状态 + - 所有控件现在都实现了 `IsVisible()` 和 `model()` 方法 + +- **API 增强**: + - Button 类新增 `setButtonFalseColor()` 方法 + - TextBox 类的 `setMaxCharLen()` 现在接受 `size_t` 类型参数 + - Window 类新增对话框管理方法和去重检测机制 + +### 重大变更(Breaking Changes) +- **API 签名变更**: + - 所有控件的 `handleEvent(const ExMessage& msg)` 方法从返回 `void` 改为返回 `bool` + - Control 基类新增纯虚函数 `IsVisible() const` 和 `model() const`,所有派生类必须实现 + +- **资源管理变更**: + - Control 基类的样式保存从栈对象改为堆对象,使用指针管理 + - 增强了资源释放的安全性,所有资源都在析构函数中正确释放 + +- **事件处理逻辑**: + - Window 的 `runEventLoop()` 方法完全重写,现在优先处理对话框事件 + - 引入了事件消费机制,事件被消费后不会继续传播 + +### 修复(Fixed) +- **内存管理**: + - 修复 `Button::setFillIma()` 的内存泄漏问题 + - 修复 Control 基类析构函数中的资源释放问题 + - 修复 Dialog 类背景图像资源管理问题 + +- **布局与渲染**: + - 修复 `Table` 组件的分页计算、列宽和行高越界问题 + - 修复 `Table` 中 `pX` 坐标累加错误导致的布局错乱 + - 修复 `Canvas::draw()` 中导致子控件不被绘制的 dirty 判定问题 + - 修复 `TextBox::draw()` 和 `restoreStyle()` 的不对称调用问题 + +- **事件处理**: + - 修复窗口事件分发逻辑,确保对话框/顶层控件优先处理事件 + - 修复鼠标移出按钮区域时状态更新不及时的问题 + - 修复非模态对话框事件处理中的竞争条件 + +- **其他问题**: + - 修复文本测量和渲染中的潜在错误 + - 修复对话框关闭后背景恢复不完全的问题 + - 修复多对话框场景下的 z-order 管理问题 + +### 改进(Changed) +- **代码质量**: + - 重构了大量内部 API,增强异常安全性与可维护性 + - 使用智能指针和现代 C++ 特性替代裸 new/delete + - 统一了代码风格和命名约定 + +- **性能优化**: + - 优化了事件处理流程,减少不必要的重绘 + - 改进了对话框背景保存和恢复机制 + - 减少了内存分配和拷贝操作 + +- **文档与示例**: + - 为所有新增功能添加了详细的使用示例 + - 完善了代码注释和 API 文档 + - 更新了 README 和 CHANGELOG 反映最新变化 + +## [1.1.0] - 2025-09-08 + +### 新增 +- **Window 类 API 增强**: + - 添加了完整的获取器(getter)方法集,提高类的封装性和可用性 + - `getHwnd()` - 获取窗口句柄,便于与原生 Windows API 集成 + - `getWidth()` - 获取窗口宽度 + - `getHeight()` - 获取窗口高度 + - `getHeadline()` - 获取窗口标题 + - `getBkcolor()` - 获取窗口背景颜色 + - `getBkImage()` - 获取窗口背景图片指针 + - `getControls()` - 获取控件管理容器的引用,允许迭代和操作已添加的控件 + +### 改进 +- **API 一致性**: 为所有重要属性提供了对称的设置器(setter)和获取器(getter)方法 +- **代码文档**: 进一步完善了类注释,使其更加清晰和专业 + ## [1.0.0] - 2025-09-08 ### 发布摘要 diff --git a/CMakeLists.txt b/CMakeLists.txt index d9f20ed..fe9be7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,130 +1,19 @@ -cmake_minimum_required(VERSION 3.15) -project(StellarX VERSION 1.0.0 LANGUAGES CXX) +cmake_minimum_required(VERSION 3.10) -# 设置C++标准 +# 项目定义 +project(StellarX VERSION 2.0.0 LANGUAGES CXX) + +# 设置 C++ 标准 set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED True) -# Windows特定设置 -if(WIN32) - add_definitions(-DWIN32 -D_WINDOWS) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) - - # 设置Windows子系统 - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS") -endif() +# 包含头文件目录(目前头文件都在根目录) +include_directories(${CMAKE_SOURCE_DIR}) -# 设置输出目录 -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - -# 包含目录 -include_directories(include) - -# Windows API库 -if(WIN32) - find_library(GDI32_LIBRARY gdi32) - find_library(USER32_LIBRARY user32) - find_library(KERNEL32_LIBRARY kernel32) - set(WIN32_LIBS ${GDI32_LIBRARY} ${USER32_LIBRARY} ${KERNEL32_LIBRARY}) -endif() - -# 创建库 -file(GLOB_RECURSE SOURCES "src/*.cpp") -add_library(StellarX STATIC ${SOURCES}) - -# 链接Windows库 -if(WIN32) - target_link_libraries(StellarX ${WIN32_LIBS}) -endif() - -# 设置库属性 -set_target_properties(StellarX PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION 1 - PUBLIC_HEADER "include/StellarX/StellarX.h" - OUTPUT_NAME "StellarX" +# 源文件收集 +file(GLOB_RECURSE SOURCES + "${CMAKE_SOURCE_DIR}/*.cpp" ) -# 安装规则 -install(DIRECTORY include/StellarX DESTINATION include) -install(TARGETS StellarX - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin - PUBLIC_HEADER DESTINATION include/StellarX -) - -# 示例程序 -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/examples) - file(GLOB EXAMPLE_SOURCES "examples/*.cpp") - foreach(example_source ${EXAMPLE_SOURCES}) - get_filename_component(example_name ${example_source} NAME_WE) - add_executable(${example_name} ${example_source}) - target_link_libraries(${example_name} StellarX ${WIN32_LIBS}) - - # 设置Windows子系统 - if(WIN32) - set_target_properties(${example_name} PROPERTIES - LINK_FLAGS "/SUBSYSTEM:WINDOWS" - ) - endif() - - # 安装示例 - install(TARGETS ${example_name} DESTINATION bin) - endforeach() -endif() - -# 文档生成选项 -option(BUILD_DOCS "Build documentation" OFF) -if(BUILD_DOCS) - find_package(Doxygen) - if(Doxygen_FOUND) - set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/docs) - set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${CMAKE_CURRENT_SOURCE_DIR}/README.md) - set(DOXYGEN_PROJECT_NAME "StellarX GUI Framework") - set(DOXYGEN_PROJECT_NUMBER ${PROJECT_VERSION}) - set(DOXYGEN_PROJECT_BRIEF "A lightweight, modular C++ GUI framework for Windows") - set(DOXYGEN_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src) - set(DOXYGEN_RECURSIVE YES) - set(DOXYGEN_EXTRACT_ALL YES) - set(DOXYGEN_EXTRACT_PRIVATE YES) - set(DOXYGEN_EXTRACT_STATIC YES) - set(DOXYGEN_SOURCE_BROWSER YES) - set(DOXYGEN_GENERATE_TREEVIEW YES) - set(DOXYGEN_HAVE_DOT YES) - set(DOXYGEN_CALL_GRAPH YES) - set(DOXYGEN_CALLER_GRAPH YES) - - doxygen_add_docs( - docs - ${DOXYGEN_INPUT} - COMMENT "Generate HTML documentation" - ) - - install(DIRECTORY ${DOXYGEN_OUTPUT_DIRECTORY}/html DESTINATION docs) - endif() -endif() - -# 打包配置 -include(InstallRequiredSystemLibraries) -set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) -set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) -set(CPACK_PACKAGE_DESCRIPTION "A lightweight, modular C++ GUI framework for Windows") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "星垣 (StellarX) - A lightweight Windows GUI framework") -set(CPACK_PACKAGE_VENDOR "StellarX Development Team") -set(CPACK_PACKAGE_CONTACT "contact@stellarx.dev") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") -set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") -set(CPACK_PACKAGE_INSTALL_DIRECTORY "StellarX") -set(CPACK_NSIS_MODIFY_PATH ON) - -if(WIN32) - set(CPACK_GENERATOR "ZIP;NSIS") -else() - set(CPACK_GENERATOR "ZIP") -endif() - -include(CPack) \ No newline at end of file +# 生成可执行文件 +add_executable(StellarX ${SOURCES}) diff --git a/README.md b/README.md index 7d61e59..54bcc69 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # 星垣 (StellarX) GUI Framework -![Version](https://img.shields.io/badge/Version-1.0.0-brightgreen.svg) -![Download](https://img.shields.io/badge/Download-1.0.0_Release-blue.svg) +![Version](https://img.shields.io/badge/Version-2.0.0-brightgreen.svg) +![Download](https://img.shields.io/badge/Download-1.0.0_Release-blue.svg) ![C++](https://img.shields.io/badge/C++-17+-00599C?logo=cplusplus&logoColor=white) ![Windows](https://img.shields.io/badge/Platform-Windows-0078D6?logo=windows) @@ -22,7 +22,7 @@ 星垣框架采用经典的**面向对象**和**模块化**设计,项目结构清晰规范: -``` +```markdown StellarX/ ├── include/ # 头文件目录 │ └── StellarX/ # 框架头文件 @@ -34,6 +34,8 @@ StellarX/ │ ├── Label.h # 标签控件 │ ├── TextBox.h # 文本框控件 │ ├── Canvas.h # 画布容器 +│ ├── Dialog.h # 对话框控件(v2.0.0新增) +│ ├── MessageBox.h # 消息框工厂(v2.0.0新增) │ └── Table.h # 表格控件 ├── src/ # 源文件目录 │ ├── Control.cpp @@ -42,7 +44,9 @@ StellarX/ │ ├── Label.cpp │ ├── TextBox.cpp │ ├── Canvas.cpp -│ └── Table.cpp +│ ├── Table.cpp +│ ├── Dialog.cpp # v2.0.0新增 +│ └── MessageBox.cpp # v2.0.0新增 ├── examples/ # 示例代码目录 │ └── demo.cpp # 基础演示 ├── docs/ # 文档目录 @@ -56,6 +60,7 @@ StellarX/ ``` **设计理念:** + 1. **单一职责原则 (SRP)**: 每个类/文件只负责一件事。 2. **依赖倒置原则 (DIP)**: 高层模块(如`Window`)不依赖低层模块(如`Button`),二者都依赖其抽象(`Control`)。 3. **开闭原则 (OCP)**: 通过继承`Control`基类,可以轻松扩展新的控件,而无需修改现有代码。 @@ -66,10 +71,12 @@ StellarX/ - **极致的轻量级**: 核心库编译后仅 ~1.2MB,无任何外部依赖。生成的应用程序小巧玲珑。 - **清晰的模块化架构**: 使用`CoreTypes.h`统一管理所有类型,消除重复定义,极大提升可维护性。 - **原生C++性能**: 直接基于EasyX和Win32 API,提供接近原生的执行效率,内存占用极低(通常<10MB)。 -- **丰富的控件库**: 提供按钮、标签、文本框、表格、画布等常用控件,满足基本桌面应用需求。 +- **完整的控件体系**: 按钮(Button)、标签(Label)、文本框(TextBox)、画布(Canvas)、表格(Table)、对话框(Dialog)与消息框工厂(MessageBox)。 - **高度可定制化**: 从控件颜色、形状(矩形、圆角、圆形、椭圆)到填充模式、字体样式,均有详尽枚举支持,可轻松定制。 - **简洁直观的API**: 采用经典的面向对象设计,代码即文档,学习成本极低。 - **标准项目结构**: 采用标准的include/src分离结构,支持CMake构建,易于集成和使用。 +- **增强的事件系统**: v2.0.0引入事件消费机制,所有`handleEvent`方法返回`bool`表示是否消费事件,支持更精细的事件传播控制。 +- **对话框系统**: 新增完整的对话框支持,包括模态和非模态对话框,自动处理背景保存和恢复。 ## ⚡ 快速开始(5分钟上手) @@ -126,43 +133,55 @@ StellarX/ #include "StellarX.h" // 程序入口点(请使用WinMain以获得更好的兼容性) -int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) { +int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) +{ + // 1. 创建一个640x480的窗口,背景为白色,标题为"我的应用" + Window mainWindow(640, 480, 0, RGB(255, 255, 255), "我的第一个星垣应用"); - // 1. 创建一个640x480的窗口,背景为白色,标题为"我的应用" - Window mainWindow(640, 480, 0, RGB(255, 255, 255), "我的第一个星垣应用"); + // 2. 创建一个按钮 (使用智能指针管理) + auto myButton = std::make_unique