changeset 105:f6b5e2fbbc81

inventory_dialog: add basic movements
author David Demelier <markand@malikania.fr>
date Tue, 31 Mar 2020 21:29:54 +0200
parents 7f254a797faf
children ed1a6bb02a78
files examples/example-inventory.c src/core/inventory_dialog.c src/core/inventory_dialog.h src/core/theme.c
diffstat 4 files changed, 143 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/examples/example-inventory.c	Tue Mar 31 21:05:00 2020 +0200
+++ b/examples/example-inventory.c	Tue Mar 31 21:29:54 2020 +0200
@@ -414,7 +414,9 @@
 {
 	struct inventory inv = { 0 };
 	struct inventory_dialog dlg = {
-		.inv = &inv
+		.inv = &inv,
+		.x = 60,
+		.y = 60
 	};
 
 	inventory_push(&inv, &items[0].item, 10);     /* Potion */
--- a/src/core/inventory_dialog.c	Tue Mar 31 21:05:00 2020 +0200
+++ b/src/core/inventory_dialog.c	Tue Mar 31 21:29:54 2020 +0200
@@ -20,11 +20,13 @@
 #include <stdio.h>
 
 #include "button.h"
+#include "event.h"
 #include "frame.h"
 #include "game.h"
 #include "inventory.h"
 #include "inventory_dialog.h"
 #include "item.h"
+#include "math.h"
 #include "painter.h"
 #include "texture.h"
 #include "window.h"
@@ -38,7 +40,7 @@
                         ((INVENTORY_ROWS_MAX + 1) * ITEM_PADDING))
 
 #define LABEL_WIDTH     (GRID_WIDTH)
-#define LABEL_HEIGHT    (32)
+#define LABEL_HEIGHT    (64)
 
 #define BUTTON_HEIGHT   (32)
 #define BUTTON_WIDTH    ((GRID_WIDTH) / 4)
@@ -51,6 +53,7 @@
  * | [] [] [] [] [] [] [] [] [] |
  * | [] [] [] [] [] [] [] [] [] |
  * +----------------------------+
+ * | Item name                  |
  * | Item description           |
  * +----------------------------+
  *                       [ Sort ]
@@ -71,6 +74,17 @@
 }
 
 static void
