Browse Source

Made a picture component for linked and embedded images in the GUI.

David Piuva 4 years ago
parent
commit
714254df95

+ 2 - 0
Source/DFPSR/gui/DsrWindow.cpp

@@ -28,6 +28,7 @@
 #include "components/Button.h"
 #include "components/Button.h"
 #include "components/ListBox.h"
 #include "components/ListBox.h"
 #include "components/Label.h"
 #include "components/Label.h"
+#include "components/Picture.h"
 // <<<< Include new components here
 // <<<< Include new components here
 
 
 #include "../math/scalar.h"
 #include "../math/scalar.h"
@@ -45,6 +46,7 @@ void dsr::gui_initialize() {
 		REGISTER_PERSISTENT_CLASS(Button)
 		REGISTER_PERSISTENT_CLASS(Button)
 		REGISTER_PERSISTENT_CLASS(ListBox)
 		REGISTER_PERSISTENT_CLASS(ListBox)
 		REGISTER_PERSISTENT_CLASS(Label)
 		REGISTER_PERSISTENT_CLASS(Label)
+		REGISTER_PERSISTENT_CLASS(Picture)
 		// <<<< Register new components here
 		// <<<< Register new components here
 
 
 		initialized = true;
 		initialized = true;

+ 85 - 0
Source/DFPSR/gui/components/Picture.cpp

@@ -0,0 +1,85 @@
+// zlib open source license
+//
+// Copyright (c) 2021 David Forsgren Piuva
+// 
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// 
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 
+//    1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 
+//    2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 
+//    3. This notice may not be removed or altered from any source
+//    distribution.
+
+#include "Picture.h"
+#include "../../api/filterAPI.h"
+
+using namespace dsr;
+
+PERSISTENT_DEFINITION(Picture)
+
+void Picture::declareAttributes(StructureDefinition &target) const {
+	VisualComponent::declareAttributes(target);
+	target.declareAttribute(U"Image");
+	target.declareAttribute(U"Interpolation");
+}
+
+Persistent* Picture::findAttribute(const ReadableString &name) {
+	if (string_caseInsensitiveMatch(name, U"Image")) {
+		return &(this->image);
+	} else if (string_caseInsensitiveMatch(name, U"Interpolation")) {
+		return &(this->interpolation);
+	} else {
+		return VisualComponent::findAttribute(name);
+	}
+}
+
+Picture::Picture() {}
+
+bool Picture::isContainer() const {
+	return false;
+}
+
+void Picture::drawSelf(ImageRgbaU8& targetImage, const IRect &relativeLocation) {
+	if (image_exists(this->image.value)) {
+		this->generateGraphics();
+		draw_alphaFilter(targetImage, this->finalImage, relativeLocation.left(), relativeLocation.top());
+	}
+}
+
+bool Picture::pointIsInside(const IVector2D& pixelPosition) {
+	return false;
+}
+
+void Picture::generateGraphics() {
+	int width = this->location.width();
+	int height = this->location.height();
+	if (width < 1) { width = 1; }
+	if (height < 1) { height = 1; }
+	if (!this->hasImages) {
+		this->finalImage = filter_resize(this->image.value, this->interpolation.value ? Sampler::Linear : Sampler::Nearest, width, height);
+		this->hasImages = true;
+	}
+}
+
+void Picture::changedLocation(const IRect &oldLocation, const IRect &newLocation) {
+	// If the component has changed dimensions then redraw the image
+	if (oldLocation.size() != newLocation.size()) {
+		this->hasImages = false;
+	}
+}
+
+void Picture::changedAttribute(const ReadableString &name) {
+	// If an attribute has changed then force the image to be redrawn
+	this->hasImages = false;
+}

+ 56 - 0
Source/DFPSR/gui/components/Picture.h

@@ -0,0 +1,56 @@
+// zlib open source license
+//
+// Copyright (c) 2021 David Forsgren Piuva
+// 
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// 
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 
+//    1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 
+//    2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 
+//    3. This notice may not be removed or altered from any source
+//    distribution.
+
+#ifndef DFPSR_GUI_COMPONENT_PICTURE
+#define DFPSR_GUI_COMPONENT_PICTURE
+
+#include "../VisualComponent.h"
+
+namespace dsr {
+
+class Picture : public VisualComponent {
+PERSISTENT_DECLARATION(Picture)
+public:
+	// Attributes
+	PersistentImage image;
+	PersistentBoolean interpolation; // False (0) for nearest neighbor, True (1) for bi-linear
+	// Generated
+	bool hasImages = false;
+	OrderedImageRgbaU8 finalImage;
+	void generateGraphics();
+	// Attribute access
+	void declareAttributes(StructureDefinition &target) const override;
+	Persistent* findAttribute(const ReadableString &name) override;
+public:
+	Picture();
+public:
+	bool isContainer() const override;
+	void drawSelf(ImageRgbaU8& targetImage, const IRect &relativeLocation) override;
+	bool pointIsInside(const IVector2D& pixelPosition) override;
+	void changedLocation(const IRect &oldLocation, const IRect &newLocation) override;
+	void changedAttribute(const ReadableString &name) override;
+};
+
+}
+
+#endif

+ 117 - 0
Source/DFPSR/persistent/atomic/PersistentImage.cpp

@@ -0,0 +1,117 @@
+// zlib open source license
+//
+// Copyright (c) 2021 David Forsgren Piuva
+// 
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// 
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 
+//    1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 
+//    2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 
+//    3. This notice may not be removed or altered from any source
+//    distribution.
+
+#include "PersistentImage.h"
+
+using namespace dsr;
+
+PERSISTENT_DEFINITION(PersistentImage)
+
+static uint8_t readHexaDecimal(const ReadableString &text, int &readFrom) {
+	uint8_t result = 0u;
+	for (int i = 0; i < 2; i++) {
+		result = result << 4;
+		DsrChar c = text[readFrom];
+		if (U'0' <= c && c <= U'9') {
+			result = result | (c - U'0');
+		} else if (U'a' <= c && c <= U'f') {
+			result = result | (c - U'a' + 10);
+		} else if (U'A' <= c && c <= U'F') {
+			result = result | (c - U'A' + 10);
+		}
+		readFrom++;
+	}
+	return result;
+}
+bool PersistentImage::assignValue(const ReadableString &text) {
+	if (string_caseInsensitiveMatch(text, U"NONE")) {
+		// Set the handle to null
+		this->value = OrderedImageRgbaU8();
+	} else {
+		// Create an image from the text
+		int colonIndex = string_findFirst(text, U':');
+		if (colonIndex == -1) {
+			printText("Missing colon when creating PersistentImage from text!\n");
+			return false;
+		}
+		ReadableString leftSide = string_before(text, colonIndex);
+		if (string_caseInsensitiveMatch(leftSide, U"FILE")) {
+			// Read image from the file path
+			this->value = image_load_RgbaU8(string_after(text, colonIndex));
+		} else {
+			// Read dimensions and a sequence of pixels as hexadecimals
+			int xIndex = string_findFirst(text, U'x');
+			if (xIndex == -1 || xIndex > colonIndex) {
+				printText("Missing x when parsing embedded PersistentImage from text!\n");
+				return false;
+			}
+			int width = string_toInteger(string_before(leftSide, xIndex));
+			int height = string_toInteger(string_after(leftSide, xIndex));
+			if (width <= 0 || height <= 0) {
+				// No pixels found
+				this->value = OrderedImageRgbaU8();
+			} else {
+				this->value = image_create_RgbaU8(width, height);
+				int readIndex = colonIndex + 1;
+				for (int y = 0; y < height; y++) {
+					for (int x = 0; x < width; x++) {
+						int red = readHexaDecimal(text, readIndex);
+						int green = readHexaDecimal(text, readIndex);
+						int blue = readHexaDecimal(text, readIndex);
+						int alpha = readHexaDecimal(text, readIndex);
+						image_writePixel(this->value, x, y, ColorRgbaI32(red, green, blue, alpha));
+					}
+				}
+			}
+		}
+	}
+	return true;
+}
+
+static const String hexadecimals = U"0123456789ABCDEF";
+static void writeHexaDecimal(String &out, uint8_t value) {
+	string_appendChar(out, hexadecimals[(value & 0b11110000) >> 4]);
+	string_appendChar(out, hexadecimals[value & 0b00001111]);
+}
+String& PersistentImage::toStreamIndented(String &out, const ReadableString &indentation) const {
+	string_append(out, indentation);
+	if (string_length(this->path)) {
+		string_append(out, "File:", this->path);
+	} else if (image_exists(this->value)) {
+		int width = image_getWidth(this->value);
+		int height = image_getHeight(this->value);
+		string_append(out, width, U"x", height, U":");
+		for (int y = 0; y < height; y++) {
+			for (int x = 0; x < width; x++) {
+				ColorRgbaI32 color = image_readPixel_clamp(this->value, x, y);
+				writeHexaDecimal(out, color.red);
+				writeHexaDecimal(out, color.green);
+				writeHexaDecimal(out, color.blue);
+				writeHexaDecimal(out, color.alpha);
+			}
+		}
+	} else {
+		string_append(out, U"None");
+	}
+	return out;
+}

+ 47 - 0
Source/DFPSR/persistent/atomic/PersistentImage.h

@@ -0,0 +1,47 @@
+// zlib open source license
+//
+// Copyright (c) 2021 David Forsgren Piuva
+// 
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// 
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 
+//    1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 
+//    2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 
+//    3. This notice may not be removed or altered from any source
+//    distribution.
+
+#ifndef DFPSR_GUI_PERSISTENTIMAGE
+#define DFPSR_GUI_PERSISTENTIMAGE
+
+#include "../ClassFactory.h"
+#include "../../api/imageAPI.h"
+
+namespace dsr {
+
+// A container for images that can either embed the image as hexadecimals or save a reference a the file's path, depending on if the path is set.
+class PersistentImage : public Persistent {
+public:
+	PERSISTENT_DECLARATION(PersistentImage)
+	OrderedImageRgbaU8 value; // Persistent images may not have native pack order, because it would cause incompatibility.
+	String path; // If the path has any characters, serialization will save the image's file path instead of the pixel content to save space.
+public:
+	PersistentImage() {}
+public:
+	virtual bool assignValue(const ReadableString &text) override;
+	virtual String& toStreamIndented(String& out, const ReadableString& indentation) const override;
+};
+
+}
+
+#endif

+ 1 - 1
Source/DFPSR/persistent/includePersistent.h

@@ -7,4 +7,4 @@
 #include "atomic/PersistentString.h"
 #include "atomic/PersistentString.h"
 #include "atomic/PersistentStringList.h"
 #include "atomic/PersistentStringList.h"
 #include "atomic/PersistentColor.h"
 #include "atomic/PersistentColor.h"
-
+#include "atomic/PersistentImage.h"

BIN
Source/SDK/guiExample/media/Alien.png


File diff suppressed because it is too large
+ 11 - 0
Source/SDK/guiExample/media/interface.lof


Some files were not shown because too many files changed in this diff