1 /// module containing the button UI element
2 module ysge.ui.button;
3 
4 import std.string;
5 import ysge.project;
6 
7 alias ButtonOnClick = void delegate(Project, Button);
8 
9 /// button UI element
10 class Button : UIElement {
11 	private string       label; /// the text that displays on the button
12 	private SDL_Texture* labelTexture;
13 	ButtonOnClick        onClick; /// called when the button is clicked
14 	SDL_Rect             rect; /// the rectangle the button will be rendered in
15 	SDL_Color            fill; /// the background colour of the button
16 	SDL_Color            outline; /// the colour of the button outline
17 	SDL_Color            labelColour; /// the colour of the label text
18 
19 	/// sets the button's label
20 	void SetLabel(string newLabel) {
21 		if (newLabel != label) {
22 			labelTexture = null;
23 		}
24 
25 		label = newLabel;
26 	}
27 
28 	override bool HandleEvent(Project project, SDL_Event e) {
29 		switch (e.type) {
30 			case SDL_MOUSEBUTTONDOWN: {
31 				if (e.button.button != SDL_BUTTON_LEFT) {
32 					return false;
33 				}
34 
35 				auto mouse = project.mousePos;
36 
37 				if (
38 					(mouse.x > rect.x) &&
39 					(mouse.y > rect.y) &&
40 					(mouse.x < rect.x + rect.w) &&
41 					(mouse.y < rect.y + rect.h)
42 				) {
43 					onClick(project, this);
44 				}
45 				else {
46 					return false;
47 				}
48 				break;
49 			}
50 			default: return false;
51 		}
52 
53 		return false;
54 	}
55 
56 	override void Render(Project project) {
57 		SDL_SetRenderDrawColor(project.renderer, fill.r, fill.g, fill.b, fill.a);
58 		SDL_RenderFillRect(project.renderer, &rect);
59 		SDL_SetRenderDrawColor(
60 			project.renderer, outline.r, outline.g, outline.b, outline.a
61 		);
62 		SDL_RenderDrawRect(project.renderer, &rect);
63 
64 		if (label.strip() == "") {
65 			return;
66 		}
67 
68 		if (labelTexture is null) {
69 			SDL_Surface* labelSurface = TTF_RenderText_Solid(
70 				project.font, toStringz(label), labelColour
71 			);
72 
73 			if (labelSurface is null) {
74 				throw new ProjectException("Failed to render text");
75 			}
76 
77 			labelTexture = SDL_CreateTextureFromSurface(
78 				project.renderer, labelSurface
79 			);
80 
81 			if (labelTexture is null) {
82 				throw new ProjectException("Failed to create text texture");
83 			}
84 		}
85 
86 		SDL_Rect textBox;
87 		SDL_QueryTexture(labelTexture, null, null, &textBox.w, &textBox.h);
88 		textBox.x  = rect.x;
89 		textBox.y  = rect.y;
90 		textBox.x += (rect.w / 2) - (textBox.w / 2);
91 		textBox.y += (rect.h / 2) - (textBox.h / 2);
92 
93 		SDL_RenderCopy(project.renderer, labelTexture, null, &textBox);
94 	}
95 }