diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/windowing/StarImageWidget.cpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/windowing/StarImageWidget.cpp')
-rw-r--r-- | source/windowing/StarImageWidget.cpp | 130 |
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())); +} + +} |