From 6e0d5940561156c8a2b96ae5b293511a111d3170 Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Thu, 2 Sep 2021 10:30:25 -0700
Subject: [PATCH] Added selection rectangle.

---
 include/dawn/dawn.h         |  1 +
 include/dawn/ui/menulist.h  |  5 +++++
 include/dawn/ui/rectangle.h | 17 +++++++++++++++++
 src/ui/menulist.c           | 22 ++++++++++++++++-----
 src/ui/menulist.h           |  1 +
 src/ui/rectangle.c          | 38 +++++++++++++++++++++++++++++++++++++
 src/ui/rectangle.h          | 21 ++++++++++++++++++++
 7 files changed, 100 insertions(+), 5 deletions(-)
 create mode 100644 include/dawn/ui/rectangle.h
 create mode 100644 src/ui/rectangle.c
 create mode 100644 src/ui/rectangle.h

diff --git a/include/dawn/dawn.h b/include/dawn/dawn.h
index 8fb109bf..e1007896 100644
--- a/include/dawn/dawn.h
+++ b/include/dawn/dawn.h
@@ -70,6 +70,7 @@
 #include "ui/label.h"
 #include "ui/menu.h"
 #include "ui/menulist.h"
+#include "ui/rectangle.h"
 
 // Utility Objects
 #include "util/array.h"
diff --git a/include/dawn/ui/menulist.h b/include/dawn/ui/menulist.h
index c116d873..e9cfe2d2 100644
--- a/include/dawn/ui/menulist.h
+++ b/include/dawn/ui/menulist.h
@@ -10,6 +10,10 @@
 #include "frame.h"
 #include "label.h"
 #include "menu.h"
+#include "rectangle.h"
+
+/** Color of the menulist selection rectangle */
+#define MENULIST_SELECTION_COLOR ((pixel_t){ .r=255, .g=255, .b=255, .a=150 })
 
 /** Maximum number of items that the list supports */
 #define MENULIST_ITEMS_MAX 32
@@ -21,5 +25,6 @@ typedef struct {
   label_t labels[MENULIST_ITEMS_MAX];
   frame_t frame;
   menu_t menu;
+  rectangle_t selection;
   uint8_t count;
 } menulist_t;
\ No newline at end of file
diff --git a/include/dawn/ui/rectangle.h b/include/dawn/ui/rectangle.h
new file mode 100644
index 00000000..d30ad61e
--- /dev/null
+++ b/include/dawn/ui/rectangle.h
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#pragma once
+#include "../libs.h"
+#include "../display/primitive.h"
+
+typedef struct {
+  float x, y;
+  float width, height;
+  texture_t texture;
+  primitive_t quad;
+} rectangle_t;
\ No newline at end of file
diff --git a/src/ui/menulist.c b/src/ui/menulist.c
index bd8ce410..dbb72616 100644
--- a/src/ui/menulist.c
+++ b/src/ui/menulist.c
@@ -14,6 +14,11 @@ void menuListInit(menulist_t *ml, texture_t *texture) {
   ml->y = 0;
   ml->count = 0;
 
+  menuInit(&ml->menu);
+  
+  rectangleInit(&ml->selection);
+  rectangleSetColor(&ml->selection, MENULIST_SELECTION_COLOR);
+
   frameInit(&ml->frame);
   ml->frame.texture = texture;
 }
@@ -57,6 +62,9 @@ void menuListUpdate(menulist_t *ml, engine_t *engine) {
 void menuListRender(menulist_t *ml, shader_t *shader) {
   uint8_t i;
   label_t *label;
+  float fontScale;
+
+  fontScale = fontGetScale(ml->labels->fontSize);
 
   // Render the frame
   ml->frame.x = ml->x;
@@ -64,15 +72,19 @@ void menuListRender(menulist_t *ml, shader_t *shader) {
   frameRender(&ml->frame, shader);
 
   // Render selection box.
+  ml->selection.x = ml->x + FRAME_BORDER_SIZE;
+  ml->selection.y = ml->y + FRAME_BORDER_SIZE +(
+    ml->menu.selected * FONT_LINE_HEIGHT * fontScale
+  );
+  ml->selection.width = 100;
+  ml->selection.height = FONT_LINE_HEIGHT * fontScale;
+  rectangleRender(&ml->selection, shader);
 
-  // Render each labels
+  // Render each label.
   for(i = 0; i < ml->count; i++) {
     label = ml->labels + i;
     label->x = FRAME_BORDER_SIZE;
-    if(ml->menu.selected == i) label->x += 4;
-    label->y = FRAME_BORDER_SIZE + (
-      i * FONT_LINE_HEIGHT * fontGetScale(label->fontSize)
-    );
+    label->y = FRAME_BORDER_SIZE + i * FONT_LINE_HEIGHT * fontScale;
     labelRender(label, shader);
   }
 }
diff --git a/src/ui/menulist.h b/src/ui/menulist.h
index 78826d6d..09da7e2d 100644
--- a/src/ui/menulist.h
+++ b/src/ui/menulist.h
@@ -10,6 +10,7 @@
 #include "label.h"
 #include "menu.h"
 #include "frame.h"
+#include "rectangle.h"
 
 void menuListInit(menulist_t *ml, texture_t *texture);
 
diff --git a/src/ui/rectangle.c b/src/ui/rectangle.c
new file mode 100644
index 00000000..1ddedd4a
--- /dev/null
+++ b/src/ui/rectangle.c
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include "rectangle.h"
+
+void rectangleInit(rectangle_t *rectangle) {
+  rectangle->x = 0;
+  rectangle->y = 0;
+  rectangle->width = 32;
+  rectangle->height = 32;
+  textureInit(&rectangle->texture, 1, 1, NULL);
+  quadInit(&rectangle->quad, 0, 0,0,0,0, 1,1,1,1);
+}
+
+void rectangleSetColor(rectangle_t *rectangle, pixel_t color) {
+  textureBufferPixels(&rectangle->texture,
+    0, 0, 1, 1, &color
+  );
+}
+
+void rectangleRender(rectangle_t *rectangle, shader_t *shader) {
+  shaderUsePositionAndScale(shader,
+    rectangle->x, rectangle->y, 0,
+    0, 0, 0,
+    rectangle->width, rectangle->height, 1
+  );
+  shaderUseTexture(shader, &rectangle->texture);
+  primitiveDraw(&rectangle->quad, 0, -1);
+}
+
+void rectangleDispose(rectangle_t *rectangle) {
+  primitiveDispose(&rectangle->quad);
+  textureDispose(&rectangle->texture);
+}
\ No newline at end of file
diff --git a/src/ui/rectangle.h b/src/ui/rectangle.h
new file mode 100644
index 00000000..9a5c3213
--- /dev/null
+++ b/src/ui/rectangle.h
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#pragma once
+#include <dawn/dawn.h>
+#include "../display/texture.h"
+#include "../display/shader.h"
+#include "../display/primitive.h"
+#include "../display/primitives/quad.h"
+
+void rectangleInit(rectangle_t *rectangle);
+
+void rectangleSetColor(rectangle_t *rectangle, pixel_t color);
+
+void rectangleRender(rectangle_t *rectangle, shader_t *shader);
+
+void rectangleDispose(rectangle_t *rectangle);
\ No newline at end of file