Merge branch 'develop' into feature/a11y

This commit is contained in:
Martín Lucas Golini
2026-09-09 01:28:00 -03:00
40 changed files with 3092 additions and 1270 deletions
+1
View File
@@ -96,6 +96,7 @@
#include <eepp/ui/tools/uidocfindreplace.hpp>
#include <eepp/ui/tools/uifontpickerdialog.hpp>
#include <eepp/ui/tools/uiimageviewer.hpp>
#include <eepp/ui/tools/uisettingspanel.hpp>
#include <eepp/ui/tools/uitabwidgetsplitter.hpp>
#include <eepp/ui/tools/uiwidgetinspector.hpp>
#include <eepp/ui/uiapplication.hpp>
+1 -1
View File
@@ -27,7 +27,7 @@ class EE_API StyleSheetSelector {
bool hasPseudoClasses() const;
std::vector<UIWidget*> getRelatedElements( UIWidget* element, bool applyPseudo = true ) const;
SmallVector<UIWidget*, 8> getRelatedElements( UIWidget* element, bool applyPseudo = true ) const;
bool isStructurallyVolatile() const;
+1 -1
View File
@@ -123,7 +123,7 @@ template <typename T> class UIProperty {
}
/** @return All currently connected widgets, or an empty vector after expiration. */
std::vector<UIWidget*> widgets() const {
SmallVector<UIWidget*, 8> widgets() const {
auto state = mState.lock();
if ( !state || !state->property || !state->property->databind().isInitialized() )
return {};
+221
View File
@@ -0,0 +1,221 @@
#ifndef EE_UI_TOOLS_UISETTINGSPANEL_HPP
#define EE_UI_TOOLS_UISETTINGSPANEL_HPP
#include <eepp/core/string.hpp>
#include <eepp/ui/uilinearlayout.hpp>
#include <functional>
#include <memory>
#include <string>
#include <variant>
#include <vector>
namespace pugi {
class xml_node;
}
namespace EE::UI {
class UICheckBox;
}
namespace EE::UI::Tools {
struct SettingView;
struct EE_API SettingDescriptor {
std::string id;
std::string category;
String name;
String description;
String group;
};
struct EE_API BoolPointerSetting {
bool* value{ nullptr };
std::function<void( bool )> apply;
};
struct EE_API BoolSetting {
std::function<bool()> get;
std::function<void( bool )> set;
};
struct EE_API ChoiceSetting {
std::vector<String> choices;
std::vector<String> descriptions;
std::function<size_t()> get;
std::function<void( size_t )> set;
};
struct EE_API EditableChoiceSetting {
std::vector<String> choices;
std::function<String()> get;
std::function<bool( const String& )> set;
};
struct EE_API IntegerSetting {
int min{ 0 };
int max{ 0 };
std::function<int()> get;
std::function<void( int )> set;
};
struct EE_API TextSetting {
std::function<std::string()> get;
std::function<bool( const std::string& )> set;
bool commitOnFocusLoss{ false };
bool password{ false };
};
struct EE_API FloatSetting {
double min{ 0 };
double max{ 0 };
double step{ 0 };
std::function<double()> get;
std::function<void( double )> set;
};
struct EE_API ActionSetting {
String buttonText;
std::function<void()> action;
};
using SettingValue =
std::variant<BoolPointerSetting, BoolSetting, ChoiceSetting, EditableChoiceSetting,
IntegerSetting, TextSetting, FloatSetting, ActionSetting>;
struct EE_API SettingDefinition {
SettingDescriptor descriptor;
SettingValue value;
bool enabled{ true };
};
struct EE_API SettingsCategory {
std::string id;
String parent;
String name;
};
struct EE_API SettingsGroup {
std::string category;
String name;
size_t beforeSetting{ 0 };
};
class EE_API SettingsModel {
public:
void clear();
bool addCategory( SettingsCategory category );
bool addGroup( SettingsGroup group );
bool addSetting( SettingDefinition setting );
bool hasCategory( const std::string& id ) const;
const std::vector<SettingsCategory>& categories() const { return mCategories; }
const std::vector<SettingsGroup>& groups() const { return mGroups; }
std::vector<SettingDefinition>& settings() { return mSettings; }
const std::vector<SettingDefinition>& settings() const { return mSettings; }
private:
std::vector<SettingsCategory> mCategories;
std::vector<SettingsGroup> mGroups;
std::vector<SettingDefinition> mSettings;
};
class EE_API UISettingsPanel : public UILinearLayout {
public:
static UISettingsPanel* New( UIWidget* parent );
virtual ~UISettingsPanel();
SettingsModel& getModel();
const SettingsModel& getModel() const;
bool addCategory( std::string id, String parent, String name );
bool addGroup( std::string category, String name );
bool addBool( SettingDescriptor descriptor, bool* value,
std::function<void( bool )> apply = {} );
bool addBool( SettingDescriptor descriptor, std::function<bool()> get,
std::function<void( bool )> set );
bool addChoice( SettingDescriptor descriptor, std::vector<String> choices,
std::function<size_t()> get, std::function<void( size_t )> set,
std::vector<String> choiceDescriptions = {} );
bool addEditableChoice( SettingDescriptor descriptor, std::vector<String> choices,
std::function<String()> get, std::function<bool( const String& )> set );
bool addInteger( SettingDescriptor descriptor, int min, int max, std::function<int()> get,
std::function<void( int )> set );
bool addText( SettingDescriptor descriptor, std::function<std::string()> get,
std::function<bool( const std::string& )> set, bool commitOnFocusLoss = false );
bool addFloat( SettingDescriptor descriptor, double min, double max, double step,
std::function<double()> get, std::function<void( double )> set );
bool addAction( SettingDescriptor descriptor, String buttonText, std::function<void()> action );
void build();
void selectCategory( const std::string& category );
void setCategoryEnabled( const std::string& category, bool enabled,
const std::string& excludedSetting = {} );
void refreshTextSetting( const std::string& id );
void setSearchResultsText( String text );
void setFilter( String filter );
void focusSearch();
void focusCategories();
bool isBuilt() const;
protected:
struct Impl;
std::unique_ptr<Impl> mImpl;
explicit UISettingsPanel( UIWidget* parent );
void selectCategory( Impl& panel, const std::string& category );
void addCategory( Impl& panel, const std::string& id, const String& parent,
const String& name );
void addSubcategoryHeading( Impl& panel, const std::string& category, const String& name );
void setupCategories( Impl& panel );
UIWidget* createRow( Impl& panel, SettingDefinition& setting, SettingView& view,
pugi::xml_node layout );
UICheckBox* createBoolControl( Impl& panel, SettingDefinition& setting, SettingView& view );
void materializeCategory( Impl& panel, const std::string& category );
void materializeVisibleSettings( Impl& panel, const String& query );
void setCategoryEnabled( Impl& panel, const std::string& category, bool enabled,
const std::string& excludedSetting = {} );
void refreshTextSetting( Impl& panel, const std::string& id );
void filter( Impl& panel );
};
} // namespace EE::UI::Tools
#endif
+6
View File
@@ -1516,8 +1516,14 @@ class EE_API UINode : public Node {
/** @brief Get a widget's computed absolute font size in pixels. */
Float getAbsoluteFontSize( const UIWidget* widget ) const;
/** Returns true if the node is currently being created, this state is not used by all node
* types.
*/
bool isCreatingNode() const;
/** Forces a left mouse click event over the node */
void click();
protected:
Vector2f mDpPos;
Sizef mDpSize;
+2 -1
View File
@@ -864,7 +864,8 @@ class EE_API UISceneNode : public SceneNode {
* @param marker Marker for style association.
* @return Vector of root widgets created.
*/
std::vector<UIWidget*> loadNode( pugi::xml_node node, Node* parent, const Uint32& marker = 0 );
SmallVector<UIWidget*, 8> loadNode( pugi::xml_node node, Node* parent,
const Uint32& marker = 0 );
/** Sets the document / scene URI used to resolve paths of inner elements */
void setURI( const URI& uri );
+7 -4
View File
@@ -26,6 +26,7 @@ class UITooltip;
class UIStyle;
class AccessibilityWidgetResolver;
struct AccessibilityProperties;
class UIWidget;
struct MarginAuto {
static constexpr auto Left = ( 1 << 0 );
@@ -34,6 +35,8 @@ struct MarginAuto {
static constexpr auto Bottom = ( 1 << 3 );
};
using WidgetQueryResult = SmallVector<UIWidget*, 8>;
/**
* @brief Base class for all UI widgets in the eepp framework.
*
@@ -1153,7 +1156,7 @@ class EE_API UIWidget : public UINode {
* @param className The CSS class to search for.
* @return Vector of matching UIWidget pointers.
*/
std::vector<UIWidget*> findAllByClass( const std::string& className );
WidgetQueryResult findAllByClass( const std::string& className );
/**
* @brief Finds all widgets by CSS tag.
@@ -1163,7 +1166,7 @@ class EE_API UIWidget : public UINode {
* @param tag The CSS tag to search for.
* @return Vector of matching UIWidget pointers.
*/
std::vector<UIWidget*> findAllByTag( const std::string& tag );
WidgetQueryResult findAllByTag( const std::string& tag );
/**
* @brief Finds a widget by CSS class.
@@ -1225,7 +1228,7 @@ class EE_API UIWidget : public UINode {
* @param selector The CSS selector to use.
* @return Vector of all matching UIWidget pointers.
*/
std::vector<UIWidget*> querySelectorAll( const CSS::StyleSheetSelector& selector );
WidgetQueryResult querySelectorAll( const CSS::StyleSheetSelector& selector );
/**
* @brief Queries all widgets using a CSS selector string.
@@ -1235,7 +1238,7 @@ class EE_API UIWidget : public UINode {
* @param selector The CSS selector string to use.
* @return Vector of all matching UIWidget pointers.
*/
std::vector<UIWidget*> querySelectorAll( const std::string& selector );
WidgetQueryResult querySelectorAll( const std::string& selector );
/**
* @brief Gets a property value as a string.
+27
View File
@@ -7,6 +7,10 @@ namespace EE { namespace Window {
class EE_API Clipboard {
public:
using Data = std::vector<Uint8>;
using DataCallback = std::function<const void*( const char* mimeType, size_t* size )>;
using CleanupCallback = std::function<void()>;
virtual ~Clipboard();
/** @return The Clipboard Text if available */
@@ -30,6 +34,29 @@ class EE_API Clipboard {
/** Set the current clipboard primary selection text */
virtual void setPrimarySelectionText( const std::string& text ) {}
/**
* Offer non-text clipboard data in one or more MIME types. The data callback is invoked lazily
* when the operating system requests a format, and with a null MIME type when the offer is
* cleared or replaced. The returned data must remain valid until the cleanup callback is
* invoked. Only implemented by the SDL3 backend.
*/
virtual bool setData( DataCallback callback, CleanupCallback cleanup,
const std::vector<std::string>& mimeTypes ) {
return false;
}
/** Clear all clipboard data. Only implemented by the SDL3 backend. */
virtual bool clearData() { return false; }
/** Get clipboard data for a MIME type. Only implemented by the SDL3 backend. */
virtual Data getData( const std::string& mimeType ) { return {}; }
/** @return The MIME types currently offered by the clipboard. SDL3 backend only. */
virtual std::vector<std::string> getMimeTypes() { return {}; }
/** @return Whether clipboard data is available for a MIME type. SDL3 backend only. */
virtual bool hasData( const std::string& mimeType ) const { return false; }
protected:
friend class Window;