Added tooltips

This commit is contained in:
OmniaX-Dev 2026-04-22 05:34:59 +02:00
parent 83f4687198
commit ffe9d7ca1a
9 changed files with 75 additions and 21 deletions

View file

@ -10,7 +10,16 @@ const $accentColorDark = #6B0A1DFF
% ====== Root Widget ====== % ====== Root Widget ======
window.backgroundColor = rgba(160, 160, 160, 255) (window) {
backgroundColor = rgba(160, 160, 160, 255)
(tooltip) {
backgroundColor = #FFF7D6FF
borderColor = rgb(30, 30, 30)
textColor = rgb(30, 30, 30)
borderWidth = 1
fontSize = 20
}
}
% ========================= % =========================

View file

@ -42,6 +42,7 @@ Implement following widgets:
***Button ***Button
***Image/Icon ***Image/Icon
***Save/Open File Dialogs (and folder dialogs) ***Save/Open File Dialogs (and folder dialogs)
***Tooltips
Radio Button Radio Button
Grouping Grouping
Progressbar Progressbar
@ -49,7 +50,6 @@ Implement following widgets:
Vertical Slider Vertical Slider
ListBox ListBox
ComboBox ComboBox
Tooltips
Context Menu Context Menu
Menu Bar Menu Bar
Layouts Layouts

View file

@ -583,6 +583,7 @@ namespace ogfx
else if (event.type == SDL_EVENT_MOUSE_MOTION) else if (event.type == SDL_EVENT_MOUSE_MOTION)
{ {
MouseEventData mmd = get_mouse_state(event); MouseEventData mmd = get_mouse_state(event);
m_mousePosition = { mmd.position_x, mmd.position_y };
ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MouseMoved, ostd::Signal::Priority::RealTime, mmd); ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MouseMoved, ostd::Signal::Priority::RealTime, mmd);
} }
else if (event.type == SDL_EVENT_MOUSE_WHEEL) else if (event.type == SDL_EVENT_MOUSE_WHEEL)
@ -876,6 +877,15 @@ namespace ogfx
m_rootWidget.__update(); m_rootWidget.__update();
m_rootWidget.__draw(m_gfx); m_rootWidget.__draw(m_gfx);
onRedraw(m_gfx); onRedraw(m_gfx);
if (isTooltipShown())
{
auto textSize = m_gfx.getStringDimensions(getTooltipText(), m_rootWidget.getTooltipFontSize());
Rectangle textBounds = { getMousePosition(), textSize };
textBounds += Rectangle { 0, 0, 30, 10 };
m_gfx.outlinedRect(textBounds, m_rootWidget.getTooltipBackgroundColor(), m_rootWidget.getTooltipBorderColor(), m_rootWidget.getTooltipBorderWidth());
m_gfx.drawCenteredString(getTooltipText(), textBounds, m_rootWidget.getTooltipTextColor(), m_rootWidget.getTooltipFontSize());
}
m_gfx.endFrame(); m_gfx.endFrame();
after_render(); after_render();
} }

View file

@ -135,6 +135,13 @@ namespace ogfx
inline GraphicsWindowOutputHandler& wout(void) { return m_wout; } inline GraphicsWindowOutputHandler& wout(void) { return m_wout; }
inline f32 getScaleFactor(void) const { return m_systemScale * m_userScale; } inline f32 getScaleFactor(void) const { return m_systemScale * m_userScale; }
inline void updateScalleFactor(void) { setUserScale(m_userScale); } inline void updateScalleFactor(void) { setUserScale(m_userScale); }
inline Vec2 getMousePosition(void) const { return m_mousePosition; }
inline void startTooltipTimer(const String& text) { m_tooltipText = text; m_tooltipTimer.startCount(ostd::eTimeUnits::Seconds); }
inline void stopTooltipTimer(void) { m_tooltipText = ""; m_tooltipTimer.endCount(); }
inline void restartTooltipTimer(void) { m_tooltipTimer.restart(ostd::eTimeUnits::Seconds); }
inline u64 readTooltipTimer(void) { return m_tooltipTimer.read(); }
inline bool isTooltipShown(void) { return m_tooltipText.new_trim() != "" && m_tooltipTimer.read() >= 2; }
inline String getTooltipText(void) const { return m_tooltipText; }
protected: protected:
MouseEventData get_mouse_state(SDL_Event& event); MouseEventData get_mouse_state(SDL_Event& event);
@ -170,6 +177,9 @@ namespace ogfx
i32 m_windowHeight { 0 }; i32 m_windowHeight { 0 };
String m_title { "" }; String m_title { "" };
i32 m_blockingEventsDelay { 33 }; i32 m_blockingEventsDelay { 33 };
Vec2 m_mousePosition { 0, 0 };
ostd::Timer m_tooltipTimer;
String m_tooltipText { "" };
bool m_running { false }; bool m_running { false };
bool m_initialized { false }; bool m_initialized { false };

View file

