Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/windowing/StarSliderBar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/windowing/StarSliderBar.cpp')
-rw-r--r--source/windowing/StarSliderBar.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/source/windowing/StarSliderBar.cpp b/source/windowing/StarSliderBar.cpp
new file mode 100644
index 0000000..12fb749
--- /dev/null
+++ b/source/windowing/StarSliderBar.cpp
@@ -0,0 +1,183 @@
+#include "StarSliderBar.hpp"
+#include "StarRoot.hpp"
+#include "StarAssets.hpp"
+#include "StarGuiReader.hpp"
+#include "StarImageMetadataDatabase.hpp"
+
+namespace Star {
+
+SliderBarWidget::SliderBarWidget(String const& grid, bool showSpinner)
+ : m_grid(make_shared<ImageWidget>(grid)),
+ m_low(0),
+ m_high(1),
+ m_delta(1),
+ m_val(0),
+ m_updateJog(true),
+ m_jogDragActive(false),
+ m_enabled(true) {
+
+ auto assets = Root::singleton().assets();
+ auto imgMetadata = Root::singleton().imageMetadataDatabase();
+
+ m_jog = make_shared<ButtonWidget>();
+ m_jog->setImages(assets->json("/interface.config:slider.jog").toString());
+ m_jog->setPressedOffset({0, 0});
+
+ if (showSpinner) {
+ GuiReader guiReader;
+ guiReader.registerCallback("spinner.down", bind(&SliderBarWidget::leftCallback, this));
+ guiReader.registerCallback("spinner.up", bind(&SliderBarWidget::rightCallback, this));
+
+ float rightButtonOffset = imgMetadata->imageSize(assets->json("/interface.config:slider.leftBase").toString())[0];
+ rightButtonOffset += assets->json("/interface.config:slider.defaultPadding").toInt();
+
+ float gridOffset = rightButtonOffset;
+
+ rightButtonOffset += imgMetadata->imageSize(grid)[0];
+ rightButtonOffset += assets->json("/interface.config:slider.defaultPadding").toInt();
+
+ // TODO: Make spinners a thing already
+ Json config = Json::parse(strf(
+ R"SPINNER(
+ {
+ "spinner" : {
+ "type" : "spinner",
+ "leftBase" : "%s",
+ "leftHover" : "%s",
+ "rightBase" : "%s",
+ "rightHover" : "%s",
+ "position" : [0, 0],
+ "upOffset" : %s
+ }
+ }
+ )SPINNER",
+ assets->json("/interface.config:slider.leftBase").toString(),
+ assets->json("/interface.config:slider.leftHover").toString(),
+ assets->json("/interface.config:slider.rightBase").toString(),
+ assets->json("/interface.config:slider.rightHover").toString(),
+ rightButtonOffset));
+
+ guiReader.construct(config, this);
+
+ m_grid->setPosition(Vec2I(gridOffset, 0));
+
+ m_leftButton = fetchChild<ButtonWidget>("spinner.down");
+ m_rightButton = fetchChild<ButtonWidget>("spinner.up");
+ }
+
+ addChild("grid", m_grid);
+ addChild("jog", m_jog);
+
+ markAsContainer();
+ disableScissoring();
+}
+
+void SliderBarWidget::setJogImages(String const& baseImage, String const& hoverImage, String const& pressedImage, String const& disabledImage) {
+ m_jog->setImages(baseImage, hoverImage, pressedImage, disabledImage);
+}
+
+void SliderBarWidget::setRange(int low, int high, int delta) {
+ m_low = low;
+ m_high = high;
+ m_high = std::max(m_low + 1, m_high);
+ if (delta <= 0)
+ m_delta = 1;
+ else
+ m_delta = delta;
+ setVal(m_val);
+}
+
+void SliderBarWidget::setRange(Vec2I const& range, int delta) {
+ setRange(range[0], range[1], delta);
+}
+
+void SliderBarWidget::setVal(int val, bool callbackIfChanged) {
+ bool doCallback = false;
+ if (m_callback && callbackIfChanged && m_val != val)
+ doCallback = true;
+
+ if (m_val != val)
+ m_updateJog = true;
+
+ m_val = val;
+ m_val = clamp(m_val, m_low, m_high);
+
+ if (doCallback)
+ m_callback(this);
+}
+
+int SliderBarWidget::val() const {
+ return m_val;
+}
+
+void SliderBarWidget::setEnabled(bool enabled) {
+ if (m_enabled != enabled) {
+ m_enabled = enabled;
+ m_jogDragActive = false;
+ m_jog->setEnabled(enabled);
+ if (m_rightButton)
+ m_rightButton->setEnabled(enabled);
+ if (m_leftButton)
+ m_leftButton->setEnabled(enabled);
+ }
+}
+
+void SliderBarWidget::setCallback(WidgetCallbackFunc callback) {
+ m_callback = callback;
+}
+
+void SliderBarWidget::update() {
+ float gridLow = m_grid->position()[0];
+ float gridHigh = gridLow + m_grid->size()[0];
+
+ if (m_jogDragActive) {
+ auto clampedPos = clamp<float>(m_jogDragPos[0], gridLow, gridHigh);
+ float clampedPercent = (clampedPos - gridLow) / (gridHigh - gridLow);
+ setVal(clampedPercent * (m_high - m_low));
+ }
+
+ if (m_updateJog) {
+ float percent = (float)m_val / (m_high - m_low);
+
+ float jogPos = (gridHigh - gridLow) * percent + gridLow - m_jog->size()[0] * 0.5;
+
+ m_jog->setPosition(Vec2I(jogPos, 0));
+ m_updateJog = false;
+ }
+
+ Widget::update();
+}
+
+bool SliderBarWidget::sendEvent(InputEvent const& event) {
+ if (event.is<MouseButtonUpEvent>()) {
+ blur();
+ m_jogDragActive = false;
+ }
+
+ if (m_enabled) {
+ if (event.is<MouseButtonDownEvent>()) {
+ if (m_jog->inMember(*context()->mousePosition(event))) {
+ focus();
+ m_jogDragPos = *context()->mousePosition(event) - screenPosition();
+ m_jogDragActive = true;
+ }
+ }
+
+ if (event.is<MouseMoveEvent>()) {
+ if (m_jogDragActive)
+ m_jogDragPos = *context()->mousePosition(event) - screenPosition();
+ }
+ }
+
+ return Widget::sendEvent(event);
+}
+
+void SliderBarWidget::leftCallback() {
+ setVal(std::max(m_low, m_val - m_delta));
+}
+
+void SliderBarWidget::rightCallback() {
+ setVal(std::min(m_high, m_val + m_delta));
+}
+
+}