+compute_box_position(const struct inventory_dialog *dlg, int r, int c, int *x, int *y)
+{
+	assert(dlg);
+	assert(x);
+	assert(y);
+
+	*x = dlg->fgrid.x + ((c * ITEM_SIZE) + ((c + 1) * ITEM_PADDING));
+	*y = dlg->fgrid.y + ((r * ITEM_SIZE) + ((r + 1) * ITEM_PADDING));
+}
+
+static void
 draw_grid_item_frame(int x, int y)
 {
 	struct frame frame = {
@@ -93,7 +107,7 @@
 }
 
 static void
-draw_grid_item_label(struct inventory_slot *slot, int x, int y)
+draw_grid_item_amount(struct inventory_slot *slot, int x, int y)
 {
 	char nstr[16];
 	struct label label = {
@@ -108,33 +122,34 @@
 }
 
 static void
-draw_grid_item(struct inventory_slot *slot, int x, int y)
+draw_grid_item(struct inventory_slot *slot, int x, int y, bool selected)
 {
 	draw_grid_item_frame(x, y);
 
 	if (slot->item) {
 		draw_grid_item_icon(slot->item, x, y);
-		draw_grid_item_label(slot, x, y);
+		draw_grid_item_amount(slot, x, y);
+	}
+
+	if (selected) {
+		x -= 16 + 8;
+		y += (ITEM_SIZE / 2) - 8;
+		painter_draw_rectangle(x, y, 16, 16);
 	}
 }
 
 static void
 draw_grid_items(const struct inventory_dialog *dlg)
 {
-	int x;
-	int y;
-
-	y = ITEM_PADDING;
+	int x, y;
+	bool selected;
 
 	for (int r = 0; r < INVENTORY_ROWS_MAX; ++r) {
-		x = dlg->fgrid.x + ITEM_PADDING;
-
 		for (int c = 0; c < INVENTORY_COLS_MAX; ++c) {
-			draw_grid_item(&dlg->inv->items[r][c], x, y);
-			x += ITEM_SIZE + ITEM_PADDING;
+			selected = r == dlg->selrow && c == dlg->selcol;
+			compute_box_position(dlg, r, c, &x, &y);
+			draw_grid_item(&dlg->inv->items[r][c], x, y, selected);
 		}
-
-		y += ITEM_SIZE + ITEM_PADDING;
 	}
 }
 
@@ -145,10 +160,13 @@
 
 	struct item *item = dlg->inv->items[dlg->selrow][dlg->selcol].item;
 
-	frame_draw(&dlg->flabel);
+	frame_draw(&dlg->fname);
+	frame_draw(&dlg->fdesc);
 
 	if (item) {
+		dlg->lname.text = item->name;
 		dlg->ldesc.text = item->summary;
+		label_draw(&dlg->lname);
 		label_draw(&dlg->ldesc);
 	}
 }
@@ -169,30 +187,98 @@
 	/* Grid frame position. */
 	dlg->fgrid.w = GRID_WIDTH;
 	dlg->fgrid.h = GRID_HEIGHT;
-	dlg->fgrid.x = 0; /* TODO */
-	dlg->fgrid.y = 0;
+	dlg->fgrid.x = dlg->x;
+	dlg->fgrid.y = dlg->y;
 
-	/* Label frame position. */
-	dlg->flabel.w = dlg->ldesc.w = LABEL_WIDTH;
-	dlg->flabel.h = dlg->ldesc.h = LABEL_HEIGHT;
-	dlg->flabel.x = dlg->ldesc.x = 0; /* TODO */
-	dlg->flabel.y = dlg->ldesc.y = GRID_HEIGHT;
+	/* Name label. */
+	dlg->fname.w = dlg->lname.w = LABEL_WIDTH;
+	dlg->fname.h = dlg->lname.h = LABEL_HEIGHT / 2;
+	dlg->fname.x = dlg->lname.x = dlg->x;
+	dlg->fname.y = dlg->lname.y = dlg->y + GRID_HEIGHT;
+	dlg->lname.x += ITEM_PADDING;
+	dlg->lname.flags = LABEL_NO_HCENTER;
+
+	/* Description label. */
+	dlg->fdesc.w = dlg->ldesc.w = LABEL_WIDTH;
+	dlg->fdesc.h = dlg->ldesc.h = LABEL_HEIGHT / 2;
+	dlg->fdesc.x = dlg->ldesc.x = dlg->y;
+	dlg->fdesc.y = dlg->ldesc.y = dlg->y + GRID_HEIGHT + (LABEL_HEIGHT / 2);
 	dlg->ldesc.x += ITEM_PADDING;
 	dlg->ldesc.flags = LABEL_NO_HCENTER;
 
 	/* Button sort. */
-	dlg->bsort.x = 0;
-	dlg->bsort.y = GRID_HEIGHT + LABEL_HEIGHT;
+	dlg->bsort.x = dlg->x;
+	dlg->bsort.y = dlg->y + GRID_HEIGHT + LABEL_HEIGHT;
 	dlg->bsort.w = BUTTON_WIDTH;
 	dlg->bsort.h = BUTTON_HEIGHT;
 	dlg->bsort.text = "Sort";
 }
 
