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

summaryrefslogtreecommitdiff
path: root/source/windowing/StarImageWidget.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/windowing/StarImageWidget.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/windowing/StarImageWidget.cpp')
-rw-r--r--source/windowing/StarImageWidget.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/source/windowing/StarImageWidget.cpp b/source/windowing/StarImageWidget.cpp
new file mode 100644
index 0000000..c189eac
--- /dev/null
+++ b/source/windowing/StarImageWidget.cpp
@@ -0,0 +1,130 @@
+#include "StarImageWidget.hpp"
+
+namespace Star {
+
+ImageWidget::ImageWidget(String const& image) {
+ m_centered = false;
+ m_trim = false;
+ m_scale = 1;
+ m_rotation = 0;
+ m_maxSize = Vec2I{4096, 4096};
+ m_minSize = Vec2I{0, 0};
+ m_offset = Vec2I{0, 0};
+ setImage(image);
+}
+
+void ImageWidget::renderImpl() {
+ auto screenPos = screenPosition();
+ for (auto const& drawable : m_drawables)
+ context()->drawDrawable(drawable, Vec2F(screenPos) * context()->interfaceScale() + Vec2F(m_offset), context()->interfaceScale(), Vec4B::filled(255));
+}
+
+bool ImageWidget::interactive() const {
+ return false;
+}
+
+void ImageWidget::setImage(String const& image) {
+ if (image.empty())
+ setDrawables({});
+ else
+ setDrawables({Drawable::makeImage(image, 1.0f, false, Vec2F())});
+}
+
+void ImageWidget::setScale(float scale) {
+ m_scale = scale;
+ transformDrawables();
+}
+
+void ImageWidget::setRotation(float rotation) {
+ m_rotation = rotation;
+ transformDrawables();
+}
+
+String ImageWidget::image() const {
+ if (!m_drawables.size())
+ return "";
+ return m_drawables[0].imagePart().image;
+}
+
+void ImageWidget::setDrawables(List<Drawable> drawables) {
+ m_baseDrawables = move(drawables);
+
+ transformDrawables();
+}
+
+Vec2I ImageWidget::offset() {
+ return m_offset;
+}
+
+void ImageWidget::setOffset(Vec2I const& offset) {
+ m_offset = offset;
+}
+
+bool ImageWidget::centered() {
+ return m_centered;
+}
+
+void ImageWidget::setCentered(bool centered) {
+ m_centered = centered;
+ transformDrawables();
+}
+
+bool ImageWidget::trim() {
+ return m_trim;
+}
+
+void ImageWidget::setTrim(bool trim) {
+ m_trim = trim;
+ transformDrawables();
+}
+
+void ImageWidget::setMaxSize(Vec2I const& size) {
+ m_maxSize = size;
+ transformDrawables();
+}
+
+void ImageWidget::setMinSize(Vec2I const& size) {
+ m_minSize = size;
+ transformDrawables();
+}
+
+RectI ImageWidget::screenBoundRect() const {
+ RectI base = RectI::withSize(screenPosition(), size());
+ if (m_centered) {
+ base.translate(-Vec2I::floor(size() / 2));
+ }
+
+ return base;
+}
+
+void ImageWidget::transformDrawables() {
+ m_drawables.clear();
+ for (auto drawable : m_baseDrawables)
+ m_drawables.append(Drawable(drawable));
+
+ if (m_rotation != 0)
+ Drawable::rotateAll(m_drawables, m_rotation);
+
+ // When 'centered' is true, the drawables provided are pre-centered
+ // around 0,0. Tooltips use this, as well as quest dialog portraits.
+ if (m_centered) {
+ auto boundBox = Drawable::boundBoxAll(m_drawables, m_trim);
+ Drawable::translateAll(m_drawables, -boundBox.center());
+ }
+
+ auto boundBox = Drawable::boundBoxAll(m_drawables, m_trim);
+ auto size = boundBox.size().piecewiseMax({0, 0});
+ if (size[0] && size[1]) {
+ if ((size[0] > m_maxSize[0]) || (size[1] > m_maxSize[1])) {
+ m_scale = std::min(m_maxSize[0] / size[0], m_maxSize[1] / size[1]);
+ } else if ((size[0] < m_minSize[0]) || (size[1] < m_minSize[1])) {
+ m_scale = std::min(m_minSize[0] / size[0], m_minSize[1] / size[1]);
+ }
+ }
+
+ Drawable::scaleAll(m_drawables, m_scale);
+
+ setSize(Vec2I((size * m_scale).ceil()));
+}
+
+}