-
Notifications
You must be signed in to change notification settings - Fork 1
Description
DesignManager (design_manager.h) is a comprehensive UI design tool built upon ImGui, offering powerful features like layers, advanced shape rendering (corners, borders, shadows, blur, gradients, glass), parenting hierarchies, Shape Keys for responsiveness, a sophisticated animation engine (ButtonAnimation, ChainAnimation), and code generation capabilities.
Despite its strengths, creating complex, responsive, and fluid user interfaces comparable to those built with modern web frameworks (e.g., React with CSS Flexbox/Grid) presents challenges. The current reliance on absolute positioning and manual adjustments often leads to what can be described as a "mathematics explosion" and repetitive style management, hindering rapid development and maintainability.
This issue outlines the core areas for improvement required to bridge this gap, aiming to enhance DesignManager's capabilities while preserving its existing powerful features. The primary focus is on fundamentally improving the Layout System and the Styling System to align better with modern UI development paradigms.
Areas for Improvement & Proposed Paths:
1. Layout System:
- Current State:
- Layout primarily relies on absolute positioning defined by
ShapeItem::positionandShapeItem::size. - The
ShapeKeymechanism provides adaptability based on window size, but it's rule-based and requires manual configuration for specific size transitions. It doesn't inherently handle the relative positioning of sibling elements. - Parenting (
SetParent) establishes a transform hierarchy, but lacks an intrinsic mechanism for automatic content flow or dynamic arrangement of children within a container (analogous to CSS Flexbox or Grid). - Common layout scenarios like arranging items horizontally/vertically with spacing, wrapping content, distributing space, or centering groups require extensive manual calculations or complex
ShapeKeysetups.
- Layout primarily relies on absolute positioning defined by
- Shortcomings:
- Absence of an automatic, fluid, and constraint-based layout engine.
- Significant manual effort ("math explosion") is needed for achieving responsive and adaptive layouts beyond simple
ShapeKeyrules. - Poor scalability for complex UIs where elements need to reflow dynamically.
- Proposed Path (High Priority):
- Introduce Container Elements:
- Define new specialized
ShapeItemtypes (e.g.,FlexContainer,GridContainer,StackPanel) OR add layout modes/properties to the existingShapeItem. - These containers will be responsible for measuring and arranging their child
ShapeItems.
- Define new specialized
- Implement Layout Properties: Equip container elements with properties to control child arrangement:
direction:Row,Column(for Flex/Stack)justifyContent:Start,Center,End,SpaceBetween,SpaceAround,SpaceEvenly(distribution along the main axis)alignItems:Start,Center,End,Stretch,Baseline(alignment along the cross axis)gap: Spacing between child elements (pixels or potentially relative units).wrap:NoWrap,Wrap,WrapReverse(for Flex)- (Grid-specific properties like
templateColumns,templateRowscould be added later if a Grid container is implemented)
- Develop a Two-Pass Layout Engine (
Measure/Arrange):- Measure Pass: Each container recursively asks its children how much space they desire (based on their content, fixed size, or constraints). The container then determines its own desired size based on its children and layout rules. This pass calculates the "intrinsic" or "desired" size.
- Arrange Pass: Given the actual space allocated to the container (by its parent or the window), the container recursively positions and sizes its children according to its layout properties (
direction,justifyContent,alignItems,gap, etc.) and the children's measured sizes/flexibility factors.
- Implement Flexibility (
Grow/Shrink): Allow child elements within layout containers to define flexibility factors:growFactor: How much extra space the element should take up if the container has available space along the main axis.shrinkFactor: How much the element should shrink if there isn't enough space in the container along the main axis.basis(Optional): An initial size basis before flexing.
- Introduce Container Elements:
2. Styling System:
- Current State:
- Style attributes (
fillColor,borderColor,cornerRadius,shadowColor, etc.) are defined directly as members of theShapeItemstruct. - Basic state styling exists via
hoverColorandclickedColor. - Advanced styles like gradients and glass effects are handled through specific properties.
- Style attributes (
- Shortcomings:
- No mechanism for defining reusable styles or themes (like CSS classes). Applying consistent styling across multiple elements requires redundant property setting.
- Lack of a standardized way to handle other common UI states (e.g.,
disabled,focused). - Difficult to perform global theme changes.
- Proposed Path (Medium Priority):
- Define a
StyleDataStruct/Class: Create a dedicated structure to encapsulate all visual styling attributes (colors, fonts, borders, shadows, gradients, potentially padding/margin if integrated with the layout system). - Implement a Central Style Repository (
StyleSheet): Use a mechanism likestd::map<std::string, StyleData>to define named, reusable styles. - Reference Styles from
ShapeItem: ModifyShapeItemto hold references (e.g.,std::string styleNameorStyleID) to styles defined in the central repository, rather than holding all style properties directly. Allow overriding specific properties locally. - Introduce State-Based Styles: Enhance
StyleDataor the referencing mechanism to support variations for different states (normal,hover,active,disabled,focused). TheDesignManagerrendering logic should automatically query the appropriate style variant based on the element's current state (usingImGui::IsItemHovered(),ImGui::IsItemActive(), potentially adding adisabledflag toShapeItem). - Consider Style Inheritance (Optional): Implement a simple inheritance model where child elements inherit style properties from their parent unless explicitly overridden.
- Define a
3. Animation & Layout Integration:
- Current State: The sophisticated animation engine (
ButtonAnimation,ChainAnimation) primarily targets direct transform properties (position,size,rotation). - Shortcomings: Cannot fluidly animate layout-related properties (e.g., a
FlexContainer'sgap, an element'swidthpercentage, a sidebar's overall width managed by the layout system). This prevents smooth transitions like the collapsing sidebar seen in the React example. - Proposed Path (Post-Layout System):
- Extend the animation engine (
UpdateShapeTransforms_Unified,UpdateChainAnimations) to allow targeting and interpolating layout-specific properties defined in the new Layout System (e.g.,width,height(could be fixed, percentage, or 'auto'),growFactor,gap, potentially container-specific properties). - Ensure the Layout Engine re-runs its
MeasureandArrangepasses whenever animated layout properties change, allowing the UI to reflow smoothly during the animation.
- Extend the animation engine (
4. Code Structure & Organization:
- Current State: All code resides within a single, large header file (
design_manager.h). - Shortcomings: Can lead to longer compile times, reduced maintainability, and potential namespace pollution as the system grows.
- Proposed Path (Ongoing/Lower Priority):
- Modularize: Refactor the code into logical modules (e.g.,
Core,Rendering,Layout,Animation,Styling,UI_Editor) with separate header (.h) and implementation (.cpp) files. - Namespace Usage: Enforce consistent use of the
DesignManagernamespace for all related structures, functions, and enums to prevent naming conflicts.
- Modularize: Refactor the code into logical modules (e.g.,
5. Component Model Refinement (Optional/Lower Priority):
- Current State:
ShapeItemserves as a monolithic entity handling rendering, styling, basic layout, animation, and behavior. - Shortcomings: Can make the
ShapeItemstruct overly complex and potentially violate the Single Responsibility Principle. - Proposed Path: Consider introducing more specialized component types, perhaps inheriting from a base
UIElementor usingShapeItemvia composition. Examples:TextLabel,ImageElement,Panel,ButtonBase,FlexContainer. This could improve code clarity and organization but requires significant refactoring. Evaluate if the benefits outweigh the costs after addressing layout and styling.
Proposed Roadmap (Prioritized):
- [Layout System] Design and implement the core layout container(s) (e.g., Flexbox-like) and the
Measure/Arrangepass logic. - [Styling System] Design and implement the
StyleDatastructure and the centralStyleSheetrepository mechanism. ModifyShapeItemto use style references. Implement state-based styling application. - [Animation/Layout Integration] Update the animation engine to target and interpolate layout properties. Integrate with the layout engine for smooth reflows.
- [Code Structure] Gradually refactor the codebase into separate modules and improve namespace consistency.
- [Component Model] Evaluate the need for and potentially implement more specialized component types.
Conclusion:
DesignManager provides a remarkable foundation for visual UI design within the ImGui ecosystem. Addressing the core Layout and Styling systems as outlined above will be crucial in elevating its capabilities to match the flexibility and developer experience offered by modern UI frameworks. These enhancements will significantly reduce the need for manual calculations, streamline the design workflow, and enable the creation of more complex, adaptive, and visually polished user interfaces.