Added Drag and Drop for Color Picker
This commit is contained in:
parent
6fb05f77ab
commit
28380f94d9
8 changed files with 173 additions and 143 deletions
|
|
@ -417,4 +417,8 @@ macro set_common_values(_borderColor = $borderColor, _fontSize = 18, _showBorder
|
||||||
regionSpacing = 8
|
regionSpacing = 8
|
||||||
cursorRadius = 6
|
cursorRadius = 6
|
||||||
}
|
}
|
||||||
|
(colorButton) {
|
||||||
|
set_common_values()
|
||||||
|
set_focus_border($blueAccent)
|
||||||
|
}
|
||||||
% =========================
|
% =========================
|
||||||
|
|
|
||||||
|
|
@ -151,14 +151,14 @@ namespace ogfx
|
||||||
{
|
{
|
||||||
if (w->m_mouseInside)
|
if (w->m_mouseInside)
|
||||||
{
|
{
|
||||||
// w->m_mouseInside = false;
|
w->m_mouseInside = false;
|
||||||
w->__onMouseExited(event);
|
w->__onMouseExited(event);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!w->m_mouseInside)
|
if (!w->m_mouseInside)
|
||||||
{
|
{
|
||||||
// w->m_mouseInside = true;
|
w->m_mouseInside = true;
|
||||||
w->__onMouseEntered(event);
|
w->__onMouseEntered(event);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -176,7 +176,7 @@ namespace ogfx
|
||||||
Widget* ww = m_widgetList[j];
|
Widget* ww = m_widgetList[j];
|
||||||
if (ww->m_mouseInside)
|
if (ww->m_mouseInside)
|
||||||
{
|
{
|
||||||
// ww->m_mouseInside = false;
|
ww->m_mouseInside = false;
|
||||||
ww->__onMouseExited(event);
|
ww->__onMouseExited(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -270,10 +270,7 @@ namespace ogfx
|
||||||
if (widget == nullptr) return;
|
if (widget == nullptr) return;
|
||||||
if (!widget->isVisible()) return;
|
if (!widget->isVisible()) return;
|
||||||
if (!widget->isDragAndDropEnabled()) return;
|
if (!widget->isDragAndDropEnabled()) return;
|
||||||
_DEBUG(4);
|
|
||||||
std::cout << widget->getTypeName() << "\n" << widget->getGlobalBounds() << "\n" << ostd::Vec2 { event.mouse->position_x, event.mouse->position_y } << "\n";
|
|
||||||
if (!widget->isMouseInside()) return;
|
if (!widget->isMouseInside()) return;
|
||||||
_DEBUG(5);
|
|
||||||
if (Widget::s_dragAndDropData != nullptr)
|
if (Widget::s_dragAndDropData != nullptr)
|
||||||
{
|
{
|
||||||
auto& const_cast_event = const_cast<Event&>(event);
|
auto& const_cast_event = const_cast<Event&>(event);
|
||||||
|
|
|
||||||
|
|
@ -205,9 +205,25 @@ namespace ogfx
|
||||||
setSize({ 48, 24 });
|
setSize({ 48, 24 });
|
||||||
setCallback(eCallback::DragAndDrop, [&](const ogfx::gui::Event& event) -> void {
|
setCallback(eCallback::DragAndDrop, [&](const ogfx::gui::Event& event) -> void {
|
||||||
auto data = Widget::getDragAndDropData();
|
auto data = Widget::getDragAndDropData();
|
||||||
if (data)
|
if (data && data->getTypeName() == Color().getTypeName())
|
||||||
std::cout << *data << "\n";
|
setColor(*cast<Color*>(data));
|
||||||
});
|
});
|
||||||
|
connectSignal(ostd::BuiltinSignals::MousePressed);
|
||||||
|
m_contextMenu.onActivate = [this](const ContextMenu::Entry& e) {
|
||||||
|
if (e.id == MenuId::Copy)
|
||||||
|
{
|
||||||
|
// TODO: Replace once I have a clipboard system
|
||||||
|
SDL_SetClipboardText(getColor().hexString(true, "#"));
|
||||||
|
}
|
||||||
|
else if (e.id == MenuId::Paste)
|
||||||
|
{
|
||||||
|
// TODO: Replace once I have a clipboard system
|
||||||
|
const String clipboardText = SDL_GetClipboardText();
|
||||||
|
Color tmp;
|
||||||
|
if (!clipboardText.empty() && Color::isValidColorString(clipboardText, &tmp))
|
||||||
|
setColor(tmp);
|
||||||
|
}
|
||||||
|
};
|
||||||
validate();
|
validate();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -254,25 +270,38 @@ namespace ogfx
|
||||||
|
|
||||||
void ColorButton::onMouseReleased(const Event& event)
|
void ColorButton::onMouseReleased(const Event& event)
|
||||||
{
|
{
|
||||||
|
bool mph = m_mousePressedHere;
|
||||||
|
m_mousePressedHere = false;
|
||||||
if (!isMouseInside()) return;
|
if (!isMouseInside()) return;
|
||||||
if (event.mouse->button != MouseEventData::eButton::Left)
|
if (event.mouse->button != MouseEventData::eButton::Left)
|
||||||
{
|
{
|
||||||
if (event.mouse->button == MouseEventData::eButton::Right) {}
|
if (event.mouse->button == MouseEventData::eButton::Right)
|
||||||
|
getWindow().showContextMenu(m_contextMenu, { event.mouse->position_x, event.mouse->position_y });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Widget::setDragAndDropData(m_color);
|
if (!mph) return;
|
||||||
if (m_popupOpen) close_popup();
|
if (m_popupOpen) close_popup();
|
||||||
else open_popup();
|
else open_popup();
|
||||||
event.handle();
|
event.handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorButton::onMousePressed(const Event& event)
|
||||||
|
{
|
||||||
|
if (!isMouseInside()) return;
|
||||||
|
if (event.mouse->button != MouseEventData::eButton::Left)
|
||||||
|
return;
|
||||||
|
Widget::setDragAndDropData(m_color);
|
||||||
|
m_mousePressedHere = true;
|
||||||
|
event.handle();
|
||||||
|
}
|
||||||
|
|
||||||
void ColorButton::open_popup(void)
|
void ColorButton::open_popup(void)
|
||||||
{
|
{
|
||||||
if (m_popup) close_popup();
|
if (m_popup) close_popup();
|
||||||
|
|
||||||
m_popup = new ColorPicker(getWindow());
|
m_popup = new ColorPicker(getWindow());
|
||||||
m_popup->setRootChild();
|
m_popup->setRootChild();
|
||||||
// m_popup->setTopMost(true);
|
// m_popup->setTopMost(true); // TODO: Implement
|
||||||
m_popup->setSize({ 240, 200 });
|
m_popup->setSize({ 240, 200 });
|
||||||
m_popup->setColor(m_color);
|
m_popup->setColor(m_color);
|
||||||
|
|
||||||
|
|
@ -310,25 +339,13 @@ namespace ogfx
|
||||||
m_popupOpen = false;
|
m_popupOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorButton::onUpdate(void)
|
void ColorButton::handleSignal(ostd::Signal& signal)
|
||||||
{
|
{
|
||||||
// Click-outside dismissal: while the popup is open, check whether
|
if (!m_popupOpen) return;
|
||||||
// the mouse has been pressed outside of both the popup AND this
|
if (signal.ID != ostd::BuiltinSignals::MousePressed) return;
|
||||||
// button. We piggy-back on the mouse position via the focus
|
if (isMouseInside()) return;
|
||||||
// manager — if neither the popup nor the button has focus, close.
|
if (!m_popup->isMouseInside())
|
||||||
//
|
close_popup();
|
||||||
// A simpler heuristic that works well enough: if the popup is open
|
|
||||||
// and the user clicks somewhere that isn't inside it, the popup's
|
|
||||||
// own focus is lost. We watch for that here.
|
|
||||||
if (m_popupOpen && m_popup && !m_popup->isFocused() && !isFocused())
|
|
||||||
{
|
|
||||||
// Avoid closing on the same frame the popup opened (it hasn't
|
|
||||||
// had a chance to be focused yet). The popup grabs focus on
|
|
||||||
// its first mouse interaction, so we'll only close once the
|
|
||||||
// user has actually interacted with it and then clicked away.
|
|
||||||
// For now we leave the close-on-outside-click to the host app
|
|
||||||
// or to a future FocusManager::onFocusLeft signal.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <ogfx/gui/widgets/Text.hpp>
|
#include <ogfx/gui/widgets/Text.hpp>
|
||||||
#include <ogfx/gui/widgets/Button.hpp>
|
#include <ogfx/gui/widgets/Button.hpp>
|
||||||
#include <ogfx/gui/widgets/ColorPicker.hpp>
|
#include <ogfx/gui/widgets/ColorPicker.hpp>
|
||||||
|
#include <ogfx/gui/ContextMenu.hpp>
|
||||||
|
|
||||||
namespace ogfx
|
namespace ogfx
|
||||||
{
|
{
|
||||||
|
|
@ -87,7 +88,8 @@ namespace ogfx
|
||||||
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;
|
||||||
void onMouseReleased(const Event& event) override;
|
void onMouseReleased(const Event& event) override;
|
||||||
void onUpdate(void) override;
|
void onMousePressed(const Event& event) override;
|
||||||
|
void handleSignal(ostd::Signal& signal) override;
|
||||||
|
|
||||||
inline Color getColor(void) const { return m_color; }
|
inline Color getColor(void) const { return m_color; }
|
||||||
void setColor(const Color& c);
|
void setColor(const Color& c);
|
||||||
|
|
@ -111,8 +113,16 @@ namespace ogfx
|
||||||
// the widget tree clean.
|
// the widget tree clean.
|
||||||
ColorPicker* m_popup { nullptr };
|
ColorPicker* m_popup { nullptr };
|
||||||
bool m_popupOpen { false };
|
bool m_popupOpen { false };
|
||||||
|
bool m_mousePressedHere { false };
|
||||||
|
|
||||||
std::function<void(const Color&)> callback_onColorChanged { nullptr };
|
std::function<void(const Color&)> callback_onColorChanged { nullptr };
|
||||||
|
|
||||||
|
enum MenuId : i32 { Copy = 1, Paste };
|
||||||
|
ContextMenu::Instance m_contextMenu {{
|
||||||
|
{ "Copy Color", MenuId::Copy },
|
||||||
|
{ "Paste Color", MenuId::Paste },
|
||||||
|
}, nullptr
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -360,16 +360,11 @@ namespace ogfx
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::__onDragAndDrop(const Event& event)
|
void Widget::__onDragAndDrop(const Event& event)
|
||||||
{
|
|
||||||
if (hasChildren())
|
|
||||||
m_widgets.onMouseReleased(event);
|
|
||||||
if (!event.isHandled())
|
|
||||||
{
|
{
|
||||||
if (callback_onDragAndDrop)
|
if (callback_onDragAndDrop)
|
||||||
callback_onDragAndDrop(event);
|
callback_onDragAndDrop(event);
|
||||||
onDragAndDrop(event);
|
onDragAndDrop(event);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::__onMouseMoved(const Event& event)
|
void Widget::__onMouseMoved(const Event& event)
|
||||||
{
|
{
|
||||||
|
|
@ -424,6 +419,7 @@ namespace ogfx
|
||||||
|
|
||||||
void Widget::__onMouseDragged(const Event& event)
|
void Widget::__onMouseDragged(const Event& event)
|
||||||
{
|
{
|
||||||
|
m_mouseInside = contains(event.mouse->position_x, event.mouse->position_y);
|
||||||
if (event.isHandled() || !isMouseDraggedEventEnabled()) return;
|
if (event.isHandled() || !isMouseDraggedEventEnabled()) return;
|
||||||
if (hasChildren())
|
if (hasChildren())
|
||||||
m_widgets.onMouseDragged(event);
|
m_widgets.onMouseDragged(event);
|
||||||
|
|
|
||||||
|
|
@ -97,110 +97,11 @@ namespace ostd
|
||||||
|
|
||||||
Color& Color::set(const String& color_string)
|
Color& Color::set(const String& color_string)
|
||||||
{
|
{
|
||||||
String se(color_string);
|
if (!isValidColorString(color_string, this))
|
||||||
se.trim();
|
|
||||||
|
|
||||||
// --- Step 1: Extract optional .lighten(x) or .darken(x) suffix ---
|
|
||||||
enum class Modifier { None, Lighten, Darken };
|
|
||||||
Modifier mod = Modifier::None;
|
|
||||||
f32 modAmount = 0.0f;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
stdvec<String> matches;
|
OX_WARN("ostd::Color::set(const String&) -> Invalid color string: %s", color_string.c_str());
|
||||||
auto positions = se.regexFind("\\.(lighten|darken)\\(\\s*([0-9]*\\.?[0-9]+)\\s*\\)\\s*$", true, &matches);
|
r = 0; g = 0; b = 0; a = 255; // match original default-on-failure
|
||||||
|
|
||||||
if (!positions.empty())
|
|
||||||
{
|
|
||||||
const String& whole = matches[0];
|
|
||||||
mod = whole.contains("lighten") ? Modifier::Lighten : Modifier::Darken;
|
|
||||||
|
|
||||||
// Extract the number between '(' and ')'
|
|
||||||
u32 openParen = whole.indexOf("(");
|
|
||||||
u32 closeParen = whole.indexOf(")");
|
|
||||||
String numStr = whole.new_substr(openParen + 1, closeParen);
|
|
||||||
numStr.trim();
|
|
||||||
modAmount = numStr.toFloat();
|
|
||||||
|
|
||||||
// Clamp to [0, 1]
|
|
||||||
if (modAmount < 0.0f) modAmount = 0.0f;
|
|
||||||
if (modAmount > 1.0f) modAmount = 1.0f;
|
|
||||||
|
|
||||||
// Strip the suffix from se
|
|
||||||
se = se.substr(0, positions[0]);
|
|
||||||
se.trim();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// --- Step 2: Default values ---
|
|
||||||
r = 0;
|
|
||||||
g = 0;
|
|
||||||
b = 0;
|
|
||||||
a = 255;
|
|
||||||
|
|
||||||
// --- Step 3: Normalize "#" prefix to "0x" ---
|
|
||||||
if (se.startsWith("#"))
|
|
||||||
{
|
|
||||||
String tmp = se.new_substr(1);
|
|
||||||
tmp.trim();
|
|
||||||
se = String("0x") + tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Step 4: Parse the color body ---
|
|
||||||
if (se.startsWith("0x"))
|
|
||||||
{
|
|
||||||
String hexPart = se.new_substr(2);
|
|
||||||
hexPart.trim();
|
|
||||||
u32 hexDigits = hexPart.len();
|
|
||||||
|
|
||||||
i64 ic = se.toInt();
|
|
||||||
u32 c = static_cast<u32>(ic);
|
|
||||||
|
|
||||||
if (hexDigits <= 6)
|
|
||||||
{
|
|
||||||
// RGB only — alpha defaults to 255
|
|
||||||
r = (c >> 16) & 0xFF;
|
|
||||||
g = (c >> 8) & 0xFF;
|
|
||||||
b = (c >> 0) & 0xFF;
|
|
||||||
a = 255;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// RGBA — 7 or 8 digits
|
|
||||||
r = (c >> 24) & 0xFF;
|
|
||||||
g = (c >> 16) & 0xFF;
|
|
||||||
b = (c >> 8) & 0xFF;
|
|
||||||
a = (c >> 0) & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((se.startsWith("(") || se.startsWith("rgba(") || se.startsWith("rgb("))
|
|
||||||
&& se.endsWith(")") && se.contains(","))
|
|
||||||
{
|
|
||||||
se = se.substr(se.indexOf("(") + 1, se.len() - 1);
|
|
||||||
se.trim();
|
|
||||||
auto tokens = se.tokenize(",", true, false);
|
|
||||||
if (tokens.count() < 3 || tokens.count() > 4)
|
|
||||||
{
|
|
||||||
OX_WARN("ostd::Color::set(const String&) -> Invalid rgb string format: %s.", color_string.c_str());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
r = tokens.next().toInt();
|
|
||||||
g = tokens.next().toInt();
|
|
||||||
b = tokens.next().toInt();
|
|
||||||
if (tokens.hasNext())
|
|
||||||
a = tokens.next().toInt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OX_WARN("ostd::Color::set(const String&) -> Unknown color string format: %s", color_string.c_str());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Step 5: Apply lighten/darken modifier ---
|
|
||||||
if (mod == Modifier::Lighten)
|
|
||||||
lighten(modAmount);
|
|
||||||
else if (mod == Modifier::Darken)
|
|
||||||
darken(modAmount);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,4 +263,105 @@ namespace ostd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Color::isValidColorString(const String& str, Color* out)
|
||||||
|
{
|
||||||
|
String se(str);
|
||||||
|
se.trim();
|
||||||
|
if (se.len() == 0) return false;
|
||||||
|
|
||||||
|
// --- Step 1: Extract optional .lighten(x) / .darken(x) suffix ---
|
||||||
|
enum class Modifier { None, Lighten, Darken };
|
||||||
|
Modifier mod = Modifier::None;
|
||||||
|
f32 modAmount = 0.0f;
|
||||||
|
{
|
||||||
|
stdvec<String> matches;
|
||||||
|
auto positions = se.regexFind(
|
||||||
|
"\\.(lighten|darken)\\(\\s*([0-9]*\\.?[0-9]+)\\s*\\)\\s*$",
|
||||||
|
true, &matches);
|
||||||
|
if (!positions.empty())
|
||||||
|
{
|
||||||
|
const String& whole = matches[0];
|
||||||
|
mod = whole.contains("lighten") ? Modifier::Lighten : Modifier::Darken;
|
||||||
|
|
||||||
|
const u32 openParen = whole.indexOf("(");
|
||||||
|
const u32 closeParen = whole.indexOf(")");
|
||||||
|
String numStr = whole.new_substr(openParen + 1, closeParen);
|
||||||
|
numStr.trim();
|
||||||
|
modAmount = numStr.toFloat();
|
||||||
|
if (modAmount < 0.0f) modAmount = 0.0f;
|
||||||
|
if (modAmount > 1.0f) modAmount = 1.0f;
|
||||||
|
|
||||||
|
se = se.new_substr(0, positions[0]);
|
||||||
|
se.trim();
|
||||||
|
}
|
||||||
|
if (se.len() == 0) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local working color — only written back to *out if everything validates.
|
||||||
|
u8 rr = 0, gg = 0, bb = 0, aa = 255;
|
||||||
|
|
||||||
|
// --- Step 2: Normalize "#" prefix to "0x" ---
|
||||||
|
if (se.startsWith("#"))
|
||||||
|
se = String("0x") + se.new_substr(1).trim();
|
||||||
|
|
||||||
|
// --- Step 3a: Hex form ---
|
||||||
|
if (se.toLower().startsWith("0x"))
|
||||||
|
{
|
||||||
|
if (!se.isHex()) return false;
|
||||||
|
const u32 digits = se.len() - 2;
|
||||||
|
if (digits < 1 || digits > 8) return false;
|
||||||
|
|
||||||
|
const u32 c = static_cast<u32>(se.toInt());
|
||||||
|
if (digits <= 6)
|
||||||
|
{
|
||||||
|
rr = (c >> 16) & 0xFF;
|
||||||
|
gg = (c >> 8) & 0xFF;
|
||||||
|
bb = (c >> 0) & 0xFF;
|
||||||
|
aa = 255;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rr = (c >> 24) & 0xFF;
|
||||||
|
gg = (c >> 16) & 0xFF;
|
||||||
|
bb = (c >> 8) & 0xFF;
|
||||||
|
aa = (c >> 0) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// --- Step 3b: Functional form ---
|
||||||
|
else if ((se.startsWith("(") || se.startsWith("rgb(") || se.startsWith("rgba("))
|
||||||
|
&& se.endsWith(")") && se.contains(","))
|
||||||
|
{
|
||||||
|
String inner = se.new_substr(se.indexOf("(") + 1, se.len() - 1).trim();
|
||||||
|
auto tokens = inner.tokenize(",", true, false);
|
||||||
|
const u32 n = tokens.count();
|
||||||
|
if (n < 3 || n > 4) return false;
|
||||||
|
|
||||||
|
i64 vals[4] = { 0, 0, 0, 255 };
|
||||||
|
for (u32 i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
String tok = tokens.next();
|
||||||
|
if (tok.len() == 0 || !tok.isInt()) return false;
|
||||||
|
const i64 v = tok.toInt();
|
||||||
|
if (v < 0 || v > 255) return false;
|
||||||
|
vals[i] = v;
|
||||||
|
}
|
||||||
|
rr = static_cast<u8>(vals[0]);
|
||||||
|
gg = static_cast<u8>(vals[1]);
|
||||||
|
bb = static_cast<u8>(vals[2]);
|
||||||
|
aa = static_cast<u8>(vals[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Step 4: Build the output color and apply modifier ---
|
||||||
|
if (out != nullptr)
|
||||||
|
{
|
||||||
|
out->set(rr, gg, bb, aa);
|
||||||
|
if (mod == Modifier::Lighten) out->lighten(modAmount);
|
||||||
|
else if (mod == Modifier::Darken) out->darken(modAmount);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,8 @@ namespace ostd
|
||||||
static void RGBtoHSV(f32 r, f32 g, f32 b, f32& h, f32& s, f32& v);
|
static void RGBtoHSV(f32 r, f32 g, f32 b, f32& h, f32& s, f32& v);
|
||||||
static void HSVtoRGB(f32 h, f32 s, f32 v, f32& r, f32& g, f32& b);
|
static void HSVtoRGB(f32 h, f32 s, f32 v, f32& r, f32& g, f32& b);
|
||||||
|
|
||||||
|
static bool isValidColorString(const String& str, Color* out = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Channel r;
|
Channel r;
|
||||||
Channel g;
|
Channel g;
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,7 @@ class TestWindow : public Window
|
||||||
t1.addWidget(m_text, { 400, 700 });
|
t1.addWidget(m_text, { 400, 700 });
|
||||||
t1.addWidget(m_colBtn, { 800, 700 });
|
t1.addWidget(m_colBtn, { 800, 700 });
|
||||||
t1.addWidget(m_colBtn2, { 950, 700 });
|
t1.addWidget(m_colBtn2, { 950, 700 });
|
||||||
|
t1.addWidget(m_colPan, { 1200, 700 });
|
||||||
|
|
||||||
t2.setLayout<BoxLayout>(BoxLayout::Orientation::Vertical);
|
t2.setLayout<BoxLayout>(BoxLayout::Orientation::Vertical);
|
||||||
t2.getLayout()->setSpacing(16);
|
t2.getLayout()->setSpacing(16);
|
||||||
|
|
@ -347,9 +348,9 @@ class TestWindow : public Window
|
||||||
}
|
}
|
||||||
else if (signal.ID == ostd::BuiltinSignals::MouseReleased)
|
else if (signal.ID == ostd::BuiltinSignals::MouseReleased)
|
||||||
{
|
{
|
||||||
auto& mmd = cast<ogfx::MouseEventData&>(signal.userData);
|
// auto& mmd = cast<ogfx::MouseEventData&>(signal.userData);
|
||||||
if (mmd.button == ogfx::MouseEventData::eButton::Right)
|
// if (mmd.button == ogfx::MouseEventData::eButton::Right)
|
||||||
showContextMenu(m_menu, { mmd.position_x, mmd.position_y });
|
// showContextMenu(m_menu, { mmd.position_x, mmd.position_y });
|
||||||
}
|
}
|
||||||
else if (signal.ID == ostd::BuiltinSignals::WindowResized)
|
else if (signal.ID == ostd::BuiltinSignals::WindowResized)
|
||||||
{
|
{
|
||||||
|
|
@ -398,6 +399,7 @@ class TestWindow : public Window
|
||||||
TextEdit m_text { *this };
|
TextEdit m_text { *this };
|
||||||
ColorButton m_colBtn { *this };
|
ColorButton m_colBtn { *this };
|
||||||
ColorButton m_colBtn2 { *this };
|
ColorButton m_colBtn2 { *this };
|
||||||
|
ColorPicker m_colPan { *this };
|
||||||
|
|
||||||
enum MenuId : i32 { New = 1, Open, Save, SaveAs, Exit, CopyRaw, CopyFormatted };
|
enum MenuId : i32 { New = 1, Open, Save, SaveAs, Exit, CopyRaw, CopyFormatted };
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue