Browse Source

Left aligned menu text and made an arrow for expanding sub-menus.

David Piuva 2 years ago
parent
commit
26cae16253
2 changed files with 38 additions and 6 deletions
  1. 36 6
      Source/DFPSR/gui/components/Menu.cpp
  2. 2 0
      Source/DFPSR/gui/components/Menu.h

+ 36 - 6
Source/DFPSR/gui/components/Menu.cpp

@@ -27,6 +27,15 @@ using namespace dsr;
 
 
 PERSISTENT_DEFINITION(Menu)
 PERSISTENT_DEFINITION(Menu)
 
 
+static AlignedImageU8 arrowImage = image_fromAscii(
+	"< .xX>"
+	"<.x.  >"
+	"< XX. >"
+	"< xXX.>"
+	"< XX. >"
+	"<.x.  >"
+);
+
 void Menu::declareAttributes(StructureDefinition &target) const {
 void Menu::declareAttributes(StructureDefinition &target) const {
 	VisualComponent::declareAttributes(target);
 	VisualComponent::declareAttributes(target);
 	target.declareAttribute(U"BackColor");
 	target.declareAttribute(U"BackColor");
@@ -59,18 +68,32 @@ bool Menu::isContainer() const {
 	return true;
 	return true;
 }
 }
 
 
+bool Menu::hasArrow() {
+	return this->subMenu && this->getChildCount() > 0;
+}
+
 static OrderedImageRgbaU8 generateHeadImage(Menu &menu, MediaMethod imageGenerator, int pressed, int width, int height, ColorRgbI32 backColor, ColorRgbI32 foreColor, const ReadableString &text, RasterFont font) {
 static OrderedImageRgbaU8 generateHeadImage(Menu &menu, MediaMethod imageGenerator, int pressed, int width, int height, ColorRgbI32 backColor, ColorRgbI32 foreColor, const ReadableString &text, RasterFont font) {
 	// Create a scaled image
 	// Create a scaled image
 	OrderedImageRgbaU8 result;
 	OrderedImageRgbaU8 result;
  	component_generateImage(menu.getTheme(), imageGenerator, width, height, backColor.red, backColor.green, backColor.blue, pressed)(result);
  	component_generateImage(menu.getTheme(), imageGenerator, width, height, backColor.red, backColor.green, backColor.blue, pressed)(result);
 	if (string_length(text) > 0) {
 	if (string_length(text) > 0) {
-		int left = (image_getWidth(result) - font_getLineWidth(font, text)) / 2;
-		int top = (image_getHeight(result) - font_getSize(font)) / 2;
+		int backWidth = image_getWidth(result);
+		int backHeight = image_getHeight(result);
+		int left = menu.padding.value;
+		int top = (backHeight - font_getSize(font)) / 2;
 		if (pressed) {
 		if (pressed) {
 			top += 1;
 			top += 1;
 		}
 		}
-		// TODO: Mark sub-menus as expandable using a right facing triangle.
+		// Print the text
 		font_printLine(result, font, text, IVector2D(left, top), ColorRgbaI32(foreColor, 255));
 		font_printLine(result, font, text, IVector2D(left, top), ColorRgbaI32(foreColor, 255));
+		// Draw the arrow
+		if (menu.hasArrow()) {
+			int arrowWidth = image_getWidth(arrowImage);
+			int arrowHeight = image_getHeight(arrowImage);
+			int arrowLeft = backWidth - arrowWidth - 4;
+			int arrowTop = (backHeight - arrowHeight) / 2;
+			draw_silhouette(result, arrowImage, ColorRgbaI32(foreColor, 255), arrowLeft, arrowTop);
+		}
 	}
 	}
 	return result;
 	return result;
 }
 }
@@ -183,11 +206,13 @@ void Menu::updateLocationEvent(const IRect& oldLocation, const IRect& newLocatio
 	} else {
 	} else {
 		top += newLocation.height() - overlap;
 		top += newLocation.height() - overlap;
 	}
 	}
-	int maxWidth = newLocation.width() - (this->padding.value * 2);
+	int maxWidth = 80; // Minimum usable with.
+	// Expand list with to fit child components.
 	for (int i = 0; i < this->getChildCount(); i++) {
 	for (int i = 0; i < this->getChildCount(); i++) {
 		int width = this->children[i]->getDesiredDimensions().x;
 		int width = this->children[i]->getDesiredDimensions().x;
 		if (maxWidth < width) maxWidth = width;
 		if (maxWidth < width) maxWidth = width;
 	}
 	}
+	// Stretch out the child components to use the whole width.
 	for (int i = 0; i < this->getChildCount(); i++) {
 	for (int i = 0; i < this->getChildCount(); i++) {
 		int height = this->children[i]->getDesiredDimensions().y;
 		int height = this->children[i]->getDesiredDimensions().y;
 		this->children[i]->applyLayout(IRect(left, top, maxWidth, height));
 		this->children[i]->applyLayout(IRect(left, top, maxWidth, height));
@@ -262,6 +287,11 @@ void Menu::receiveMouseEvent(const MouseEvent& event) {
 
 
 IVector2D Menu::getDesiredDimensions() {
 IVector2D Menu::getDesiredDimensions() {
 	this->completeAssets();
 	this->completeAssets();
-	int sizeAdder = this->padding.value * 2;
-	return IVector2D(font_getLineWidth(this->font, this->text.value) + sizeAdder, font_getSize(this->font) + sizeAdder);
+	int widthAdder = this->padding.value * 2;
+	int heightAdder = widthAdder;
+	if (this->hasArrow()) {
+		// Make extra space for the expansion arrowhead when containing a list of members.
+		widthAdder += 24;
+	}
+	return IVector2D(font_getLineWidth(this->font, this->text.value) + widthAdder, font_getSize(this->font) + heightAdder);
 }
 }

+ 2 - 0
Source/DFPSR/gui/components/Menu.h

@@ -67,6 +67,8 @@ public:
 	IVector2D getDesiredDimensions() override;
 	IVector2D getDesiredDimensions() override;
 	bool managesChildren() override;
 	bool managesChildren() override;
 public:
 public:
+	// Helper functions for decorations.
+	bool hasArrow();
 	// Helper functions for overlay projecting components.
 	// Helper functions for overlay projecting components.
 	void showOverlay();
 	void showOverlay();
 	void lostFocus() override;
 	void lostFocus() override;