@ -43,12 +43,16 @@ namespace ogfx
void RootWidget::applyTheme(const ostd::Stylesheet& theme) void RootWidget::applyTheme(const ostd::Stylesheet& theme)
{ {
m_color = getThemeValue<Color>(theme, "backgroundColor", getWindow().getClearColor()); setTooltipBackgroundColor(getThemeValue<Color>(theme, "tooltip.backgroundColor", getTooltipBackgroundColor()));
setTooltipBorderColor(getThemeValue<Color>(theme, "tooltip.borderColor", getTooltipBorderColor()));
setTooltipTextColor(getThemeValue<Color>(theme, "tooltip.textColor", getTooltipTextColor()));
setTooltipBorderWidth(getThemeValue<i32>(theme, "tooltip.borderWidth", getTooltipBorderWidth()));
setTooltipFontSize(getThemeValue<i32>(theme, "tooltip.fontSize", getTooltipFontSize()));
} }
void RootWidget::onDraw(ogfx::BasicRenderer2D& gfx) void RootWidget::onDraw(ogfx::BasicRenderer2D& gfx)
{ {
gfx.fillRect({ 0, 0, cast<f32>(getWindow().getWindowWidth()), cast<f32>(getWindow().getWindowHeight()) }, m_color); gfx.fillRect({ 0, 0, cast<f32>(getWindow().getWindowWidth()), cast<f32>(getWindow().getWindowHeight()) }, getBackgroundColor());
} }
} }
} }

View file

