Separated color picker element into 3 different GUI elements
This commit is contained in:
parent
515b591ee8
commit
b5d4c38024
16 changed files with 599 additions and 219 deletions
73
src/GUIStuff/Elements/AlphaSlider.cpp
Normal file
73
src/GUIStuff/Elements/AlphaSlider.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include "AlphaSlider.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
#include "ColorPicker.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
AlphaSlider::AlphaSlider(GUIManager& gui): Element(gui) {}
|
||||
|
||||
void AlphaSlider::layout(const Clay_ElementId& id, const AlphaSliderData& opts) {
|
||||
o = opts;
|
||||
update();
|
||||
|
||||
CLAY(id, {
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}},
|
||||
.custom = {.customData = this}
|
||||
}) {
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaSlider::update() {
|
||||
if(currentG != *o.g || currentB != *o.b || currentR != *o.r || currentAlpha != *o.alpha) {
|
||||
currentR = *o.r;
|
||||
currentG = *o.g;
|
||||
currentB = *o.b;
|
||||
currentAlpha = *o.alpha;
|
||||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaSlider::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(mouseHovering && button.down && button.button == InputManager::MouseButton::LEFT) {
|
||||
if(o.onHold) o.onHold();
|
||||
update_alpha(button.pos);
|
||||
if(o.onChange) o.onChange();
|
||||
isHeld = true;
|
||||
}
|
||||
else if(isHeld && !button.down && button.button == InputManager::MouseButton::LEFT) {
|
||||
if(o.onRelease) o.onRelease();
|
||||
isHeld = false;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaSlider::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(isHeld) {
|
||||
update_alpha(motion.pos);
|
||||
if(o.onChange) o.onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaSlider::update_alpha(Vector2f p) {
|
||||
*o.alpha = std::clamp((p.x() - boundingBox.value().min.x()) / boundingBox.value().width(), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void AlphaSlider::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {
|
||||
auto& bb = boundingBox.value();
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(bb.min.x(), bb.min.y());
|
||||
canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, bb.width(), bb.height()), skiaAA);
|
||||
|
||||
SkPaint alphaBarPaint;
|
||||
alphaBarPaint.setShader(ColorPickerShaders::get_alpha_bar_shader({currentR, currentG, currentB}, bb.width()));
|
||||
canvas->drawPaint(alphaBarPaint);
|
||||
|
||||
SkPaint selectionLinePaint({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
selectionLinePaint.setAntiAlias(skiaAA);
|
||||
selectionLinePaint.setStrokeWidth(1.0f);
|
||||
canvas->drawLine(currentAlpha * bb.width(), 0.0f, currentAlpha * bb.width(), bb.height(), selectionLinePaint);
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
}
|
||||
36
src/GUIStuff/Elements/AlphaSlider.hpp
Normal file
36
src/GUIStuff/Elements/AlphaSlider.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
struct AlphaSliderData {
|
||||
float* alpha = nullptr;
|
||||
float* r = nullptr;
|
||||
float* g = nullptr;
|
||||
float* b = nullptr;
|
||||
std::function<void()> onChange;
|
||||
std::function<void()> onHold;
|
||||
std::function<void()> onRelease;
|
||||
};
|
||||
|
||||
class AlphaSlider : public Element {
|
||||
public:
|
||||
AlphaSlider(GUIManager& gui);
|
||||
|
||||
void layout(const Clay_ElementId& id, const AlphaSliderData& opts);
|
||||
virtual void update() override;
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
|
||||
|
||||
private:
|
||||
void update_alpha(Vector2f p);
|
||||
AlphaSliderData o;
|
||||
float currentAlpha = -1.0f;
|
||||
float currentR = -1.0f;
|
||||
float currentG = -1.0f;
|
||||
float currentB = -1.0f;
|
||||
bool isHeld = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
#include <include/core/SkColor.h>
|
||||
#include <include/core/SkPath.h>
|
||||
#include <include/effects/SkRuntimeEffect.h>
|
||||
#include <iostream>
|
||||
#include <Helpers/SCollision.hpp>
|
||||
#include <Helpers/HsvRgb.hpp>
|
||||
|
||||
|
|
@ -67,44 +66,17 @@ struct ColorPickerData {
|
|||
template <typename T> class ColorPicker : public Element {
|
||||
public:
|
||||
ColorPicker(GUIManager& gui);
|
||||
void layout(const Clay_ElementId& id, T* data, bool selectAlpha, const ColorPickerData& config);
|
||||
virtual void update() override;
|
||||
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
|
||||
void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
void layout(const Clay_ElementId& id, T* data, bool selectAlpha, const ColorPickerData& conf = {});
|
||||
private:
|
||||
void update_color_picker_pos(const Vector2f& p, bool justHeld);
|
||||
float get_sv_selection_area_size();
|
||||
Vector2f get_hue_bar_pos();
|
||||
Vector2f get_hue_bar_dim();
|
||||
Vector2f get_alpha_bar_pos();
|
||||
Vector2f get_alpha_bar_dim();
|
||||
void set_hsv(const Vector3f& hsv);
|
||||
void set_rgb_from_hsv(const Vector3f& hsv);
|
||||
|
||||
static constexpr float BAR_WIDTH = 30.0;
|
||||
static constexpr float BAR_GAP = 5.0;
|
||||
|
||||
struct DisplayData {
|
||||
Vector3f savedHsv = {0.0f, 0.0f, 0.0f};
|
||||
float savedAlpha = 0.0f;
|
||||
bool operator!=(const DisplayData&) const = default;
|
||||
bool operator==(const DisplayData&) const = default;
|
||||
};
|
||||
|
||||
DisplayData dd;
|
||||
DisplayData oldDD;
|
||||
static constexpr uint16_t BAR_GAP = 5;
|
||||
|
||||
Vector3f savedHsv = {0.0f, 0.0f, 0.0f};
|
||||
T* data;
|
||||
std::optional<T> oldData;
|
||||
ColorPickerData config;
|
||||
bool selectAlpha = false;
|
||||
enum class HeldBar {
|
||||
NONE,
|
||||
SV_HELD,
|
||||
HUE_HELD,
|
||||
ALPHA_HELD
|
||||
};
|
||||
HeldBar held = HeldBar::NONE;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,192 +1,116 @@
|
|||
#pragma once
|
||||
#include "ColorPicker.decl.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
#include "SaturationValueSquare.hpp"
|
||||
#include "HueVerticalSlider.hpp"
|
||||
#include "AlphaSlider.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
template <typename T> ColorPicker<T>::ColorPicker(GUIManager& gui): Element(gui) {}
|
||||
|
||||
template <typename T> void ColorPicker<T>::layout(const Clay_ElementId& id, T* data, bool selectAlpha, const ColorPickerData& config) {
|
||||
template <typename T> void ColorPicker<T>::layout(const Clay_ElementId& id, T* data, bool selectAlpha, const ColorPickerData& conf) {
|
||||
this->data = data;
|
||||
if(!oldData.has_value() || oldData.value() != *data) {
|
||||
dd.savedHsv = rgb_to_hsv<Vector3f, T>(*data);
|
||||
savedHsv = rgb_to_hsv<Vector3f, T>(*data);
|
||||
oldData = *data;
|
||||
}
|
||||
if(selectAlpha)
|
||||
dd.savedAlpha = (*data)[3];
|
||||
|
||||
this->selectAlpha = selectAlpha;
|
||||
this->config = config;
|
||||
config = conf;
|
||||
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }
|
||||
},
|
||||
.aspectRatio = {1.0f},
|
||||
.custom = { .customData = this }
|
||||
}) {}
|
||||
}
|
||||
|
||||
template <typename T> void ColorPicker<T>::update() {
|
||||
if(dd != oldDD) {
|
||||
gui.invalidate_draw_element(this);
|
||||
oldDD = dd;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void ColorPicker<T>::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {
|
||||
auto& bb = boundingBox.value();
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(bb.min.x(), bb.min.y());
|
||||
float svSelectionAreaSize = get_sv_selection_area_size();
|
||||
canvas->scale(svSelectionAreaSize, svSelectionAreaSize);
|
||||
canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, 1.0f, 1.0f), skiaAA);
|
||||
|
||||
SkPaint svSelectionAreaPaint;
|
||||
svSelectionAreaPaint.setShader(ColorPickerShaders::get_sv_selection_shader(dd.savedHsv.x() / 360.0f));
|
||||
canvas->drawPaint(svSelectionAreaPaint);
|
||||
|
||||
SkPaint selectionLinePaint({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
selectionLinePaint.setAntiAlias(skiaAA);
|
||||
selectionLinePaint.setStrokeWidth(2.0f / svSelectionAreaSize);
|
||||
canvas->drawLine(0.0f, 1.0f - dd.savedHsv.z(), 1.0f, 1.0f - dd.savedHsv.z(), selectionLinePaint);
|
||||
canvas->drawLine(dd.savedHsv.y(), 0.0f, dd.savedHsv.y(), 1.0f, selectionLinePaint);
|
||||
|
||||
canvas->restore();
|
||||
|
||||
float normalizedHue = dd.savedHsv.x() / 360.0f;
|
||||
|
||||
Vector2f hueBarPos = get_hue_bar_pos();
|
||||
Vector2f hueBarDim = get_hue_bar_dim();
|
||||
canvas->save();
|
||||
canvas->translate(hueBarPos.x(), hueBarPos.y());
|
||||
canvas->scale(hueBarDim.x(), hueBarDim.y());
|
||||
canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, 1.0f, 1.0f), skiaAA);
|
||||
|
||||
SkPaint hueBarPaint;
|
||||
hueBarPaint.setShader(ColorPickerShaders::get_hue_shader());
|
||||
canvas->drawPaint(hueBarPaint);
|
||||
canvas->drawLine(0.0f, 1.0f - normalizedHue, 1.0f, 1.0f - normalizedHue, selectionLinePaint);
|
||||
|
||||
canvas->restore();
|
||||
|
||||
Vector2f alphaBarPos = get_alpha_bar_pos();
|
||||
Vector2f alphaBarDim = get_alpha_bar_dim();
|
||||
canvas->save();
|
||||
canvas->translate(alphaBarPos.x(), alphaBarPos.y());
|
||||
canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, alphaBarDim.x(), alphaBarDim.y()), skiaAA);
|
||||
|
||||
SkPaint alphaBarPaint;
|
||||
if(selectAlpha)
|
||||
alphaBarPaint.setShader(ColorPickerShaders::get_alpha_bar_shader({(*data)[0], (*data)[1], (*data)[2]}, alphaBarDim.x()));
|
||||
else
|
||||
alphaBarPaint.setColor4f(SkColor4f{(*data)[0], (*data)[1], (*data)[2], 1.0f});
|
||||
canvas->drawPaint(alphaBarPaint);
|
||||
auto onChange = [&] {
|
||||
set_rgb_from_hsv(savedHsv);
|
||||
if(config.onChange) config.onChange();
|
||||
};
|
||||
|
||||
if(selectAlpha) {
|
||||
canvas->scale(alphaBarDim.x(), alphaBarDim.y());
|
||||
canvas->drawLine((*data)[3], 0.0f, (*data)[3], 1.0f, selectionLinePaint);
|
||||
}
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
template <typename T> void ColorPicker<T>::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
HeldBar oldHeld = held;
|
||||
held = HeldBar::NONE;
|
||||
if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down && boundingBox.has_value()) {
|
||||
auto& bb = boundingBox.value();
|
||||
float svSelectionAreaSize = get_sv_selection_area_size();
|
||||
if(SCollision::collide(SCollision::AABB<float>(bb.min, bb.min + Vector2f{svSelectionAreaSize, svSelectionAreaSize}), button.pos))
|
||||
held = HeldBar::SV_HELD;
|
||||
else {
|
||||
Vector2f hueBarPos = get_hue_bar_pos();
|
||||
Vector2f hueBarDim = get_hue_bar_dim();
|
||||
if(SCollision::collide(SCollision::AABB<float>(hueBarPos, hueBarPos + hueBarDim), button.pos))
|
||||
held = HeldBar::HUE_HELD;
|
||||
else if(selectAlpha) {
|
||||
Vector2f alphaBarPos = get_alpha_bar_pos();
|
||||
Vector2f alphaBarDim = get_alpha_bar_dim();
|
||||
if(SCollision::collide(SCollision::AABB<float>(alphaBarPos, alphaBarPos + alphaBarDim), button.pos))
|
||||
held = HeldBar::ALPHA_HELD;
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) },
|
||||
.childGap = BAR_GAP,
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
}
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.childGap = BAR_GAP,
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
},
|
||||
}) {
|
||||
gui.element<SaturationValueSquare>("sv square", SaturationValueSquareData{
|
||||
.saturation = &savedHsv.y(),
|
||||
.value = &savedHsv.z(),
|
||||
.hue = &savedHsv.x(),
|
||||
.onChange = onChange,
|
||||
.onHold = config.onHold,
|
||||
.onRelease = config.onRelease
|
||||
});
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(BAR_WIDTH), .height = CLAY_SIZING_GROW(0)}
|
||||
},
|
||||
}) {
|
||||
gui.element<HueVerticalSlider>("hue slider", HueVerticalSliderData{
|
||||
.hue = &savedHsv.x(),
|
||||
.onChange = onChange,
|
||||
.onHold = config.onHold,
|
||||
.onRelease = config.onRelease
|
||||
});
|
||||
}
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(BAR_WIDTH)}
|
||||
},
|
||||
}) {
|
||||
gui.element<AlphaSlider>("alpha slider", AlphaSliderData{
|
||||
.alpha = &(*data)[3],
|
||||
.r = &(*data)[0],
|
||||
.g = &(*data)[1],
|
||||
.b = &(*data)[2],
|
||||
.onChange = onChange,
|
||||
.onHold = config.onHold,
|
||||
.onRelease = config.onRelease
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if(oldHeld != HeldBar::NONE && held == HeldBar::NONE) {
|
||||
gui.set_post_callback_func([&] {
|
||||
if(config.onRelease) config.onRelease();
|
||||
});
|
||||
}
|
||||
update_color_picker_pos(button.pos, true);
|
||||
}
|
||||
|
||||
template <typename T> void ColorPicker<T>::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
update_color_picker_pos(motion.pos, false);
|
||||
}
|
||||
|
||||
template <typename T> void ColorPicker<T>::update_color_picker_pos(const Vector2f& p, bool justHeld) {
|
||||
if(held != HeldBar::NONE && boundingBox.has_value()) {
|
||||
gui.set_post_callback_func([&, p, justHeld]() {
|
||||
auto& bb = boundingBox.value();
|
||||
switch(held) {
|
||||
case HeldBar::NONE:
|
||||
break;
|
||||
case HeldBar::SV_HELD: {
|
||||
float svSelectionAreaSize = bb.width() - (BAR_GAP + BAR_WIDTH);
|
||||
Vector2f newSv = cwise_vec_clamp<Vector2f>((p - bb.min) / svSelectionAreaSize, Vector2f{0.0f, 0.0f}, Vector2f{1.0f, 1.0f});
|
||||
dd.savedHsv.y() = newSv.x();
|
||||
dd.savedHsv.z() = 1.0f - newSv.y();
|
||||
set_hsv(dd.savedHsv);
|
||||
if(justHeld && config.onHold) config.onHold();
|
||||
if(config.onChange) config.onChange();
|
||||
break;
|
||||
}
|
||||
case HeldBar::HUE_HELD: {
|
||||
Vector2f huePos = get_hue_bar_pos();
|
||||
Vector2f hueDim = get_hue_bar_dim();
|
||||
dd.savedHsv.x() = (1.0f - std::clamp((p.y() - huePos.y()) / hueDim.y(), 0.0f, 1.0f)) * 360.0f;
|
||||
set_hsv(dd.savedHsv);
|
||||
if(justHeld && config.onHold) config.onHold();
|
||||
if(config.onChange) config.onChange();
|
||||
break;
|
||||
}
|
||||
case HeldBar::ALPHA_HELD: {
|
||||
Vector2f alphaPos = get_alpha_bar_pos();
|
||||
Vector2f alphaDim = get_alpha_bar_dim();
|
||||
(*data)[3] = std::clamp((p.x() - alphaPos.x()) / alphaDim.x(), 0.0f, 1.0f);
|
||||
dd.savedAlpha = (*data)[3];
|
||||
oldData = *data;
|
||||
if(justHeld && config.onHold) config.onHold();
|
||||
if(config.onChange) config.onChange();
|
||||
break;
|
||||
}
|
||||
else {
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.childGap = BAR_GAP,
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
},
|
||||
}) {
|
||||
gui.element<SaturationValueSquare>("sv square", SaturationValueSquareData{
|
||||
.saturation = &savedHsv.y(),
|
||||
.value = &savedHsv.z(),
|
||||
.hue = &savedHsv.x(),
|
||||
.onChange = onChange,
|
||||
.onHold = config.onHold,
|
||||
.onRelease = config.onRelease
|
||||
});
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(BAR_WIDTH), .height = CLAY_SIZING_GROW(0)},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
},
|
||||
}) {
|
||||
gui.element<HueVerticalSlider>("hue slider", HueVerticalSliderData{
|
||||
.hue = &savedHsv.x(),
|
||||
.onChange = onChange,
|
||||
.onHold = config.onHold,
|
||||
.onRelease = config.onRelease
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> float ColorPicker<T>::get_sv_selection_area_size() {
|
||||
return boundingBox.value().width() - (BAR_GAP + BAR_WIDTH);
|
||||
}
|
||||
|
||||
template <typename T> Vector2f ColorPicker<T>::get_hue_bar_pos() {
|
||||
return {boundingBox.value().min.x() + get_sv_selection_area_size() + BAR_GAP, boundingBox.value().min.y()};
|
||||
}
|
||||
|
||||
template <typename T> Vector2f ColorPicker<T>::get_hue_bar_dim() {
|
||||
return {BAR_WIDTH, get_sv_selection_area_size()};
|
||||
}
|
||||
|
||||
template <typename T> Vector2f ColorPicker<T>::get_alpha_bar_pos() {
|
||||
return {boundingBox.value().min.x(), boundingBox.value().min.y() + get_sv_selection_area_size() + BAR_GAP};
|
||||
}
|
||||
|
||||
template <typename T> Vector2f ColorPicker<T>::get_alpha_bar_dim() {
|
||||
return {boundingBox.value().width(), BAR_WIDTH};
|
||||
}
|
||||
|
||||
template <typename T> void ColorPicker<T>::set_hsv(const Vector3f& hsv) {
|
||||
template <typename T> void ColorPicker<T>::set_rgb_from_hsv(const Vector3f& hsv) {
|
||||
Vector3f a = hsv_to_rgb<Vector3f>(hsv);
|
||||
(*data)[0] = a.x();
|
||||
(*data)[1] = a.y();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ struct DropdownOptions {
|
|||
|
||||
template <typename T> class DropDown : public Element {
|
||||
public:
|
||||
static constexpr float ENTRY_HEIGHT = 27.0f;
|
||||
static constexpr float DROPDOWN_OFFSET = 4.0f;
|
||||
|
||||
DropDown(GUIManager& gui): Element(gui) {}
|
||||
|
|
@ -61,6 +60,7 @@ template <typename T> class DropDown : public Element {
|
|||
|
||||
if(isOpen && boundingBox.has_value()) {
|
||||
auto& buttonBB = boundingBox.value();
|
||||
float ENTRY_HEIGHT = buttonBB.height();
|
||||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
gui.element<LayoutElement>("DROPDOWN", [&](LayoutElement* l, const Clay_ElementId& lId) {
|
||||
float dropdownHeight = ENTRY_HEIGHT * selections.size() + DROPDOWN_OFFSET;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,12 @@ namespace GUIStuff {
|
|||
void Element::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { }
|
||||
void Element::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { }
|
||||
void Element::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) { }
|
||||
void Element::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) { }
|
||||
void Element::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) { }
|
||||
void Element::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) {
|
||||
input_mouse_button_callback(InputManager::convert_finger_touch_to_mouse_button(touch));
|
||||
}
|
||||
void Element::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) {
|
||||
input_mouse_motion_callback(InputManager::convert_finger_motion_to_mouse_motion(motion));
|
||||
}
|
||||
void Element::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
|
||||
void Element::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {}
|
||||
|
|
|
|||
75
src/GUIStuff/Elements/HueVerticalSlider.cpp
Normal file
75
src/GUIStuff/Elements/HueVerticalSlider.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#include "HueVerticalSlider.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
#include "ColorPicker.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
HueVerticalSlider::HueVerticalSlider(GUIManager& gui): Element(gui) {}
|
||||
|
||||
void HueVerticalSlider::layout(const Clay_ElementId& id, const HueVerticalSliderData& opts) {
|
||||
o = opts;
|
||||
update();
|
||||
|
||||
CLAY(id, {
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}},
|
||||
.custom = {.customData = this}
|
||||
}) {
|
||||
}
|
||||
}
|
||||
|
||||
void HueVerticalSlider::update() {
|
||||
if(currentHue != *o.hue) {
|
||||
currentHue = *o.hue;
|
||||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
}
|
||||
|
||||
void HueVerticalSlider::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(mouseHovering && button.down && button.button == InputManager::MouseButton::LEFT) {
|
||||
if(o.onHold) o.onHold();
|
||||
update_hue(button.pos);
|
||||
if(o.onChange) o.onChange();
|
||||
isHeld = true;
|
||||
}
|
||||
else if(isHeld && !button.down && button.button == InputManager::MouseButton::LEFT) {
|
||||
if(o.onRelease) o.onRelease();
|
||||
isHeld = false;
|
||||
}
|
||||
}
|
||||
|
||||
void HueVerticalSlider::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(isHeld) {
|
||||
update_hue(motion.pos);
|
||||
if(o.onChange) o.onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void HueVerticalSlider::update_hue(Vector2f p) {
|
||||
*o.hue = (1.0f - std::clamp((p.y() - boundingBox.value().min.y()) / boundingBox.value().height(), 0.0f, 1.0f)) * 360.0f;
|
||||
}
|
||||
|
||||
void HueVerticalSlider::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {
|
||||
auto& bb = boundingBox.value();
|
||||
|
||||
float normalizedHue = currentHue / 360.0f;
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(bb.min.x(), bb.min.y());
|
||||
canvas->scale(bb.width(), bb.height());
|
||||
canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, 1.0f, 1.0f), skiaAA);
|
||||
SkPaint hueBarPaint;
|
||||
hueBarPaint.setShader(ColorPickerShaders::get_hue_shader());
|
||||
canvas->drawPaint(hueBarPaint);
|
||||
canvas->restore();
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(bb.min.x(), bb.min.y());
|
||||
SkPaint selectionLinePaint({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
selectionLinePaint.setAntiAlias(skiaAA);
|
||||
selectionLinePaint.setStrokeWidth(1.0f);
|
||||
float hueY = bb.height() * (1.0f - normalizedHue);
|
||||
canvas->drawLine(0.0f, hueY, bb.width(), hueY, selectionLinePaint);
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
}
|
||||
30
src/GUIStuff/Elements/HueVerticalSlider.hpp
Normal file
30
src/GUIStuff/Elements/HueVerticalSlider.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
struct HueVerticalSliderData {
|
||||
float* hue = nullptr;
|
||||
std::function<void()> onChange;
|
||||
std::function<void()> onHold;
|
||||
std::function<void()> onRelease;
|
||||
};
|
||||
|
||||
class HueVerticalSlider : public Element {
|
||||
public:
|
||||
HueVerticalSlider(GUIManager& gui);
|
||||
|
||||
void layout(const Clay_ElementId& id, const HueVerticalSliderData& opts);
|
||||
virtual void update() override;
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
|
||||
|
||||
private:
|
||||
void update_hue(Vector2f p);
|
||||
HueVerticalSliderData o;
|
||||
float currentHue = -1.0f;
|
||||
bool isHeld = false;
|
||||
};
|
||||
|
||||
}
|
||||
82
src/GUIStuff/Elements/SaturationValueSquare.cpp
Normal file
82
src/GUIStuff/Elements/SaturationValueSquare.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#include "SaturationValueSquare.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
#include "ColorPicker.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
SaturationValueSquare::SaturationValueSquare(GUIManager& gui): Element(gui) {}
|
||||
|
||||
void SaturationValueSquare::layout(const Clay_ElementId& id, const SaturationValueSquareData& opts) {
|
||||
o = opts;
|
||||
update();
|
||||
|
||||
CLAY(id, {
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}},
|
||||
.custom = {.customData = this}
|
||||
}) {
|
||||
}
|
||||
}
|
||||
|
||||
void SaturationValueSquare::update() {
|
||||
if(currentHue != *o.hue || currentSaturation != *o.saturation || currentValue != *o.value) {
|
||||
currentHue = *o.hue;
|
||||
currentSaturation = *o.saturation;
|
||||
currentValue = *o.value;
|
||||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
}
|
||||
|
||||
void SaturationValueSquare::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(mouseHovering && button.down && button.button == InputManager::MouseButton::LEFT) {
|
||||
if(o.onHold) o.onHold();
|
||||
update_sv(button.pos);
|
||||
if(o.onChange) o.onChange();
|
||||
isHeld = true;
|
||||
}
|
||||
else if(isHeld && !button.down && button.button == InputManager::MouseButton::LEFT) {
|
||||
if(o.onRelease) o.onRelease();
|
||||
isHeld = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SaturationValueSquare::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(isHeld) {
|
||||
update_sv(motion.pos);
|
||||
if(o.onChange) o.onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void SaturationValueSquare::update_sv(Vector2f p) {
|
||||
*o.saturation = std::clamp((p.x() - boundingBox.value().min.x()) / boundingBox.value().width(), 0.0f, 1.0f);
|
||||
*o.value = 1.0f - std::clamp((p.y() - boundingBox.value().min.y()) / boundingBox.value().height(), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void SaturationValueSquare::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {
|
||||
auto& bb = boundingBox.value();
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(bb.min.x(), bb.min.y());
|
||||
canvas->scale(bb.width(), bb.height());
|
||||
canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, 1.0f, 1.0f), skiaAA);
|
||||
|
||||
SkPaint svSelectionAreaPaint;
|
||||
svSelectionAreaPaint.setShader(ColorPickerShaders::get_sv_selection_shader(currentHue / 360.0f));
|
||||
canvas->drawPaint(svSelectionAreaPaint);
|
||||
canvas->restore();
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(bb.min.x(), bb.min.y());
|
||||
|
||||
SkPaint selectionLinePaint({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
selectionLinePaint.setAntiAlias(skiaAA);
|
||||
selectionLinePaint.setStrokeWidth(1.0f);
|
||||
|
||||
float valueY = bb.height() * (1.0f - currentValue);
|
||||
canvas->drawLine(0.0f, valueY, bb.width(), valueY, selectionLinePaint);
|
||||
float saturationX = bb.width() * currentSaturation;
|
||||
canvas->drawLine(saturationX, 0.0f, saturationX, bb.height(), selectionLinePaint);
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
}
|
||||
34
src/GUIStuff/Elements/SaturationValueSquare.hpp
Normal file
34
src/GUIStuff/Elements/SaturationValueSquare.hpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
struct SaturationValueSquareData {
|
||||
float* saturation = nullptr;
|
||||
float* value = nullptr;
|
||||
float* hue = nullptr;
|
||||
std::function<void()> onChange;
|
||||
std::function<void()> onHold;
|
||||
std::function<void()> onRelease;
|
||||
};
|
||||
|
||||
class SaturationValueSquare : public Element {
|
||||
public:
|
||||
SaturationValueSquare(GUIManager& gui);
|
||||
|
||||
void layout(const Clay_ElementId& id, const SaturationValueSquareData& opts);
|
||||
virtual void update() override;
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
|
||||
|
||||
private:
|
||||
void update_sv(Vector2f p);
|
||||
SaturationValueSquareData o;
|
||||
float currentHue = -1.0f;
|
||||
float currentSaturation = -1.0f;
|
||||
float currentValue = -1.0f;
|
||||
bool isHeld = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -624,6 +624,24 @@ void InputManager::backend_pen_axis_update(const SDL_PenAxisEvent& e) {
|
|||
}
|
||||
}
|
||||
|
||||
InputManager::MouseButtonCallbackArgs InputManager::convert_finger_touch_to_mouse_button(const FingerTouchCallbackArgs& touch) {
|
||||
return {
|
||||
.deviceType = InputManager::MouseDeviceType::TOUCH,
|
||||
.button = InputManager::MouseButton::LEFT,
|
||||
.down = touch.down,
|
||||
.clicks = static_cast<uint8_t>(touch.fingerTapCount),
|
||||
.pos = touch.pos
|
||||
};
|
||||
}
|
||||
|
||||
InputManager::MouseMotionCallbackArgs InputManager::convert_finger_motion_to_mouse_motion(const FingerMotionCallbackArgs& motion) {
|
||||
return {
|
||||
.deviceType = InputManager::MouseDeviceType::TOUCH,
|
||||
.pos = motion.pos,
|
||||
.move = motion.move
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<Vector2f> InputManager::get_multiple_finger_positions() {
|
||||
std::vector<Vector2f> pos;
|
||||
for(const SDL_TouchFingerEvent& fingerEvent : touch.fingers)
|
||||
|
|
|
|||
|
|
@ -395,6 +395,9 @@ struct InputManager {
|
|||
size_t fingerDownCount;
|
||||
};
|
||||
|
||||
static MouseButtonCallbackArgs convert_finger_touch_to_mouse_button(const FingerTouchCallbackArgs& touch);
|
||||
static MouseMotionCallbackArgs convert_finger_motion_to_mouse_motion(const FingerMotionCallbackArgs& motion);
|
||||
|
||||
struct WindowResizeCallbackArgs {
|
||||
Vector2i size;
|
||||
SCollision::AABB<float> safeArea;
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@
|
|||
#include "DrawingProgramScreen.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
#include "../GUIStuff/Elements/GridScrollArea.hpp"
|
||||
#include "../GUIStuff/Elements/DropDown.hpp"
|
||||
#include "../GUIStuff/Elements/ColorPicker.hpp"
|
||||
#include "../GUIStuff/ElementHelpers/ButtonHelpers.hpp"
|
||||
#include "../GUIStuff/ElementHelpers/LayoutHelpers.hpp"
|
||||
#include "../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
#include "../GUIStuff/ElementHelpers/TextBoxHelpers.hpp"
|
||||
#include "FileSelectScreen.hpp"
|
||||
#include <Helpers/Logger.hpp>
|
||||
|
||||
|
|
@ -112,8 +115,10 @@ void PhoneDrawingProgramScreen::bottom_toolbar() {
|
|||
}) {}
|
||||
switch(settingsMenuPopup) {
|
||||
case SettingsMenuPopup::NONE:
|
||||
reset_color_picker_popup_data();
|
||||
break;
|
||||
case SettingsMenuPopup::SETTINGS:
|
||||
reset_color_picker_popup_data();
|
||||
tool_settings_popup();
|
||||
break;
|
||||
case SettingsMenuPopup::FG_COLOR:
|
||||
|
|
@ -234,24 +239,25 @@ void PhoneDrawingProgramScreen::tool_settings_popup() {
|
|||
});
|
||||
}
|
||||
|
||||
void PhoneDrawingProgramScreen::reset_color_picker_popup_data() {
|
||||
colorPickerPopupData.extraSettingsOpen = false;
|
||||
colorPickerPopupData.addingPalette = false;
|
||||
colorPickerPopupData.newPaletteStr.clear();
|
||||
}
|
||||
|
||||
void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) {
|
||||
auto& gui = main.g.gui;
|
||||
auto& palette = main.conf.palettes[paletteData.selectedPalette];
|
||||
gui.element<LayoutElement>("color settings popup", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)},
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(gui.io.theme->windowCorners1)
|
||||
}) {
|
||||
gui.element<GridScrollArea>("color selector grid", GridScrollArea::Options{
|
||||
.entryWidth = BIG_BUTTON_SIZE,
|
||||
.childAlignmentX = CLAY_ALIGN_X_CENTER,
|
||||
.entryHeight = BIG_BUTTON_SIZE,
|
||||
.entryCount = palette.colors.size(),
|
||||
.scrollbar = ScrollArea::ScrollbarType::NORMAL,
|
||||
.elementContent = [&](size_t i) {
|
||||
auto& palette = main.conf.palettes[colorPickerPopupData.selectedPalette];
|
||||
|
||||
auto paletteColorPickerGrid = [&] {
|
||||
gui.element<GridScrollArea>("color selector grid", GridScrollArea::Options{
|
||||
.entryWidth = BIG_BUTTON_SIZE,
|
||||
.childAlignmentX = CLAY_ALIGN_X_CENTER,
|
||||
.entryHeight = BIG_BUTTON_SIZE,
|
||||
.entryCount = palette.colors.size() + 1,
|
||||
.scrollbar = ScrollArea::ScrollbarType::NORMAL,
|
||||
.elementContent = [&](size_t i) {
|
||||
if(i < palette.colors.size()) {
|
||||
auto newC = std::make_shared<Vector3f>(palette.colors[i].x(), palette.colors[i].y(), palette.colors[i].z());
|
||||
color_button(gui, "c", newC.get(), {
|
||||
.isSelected = newC->x() == color->x() && newC->y() == color->y() && newC->z() == color->z(),
|
||||
|
|
@ -264,7 +270,124 @@ void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) {
|
|||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
svg_icon_button(gui, "extra color settings", "data/icons/RemixIcon/more-fill.svg", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = colorPickerPopupData.extraSettingsOpen,
|
||||
.onClick = [&] {
|
||||
colorPickerPopupData.extraSettingsOpen = !colorPickerPopupData.extraSettingsOpen;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
auto paletteColorPickerExtras = [&] {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(200), .height = CLAY_SIZING_FIT(200)},
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
}
|
||||
}) {
|
||||
gui.element<ColorPicker<Vector4f>>("color picker element", color, true);
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
}
|
||||
}) {
|
||||
std::vector<std::string> paletteNames;
|
||||
for(auto& p : main.conf.palettes)
|
||||
paletteNames.emplace_back(p.name);
|
||||
gui.element<DropDown<size_t>>("paletteselector", &colorPickerPopupData.selectedPalette, paletteNames);
|
||||
svg_icon_button(gui, "paletteadd", "data/icons/plus.svg", {
|
||||
.onClick = [&] {
|
||||
colorPickerPopupData.addingPalette = !colorPickerPopupData.addingPalette;
|
||||
}
|
||||
});
|
||||
svg_icon_button(gui, "paletteremove", "data/icons/close.svg", {
|
||||
.onClick = [&] {
|
||||
main.conf.palettes.erase(main.conf.palettes.begin() + colorPickerPopupData.selectedPalette);
|
||||
colorPickerPopupData.selectedPalette = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
if(colorPickerPopupData.addingPalette) {
|
||||
input_text_field(gui, "paletteinputname", "Name", &colorPickerPopupData.newPaletteStr);
|
||||
text_button(gui, "addpalettebutton", "Create", {
|
||||
.wide = true,
|
||||
.onClick = [&] {
|
||||
if(!colorPickerPopupData.newPaletteStr.empty()) {
|
||||
main.conf.palettes.emplace_back();
|
||||
main.conf.palettes.back().name = colorPickerPopupData.newPaletteStr;
|
||||
colorPickerPopupData.selectedPalette = main.conf.palettes.size() - 1;
|
||||
colorPickerPopupData.addingPalette = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if(colorPickerPopupData.selectedPalette != 0) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
}
|
||||
}) {
|
||||
svg_icon_button(gui, "addcolor", "data/icons/plus.svg", {
|
||||
.onClick = [&, color] {
|
||||
std::erase(palette.colors, Vector3f{color->x(), color->y(), color->z()});
|
||||
palette.colors.emplace_back(color->x(), color->y(), color->z());
|
||||
}
|
||||
});
|
||||
svg_icon_button(gui, "deletecolor", "data/icons/close.svg", {
|
||||
.onClick = [&, color] {
|
||||
std::erase(palette.colors, Vector3f{color->x(), color->y(), color->z()});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gui.element<LayoutElement>("color settings popup", [&] (LayoutElement* l, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(gui.io.theme->windowCorners1)
|
||||
}) {
|
||||
if(colorPickerPopupData.extraSettingsOpen) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
}) {
|
||||
paletteColorPickerGrid();
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
}) {
|
||||
paletteColorPickerExtras();
|
||||
}
|
||||
}
|
||||
else
|
||||
paletteColorPickerGrid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,11 @@ class PhoneDrawingProgramScreen : public DrawingProgramScreen {
|
|||
FG_COLOR,
|
||||
BG_COLOR
|
||||
} settingsMenuPopup = SettingsMenuPopup::NONE;
|
||||
struct PaletteData {
|
||||
struct ColorPickerPopupData {
|
||||
bool extraSettingsOpen = false;
|
||||
size_t selectedPalette = 0;
|
||||
bool addingPalette = false;
|
||||
std::string newPaletteStr;
|
||||
} paletteData;
|
||||
} colorPickerPopupData;
|
||||
void reset_color_picker_popup_data();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue