Something went wrong. Try again.
art software for the rest of us
drawing paint image sdl art
Something went wrong. Try again.
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137#include "ArtworkCard.h"#include <algorithm>#include "AppLayers/ScreenLayer.h"#include "Label.h"#include "Screens/ProjectsScreen.h"#include "UserInterface/Engine/Geometry.h"
namespace UI {namespace {constexpr float ThumbnailHeight = 160.0f;constexpr float ThumbnailWidth = 220.0f;constexpr float NameHeight = 32.0f;constexpr float NameGap = 8.0f;}
Size ArtworkCard::GetThumbnailSize(const Artwork* artwork) { if (!artwork || artwork->GetWidth() <= 0 || artwork->GetHeight() <= 0) { return {ThumbnailWidth, ThumbnailHeight}; }
const float aspect = static_cast<float>(artwork->GetWidth()) / static_cast<float>(artwork->GetHeight()); float width = ThumbnailWidth; float height = width / aspect; if (height > ThumbnailHeight) { height = ThumbnailHeight; width = height * aspect; } return {std::max(1.0f, width), std::max(1.0f, height)};}
Size ArtworkCard::GetSizeForArtwork(const Artwork* artwork, bool showName, ArtworkCardSizeMode sizeMode) { if (sizeMode >= ArtworkCardSizeMode::Fill) { return { ThumbnailWidth, ThumbnailHeight + (showName ? NameGap + NameHeight : 0.0f) }; }
Size thumbnailSize = GetThumbnailSize(artwork); return { showName ? ThumbnailWidth : thumbnailSize.width, thumbnailSize.height + (showName ? NameGap + NameHeight : 0.0f) };}
// TODO: get rid of showName, generally sizemode fill implies showName falseArtworkCard::ArtworkCard(Artwork* artwork, bool showName, ArtworkCardSizeMode sizeMode) : artwork(artwork), showName(showName), sizeMode(sizeMode), thumbnail(std::make_unique<Panel>(GetThumbnailSize(artwork))) { focusable = false; thumbnail->SetBgColor(Color(1.0f, 1.0f, 1.0f, 1.0f)); thumbnail->SetBorder(Color(0.0f, 0.0f, 0.0f, 0.54772256f), 2.0f, 0.0f); AddChild(std::move(thumbnail)); if (showName) { auto nameLabel = std::make_unique<Label>(artwork ? artwork->GetName() : "untitled"); nameLabel->SetTextColor(Color(0.0f, 0.0f, 0.0f, 1.0f)); nameLabel->SetHorizontalAlignment(HorizontalAlignment::Center); // TODO: make this work if (sizeMode == ArtworkCardSizeMode::FillExtra) { nameLabel->SetPadding(Thickness(32, 0)); } AddChild(std::move(nameLabel)); }}
void ArtworkCard::Measure(Size availableSpace) { if (sizeMode >= ArtworkCardSizeMode::Fill) { desiredSize.width = std::clamp( std::max(0.0f, availableSpace.width - margin.HorizontalTotal()), minSize.width, maxSize.width); desiredSize.height = std::clamp( std::max(0.0f, availableSpace.height - margin.VerticalTotal()), minSize.height, maxSize.height); return; }
Size size = GetSizeForArtwork(artwork, showName, sizeMode); // sizeMode always not applicable here.. desiredSize.width = std::clamp(size.width + margin.HorizontalTotal(), minSize.width, maxSize.width); desiredSize.height = std::clamp(size.height + margin.VerticalTotal(), minSize.height, maxSize.height);}
void ArtworkCard::Arrange(Rect finalBounds) { ArrangeCore(finalBounds);
const Size naturalThumbnailSize = GetThumbnailSize(artwork); Size thumbnailSize = naturalThumbnailSize;
float offsetX = (localBounds.Width - thumbnailSize.width) * 0.5f; float offsetY = 0.0f;
if (sizeMode >= ArtworkCardSizeMode::Fill) { // scale to fit const float availableHeight = std::max(0.0f, localBounds.Height - (showName ? NameGap + NameHeight : 0.0f)); float scale = 0.0f; if (naturalThumbnailSize.width > 0.0f && naturalThumbnailSize.height > 0.0f) { scale = std::max(0.0f, std::min(localBounds.Width / naturalThumbnailSize.width, availableHeight / naturalThumbnailSize.height)); } thumbnailSize = { naturalThumbnailSize.width * scale, naturalThumbnailSize.height * scale };
// center const float totalContentHeight = thumbnailSize.height + (showName ? NameGap + NameHeight : 0.0f); offsetX = (localBounds.Width - thumbnailSize.width) * 0.5f; offsetY = (localBounds.Height - totalContentHeight) * 0.5f; }
Widget* thumbnailWidget = children.front().get(); thumbnailWidget->Arrange(Rect(offsetX, offsetY, thumbnailSize.width, thumbnailSize.height)); if (showName) { Widget* labelWidget = children[1].get(); labelWidget->Measure(Size(localBounds.Width, NameHeight)); labelWidget->Arrange(Rect(0.0f, offsetY + thumbnailSize.height + NameGap, localBounds.Width, NameHeight)); } ClearDirty(DirtyFlags::Layout | DirtyFlags::Hierarchy);}
bool ArtworkCard::OnPointerStream(const std::shared_ptr<PointerStream>& stream) { // deriuve from button if (!enabled || !visible || sizeMode == ArtworkCardSizeMode::FillExtra) return false; // ok maybe dblclick to enter edit, altho ibispaint only introduced this in ver.14
const auto event = stream->PeekLatestInput();
if (event.actDirection == PointerDirection::Down) { SetPressed(true); return true; } else if (event.actDirection == PointerDirection::Up) { if (pressed) { SetPressed(false); if (globalBounds.Contains(event.scaledX, event.scaledY)) { ScreenLayer::OpenScreen(std::make_unique<ProjectsScreen>(artwork)); } return true; } } return false;}
}