@ -1,21 +1,21 @@
/* /*
OmniaFramework - A collection of useful functionality OmniaFramework - A collection of useful functionality
Copyright (C) 2025 OmniaX-Dev Copyright (C) 2025 OmniaX-Dev
This file is part of OmniaFramework. This file is part of OmniaFramework.
OmniaFramework is free software: you can redistribute it and/or modify OmniaFramework is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
OmniaFramework is distributed in the hope that it will be useful, OmniaFramework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>. along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
@ -35,9 +35,18 @@ namespace ogfx
void onWindowResized(const Event& event) override; void onWindowResized(const Event& event) override;
void applyTheme(const ostd::Stylesheet& theme) override; void applyTheme(const ostd::Stylesheet& theme) override;
void onDraw(ogfx::BasicRenderer2D& gfx) override; void onDraw(ogfx::BasicRenderer2D& gfx) override;
OSTD_PARAM_GETSET(Color, TooltipBackgroundColor, m_tooltipBackgroundColor);
OSTD_PARAM_GETSET(Color, TooltipBorderColor, m_tooltipBorderColor);
OSTD_PARAM_GETSET(Color, TooltipTextColor, m_tooltipTextColor);
OSTD_PARAM_GETSET(i32, TooltipBorderWidth, m_tooltipBorderWidth);
OSTD_PARAM_GETSET(i32, TooltipFontSize, m_tooltipFontSize);
private: private:
Color m_color { Colors::Transparent }; Color m_tooltipBackgroundColor { "#FFF7D6FF" };
Color m_tooltipBorderColor { 50, 50, 50 };
Color m_tooltipTextColor { 50, 50, 50 };
i32 m_tooltipBorderWidth { 1 };
i32 m_tooltipFontSize { 20 };
}; };
} }
} }

View file

@ -320,6 +320,8 @@ namespace ogfx
callback_onMouseMoved(event); callback_onMouseMoved(event);
onMouseMoved(event); onMouseMoved(event);
} }
if (isTooltipEnabled() && isMouseInside())
getWindow().restartTooltipTimer();
} }
void Widget::__onMouseScrolled(const Event& event) void Widget::__onMouseScrolled(const Event& event)
@ -340,6 +342,8 @@ namespace ogfx
if (callback_onMouseEntered) if (callback_onMouseEntered)
callback_onMouseEntered(event); callback_onMouseEntered(event);
onMouseEntered(event); onMouseEntered(event);
if (isTooltipEnabled())
getWindow().startTooltipTimer(getTooltipText());
} }
void Widget::__onMouseExited(const Event& event) void Widget::__onMouseExited(const Event& event)
@ -348,6 +352,8 @@ namespace ogfx
if (callback_onMouseExited) if (callback_onMouseExited)
callback_onMouseExited(event); callback_onMouseExited(event);
onMouseExited(event); onMouseExited(event);
if (isTooltipEnabled())
getWindow().stopTooltipTimer();
} }
void Widget::__onMouseDragged(const Event& event) void Widget::__onMouseDragged(const Event& event)

View file

@ -26,6 +26,7 @@
#include <ostd/math/Geometry.hpp> #include <ostd/math/Geometry.hpp>
#include <ostd/io/Stylesheet.hpp> #include <ostd/io/Stylesheet.hpp>
#include <ostd/utils/Defines.hpp> #include <ostd/utils/Defines.hpp>
#include <ostd/utils/Time.hpp>
#include <functional> #include <functional>
namespace ogfx namespace ogfx
@ -141,6 +142,7 @@ namespace ogfx
OSTD_PARAM_GETSET(Rectangle, Margin, m_margin); OSTD_PARAM_GETSET(Rectangle, Margin, m_margin);
OSTD_PARAM_GETSET(i32, TabIndex, m_tabIndex); OSTD_PARAM_GETSET(i32, TabIndex, m_tabIndex);
OSTD_PARAM_GETSET(Vec2, ContentOffset, m_contentOffset); OSTD_PARAM_GETSET(Vec2, ContentOffset, m_contentOffset);
OSTD_PARAM_GETSET(String, TooltipText, m_tooltipText);
// BOOL PARAMETERS // BOOL PARAMETERS
inline bool isVisible(void) const { return m_visible; } inline bool isVisible(void) const { return m_visible; }
@ -167,6 +169,7 @@ namespace ogfx
OSTD_BOOL_PARAM_GETSET_E(HScroll, m_vScrollEnabled); OSTD_BOOL_PARAM_GETSET_E(HScroll, m_vScrollEnabled);
OSTD_BOOL_PARAM_GETSET_E(BackgroundGradient, m_useBackgroundGradient); OSTD_BOOL_PARAM_GETSET_E(BackgroundGradient, m_useBackgroundGradient);
OSTD_BOOL_PARAM_GETSET_E(Theming, m_enableTheming); OSTD_BOOL_PARAM_GETSET_E(Theming, m_enableTheming);
OSTD_BOOL_PARAM_GETSET_E(Tooltip, m_enableTooltip);
// ========================================================================== // ==========================================================================
protected: protected:
@ -185,6 +188,7 @@ namespace ogfx
bool m_focused { false }; bool m_focused { false };
i32 m_tabIndex { -1 }; i32 m_tabIndex { -1 };
i32 m_zIndex { -1 }; i32 m_zIndex { -1 };
String m_tooltipText { "" };
MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None }; MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None };
// ==================== // ====================
@ -205,6 +209,7 @@ namespace ogfx
bool m_vScrollEnabled { false }; bool m_vScrollEnabled { false };
bool m_hScrollEnabled { false }; bool m_hScrollEnabled { false };
bool m_enableTheming { true }; bool m_enableTheming { true };
bool m_enableTooltip { false };
// ==================== // ====================

View file

@ -52,7 +52,6 @@ class Window : public ogfx::gui::Window
m_label1.setText("Show Panel2"); m_label1.setText("Show Panel2");
m_label1.setCallback(ogfx::gui::Widget::eCallback::MousePressed, [&](const ogfx::gui::Event& event) -> void { m_label1.setCallback(ogfx::gui::Widget::eCallback::MousePressed, [&](const ogfx::gui::Event& event) -> void {
m_check1.setChecked(!m_check1.isChecked()); m_check1.setChecked(!m_check1.isChecked());
m_label1.addy(10);
}); });
m_label1.disableTheming(); m_label1.disableTheming();
m_label1.addThemeOverride("@.label.showBackground", true); m_label1.addThemeOverride("@.label.showBackground", true);
@ -81,6 +80,8 @@ class Window : public ogfx::gui::Window
m_btn1.setIcon("./img.png"); m_btn1.setIcon("./img.png");
m_btn1.setIconSize({ 64, 64 }); m_btn1.setIconSize({ 64, 64 });
m_btn1.enableAnimated(); m_btn1.enableAnimated();
m_btn1.enableTooltip();
m_btn1.setTooltipText("Test tooltip");
m_label2.setText("Label2"); m_label2.setText("Label2");
m_label3.setText("Label3"); m_label3.setText("Label3");
@ -99,13 +100,13 @@ class Window : public ogfx::gui::Window
m_panel2.setSize(600, 400); m_panel2.setSize(600, 400);
m_panel2.setTitle("Panel 2"); m_panel2.setTitle("Panel 2");
m_panel2.enableTooltip();
m_panel2.setTooltipText("PANEL tooltip");
m_tabs.setSize(900, 700); m_tabs.setSize(900, 700);
auto& t1 = m_tabs.addTab("Tab1"); auto& t1 = m_tabs.addTab("Tab1");
auto& t2 = m_tabs.addTab("Tab2 Test"); auto& t2 = m_tabs.addTab("Tab2 Test");
auto& t3 = m_tabs.addTab("Long Tab Test"); auto& t3 = m_tabs.addTab("Long Tab Test");
for (i32 i = 3; i < 15; i++)
m_tabs.addTab(String("Tab").add(i));
t2.addThemeOverride("@panel_tab.panel.backgroundColor", Colors::SkyBlue); t2.addThemeOverride("@panel_tab.panel.backgroundColor", Colors::SkyBlue);
t3.addThemeOverride("@panel_tab.panel.backgroundColor", Colors::Orange); t3.addThemeOverride("@panel_tab.panel.backgroundColor", Colors::Orange);