+static void
+handle_keydown(struct inventory_dialog *dlg, const struct event_key *ev)
+{
+	assert(ev && ev->type == EVENT_KEYDOWN);
+
+	switch (ev->key) {
+	case KEY_LEFT:
+		if (dlg->selcol == 0)
+			dlg->selcol = INVENTORY_COLS_MAX - 1;
+		else
+			dlg->selcol--;
+		break;
+	case KEY_RIGHT:
+		dlg->selcol = (dlg->selcol + 1) % INVENTORY_COLS_MAX;
+		break;
+	case KEY_UP:
+		if (dlg->selrow == 0)
+			dlg->selrow = INVENTORY_ROWS_MAX - 1;
+		else
+			dlg->selrow--;
+		break;
+	case KEY_DOWN:
+		dlg->selrow = (dlg->selrow + 1) % INVENTORY_ROWS_MAX;
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+handle_clickdown(struct inventory_dialog *dlg, const struct event_click *ev)
+{
+	assert(dlg);
+	assert(ev && ev->type == EVENT_CLICKDOWN);
+
+	int x, y;
+
+	for (int r = 0; r < INVENTORY_ROWS_MAX; ++r) {
+		for (int c = 0; c < INVENTORY_COLS_MAX; ++c) {
+			compute_box_position(dlg, r, c, &x, &y);
+
+			if (math_is_boxed(x, y, ITEM_SIZE, ITEM_SIZE, ev->x, ev->y)) {
+				dlg->selrow = r;
+				dlg->selcol = c;
+			}
+		}
+	}
+}
+
 void
 inventory_dialog_handle(struct inventory_dialog *dlg, const union event *event)
 {
 	assert(event);
 
+	switch (event->type) {
+	case EVENT_KEYDOWN:
+		handle_keydown(dlg, &event->key);
+		break;
+	case EVENT_CLICKDOWN:
+		handle_clickdown(dlg, &event->click);
+		break;
+	default:
+		break;
+	}
+
 #if 0
 	button_handle(&data.sort, event);
 
@@ -212,6 +298,12 @@
 }
 
 void
+inventory_dialog_move(struct inventory_dialog *dlg, int x, int y)
+{
+	assert(dlg);
+}
+
+void
 inventory_dialog_draw(struct inventory_dialog *dlg)
 {
 	assert(dlg);
--- a/src/core/inventory_dialog.h	Tue Mar 31 21:05:00 2020 +0200
+++ b/src/core/inventory_dialog.h	Tue Mar 31 21:29:54 2020 +0200
@@ -34,12 +34,16 @@
 };
 
 struct inventory_dialog {
+	int x;                                  /*!< (RO) Position in x. */
+	int y;                                  /*!< (RO) Position in y. */
 	struct inventory *inv;                  /*!< (RW, ref) Inventory to use. */
 	struct theme *theme;                    /*!< (RW, ref, optional) Theme to use. */
-	struct label ldesc;                     /*!< (RO) Label containing current description. */
 	struct button bsort;                    /*!< (RO) Button sort. */
 	struct frame fgrid;                     /*!< (RO) Grid frame. */
-	struct frame flabel;                    /*!< (RO) Label frame. */
+	struct frame fname;                     /*!< (RO) Frame for name. */
+	struct frame fdesc;                     /*!< (RO) Frame for description. */
+	struct label lname;                     /*!< (RO) Label for name. */
+	struct label ldesc;                     /*!< (RO) Label for description. */
 	enum inventory_dialog_state state;      /*!< (RO) Current dialog state. */
 	unsigned int selrow;                    /*!< (RO) Current selected row. */
 	unsigned int selcol;                    /*!< (RO) Current selected column. */
@@ -55,6 +59,9 @@
 inventory_dialog_update(struct inventory_dialog *dlg, unsigned int ticks);
 
 void
+inventory_dialog_move(struct inventory_dialog *dlg, int x, int y);
+
+void
 inventory_dialog_draw(struct inventory_dialog *dlg);
 
 void
--- a/src/core/theme.c	Tue Mar 31 21:05:00 2020 +0200
+++ b/src/core/theme.c	Tue Mar 31 21:29:54 2020 +0200
@@ -15089,6 +15089,18 @@
 static struct font default_font;
 
 static void
+box(int x, int y, unsigned int w, unsigned int h)
+{
+	/* Some basic outlines. */
+	painter_set_color(0x4d3533ff);
+
+	painter_draw_line(x, y, x + w, y);
+	painter_draw_line(x, y + h, x + w, y + h);
+	painter_draw_line(x, y, x, y + h);
+	painter_draw_line(x + w, y, x + w, y + h);
+}
+
+static void
 draw_frame(struct theme *t, const struct frame *frame)
 {
 	if (frame->style == FRAME_STYLE_BOX)
@@ -15097,6 +15109,7 @@
 		painter_set_color(0xce9248ff);
 
 	painter_draw_rectangle(frame->x, frame->y, frame->w, frame->h);
+	box(frame->x, frame->y, frame->w, frame->h);
 }
 
 static void
@@ -15155,6 +15168,8 @@
 	painter_draw_rectangle(button->x, button->y, button->w, button->h);
 
 	label_draw(&label);
+
+	box(button->x, button->y, button->w, button->h);
 }
 
 /* Default theme. */