Add layouts and decouple immediate drawings
This commit is contained in:
		
							parent
							
								
									3bb8a63ee1
								
							
						
					
					
						commit
						c8e6c320f1
					
				
							
								
								
									
										118
									
								
								src/k3menu.c
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								src/k3menu.c
									
									
									
									
									
								
							| @ -3,6 +3,78 @@ | |||||||
| #include<string.h> | #include<string.h> | ||||||
| #include<stdio.h> | #include<stdio.h> | ||||||
| #include<GLFW/glfw3.h> | #include<GLFW/glfw3.h> | ||||||
|  | #include"immdraw.h" | ||||||
|  | 
 | ||||||
|  | void k3MMeasure(struct k3MObj *this) { | ||||||
|  | 	for(size_t c = 0; c < this->childCount; c++) { | ||||||
|  | 		k3MMeasure(this->children[c]); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	struct k3MEvent newev = { | ||||||
|  | 		.code = k3M_EVENT_MEASURE, | ||||||
|  | 		.kind = k3M_EVENTKIND_DIRECT, | ||||||
|  | 		 | ||||||
|  | 		.original = (void*) this, | ||||||
|  | 		.target = (void*) this, | ||||||
|  | 	}; | ||||||
|  | 	if(!k3MEventSend(&newev)) { | ||||||
|  | 		this->wDesired = this->w; | ||||||
|  | 		this->hDesired = this->h; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void k3MArrange(struct k3MObj *this) { | ||||||
|  | 	struct k3MEvent newev = { | ||||||
|  | 		.code = k3M_EVENT_ARRANGE, | ||||||
|  | 		.kind = k3M_EVENTKIND_DIRECT, | ||||||
|  | 		 | ||||||
|  | 		.original = (void*) this, | ||||||
|  | 		.target = (void*) this, | ||||||
|  | 	}; | ||||||
|  | 	k3MEventSend(&newev); | ||||||
|  | 	 | ||||||
|  | 	for(size_t c = 0; c < this->childCount; c++) { | ||||||
|  | 		k3MArrange(this->children[c]); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static bool linear_measure(struct k3MEvent *ev, uint8_t *ud) { | ||||||
|  | 	struct k3MObj *o = ev->target; | ||||||
|  | 	 | ||||||
|  | 	o->wDesired = 0; | ||||||
|  | 	o->hDesired = 0; | ||||||
|  | 	 | ||||||
|  | 	for(size_t i = 0; i < o->childCount; i++) { | ||||||
|  | 		struct k3MObj *c = o->children[i]; | ||||||
|  | 		 | ||||||
|  | 		if(o->wDesired < c->wDesired) { | ||||||
|  | 			o->wDesired = c->wDesired; | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		o->hDesired += c->hDesired; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | static bool linear_arrange(struct k3MEvent *ev, uint8_t *ud) { | ||||||
|  | 	struct k3MObj *o = ev->target; | ||||||
|  | 	 | ||||||
|  | 	size_t y = o->y; | ||||||
|  | 	 | ||||||
|  | 	for(size_t i = 0; i < o->childCount; i++) { | ||||||
|  | 		struct k3MObj *c = o->children[i]; | ||||||
|  | 		 | ||||||
|  | 		c->x = o->x; | ||||||
|  | 		c->y = y; | ||||||
|  | 		 | ||||||
|  | 		c->w = c->wDesired; | ||||||
|  | 		c->h = c->hDesired; | ||||||
|  | 		 | ||||||
|  | 		y += c->h; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | void k3MSetLayoutLinear(struct k3MObj *this, bool vertical) { | ||||||
|  | 	k3MRegisterEventHandler(this, k3M_EVENT_MEASURE, linear_measure, NULL, 0); | ||||||
|  | 	k3MRegisterEventHandler(this, k3M_EVENT_ARRANGE, linear_arrange, NULL, 0); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h) { | void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h) { | ||||||
| 	this->x = x; | 	this->x = x; | ||||||
| @ -38,6 +110,8 @@ int k3MRegisterEventHandler_(struct k3MObj *obj, uint16_t evcode, k3MEventHandle | |||||||
| 	if(ud) { | 	if(ud) { | ||||||
| 		memcpy(obj->handlers[obj->handlerCount - 1].ud, ud, udSize); | 		memcpy(obj->handlers[obj->handlerCount - 1].ud, ud, udSize); | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
|  | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool k3MEventSend(struct k3MEvent *ev) { | bool k3MEventSend(struct k3MEvent *ev) { | ||||||
| @ -83,10 +157,9 @@ static void obj_draw(struct k3MObj *this) { | |||||||
| 		bgColor[3] = bgColorProp->si[3] / 255.0; | 		bgColor[3] = bgColorProp->si[3] / 255.0; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	k3BatchAdd(NULL, (struct k3RectF) {0, 0, 1, 1}, (struct k3RectF) { | 	if(bgColor[3] != 0) { | ||||||
| 		this->x, this->y, | 		immdraw_fill_rect(this->x, this->y, this->w, this->h, bgColor[0], bgColor[1], bgColor[2], bgColor[3], borderRadius); | ||||||
| 		this->w, this->h | 	} | ||||||
| 	}, 0, bgColor, borderRadius); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool label_draw(struct k3MEvent *ev, uint8_t *ud) { | static bool label_draw(struct k3MEvent *ev, uint8_t *ud) { | ||||||
| @ -95,7 +168,13 @@ static bool label_draw(struct k3MEvent *ev, uint8_t *ud) { | |||||||
| 	obj_draw((void*) this); | 	obj_draw((void*) this); | ||||||
| 	 | 	 | ||||||
| 	if(this->txt) { | 	if(this->txt) { | ||||||
| 		k3FontDraw(this->font, this->x, this->y, this->sz, this->txt, (vec4) {1, 1, 1, 1}); | 		int alignment = k3M_ALIGN_CENTER; | ||||||
|  | 		 | ||||||
|  | 		struct k3MProperty *prop = k3MFindProperty(this, k3M_PROP_HORIZONTAL_ALIGNMENT, false); | ||||||
|  | 		if(prop) alignment = prop->si[0]; | ||||||
|  | 		 | ||||||
|  | 		immdraw_font_draw(this->font, this->x, this->y, this->w, this->sz, strlen(this->txt), this->txt, alignment, | ||||||
|  | 			1, 1, 1, 1); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	return false; | 	return false; | ||||||
| @ -105,7 +184,7 @@ struct k3MLabel *k3MLabel(struct k3Font *font, float sz, const char *txt) { | |||||||
| 	struct k3MLabel *ret = calloc(1, sizeof(*ret)); | 	struct k3MLabel *ret = calloc(1, sizeof(*ret)); | ||||||
| 	ret->font = font; | 	ret->font = font; | ||||||
| 	ret->sz = sz; | 	ret->sz = sz; | ||||||
| 	ret->txt = txt; | 	ret->txt = strdup(txt); | ||||||
| 	 | 	 | ||||||
| 	k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0); | 	k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0); | ||||||
| 	 | 	 | ||||||
| @ -260,11 +339,19 @@ static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) { | |||||||
| 	obj_draw((void*) this); | 	obj_draw((void*) this); | ||||||
| 	 | 	 | ||||||
| 	if(this->txt) { | 	if(this->txt) { | ||||||
| 		struct k3RectF txtsz; | 		/*struct k3RectF txtsz;
 | ||||||
| 		k3FontSz(this->font, this->sz, this->txt, &txtsz); | 		k3FontSz(this->font, this->sz, this->txt, &txtsz); | ||||||
| 		 | 		 | ||||||
| 		k3FontDraw(this->font, this->x + this->w / 2 - txtsz.w / 2, this->y, this->sz, this->txt, (vec4) { | 		k3FontDraw(this->font, this->x + this->w / 2 - txtsz.w / 2, this->y, this->sz, this->txt, (vec4) { | ||||||
| 			1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1}); | 			1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1});*/ | ||||||
|  | 		 | ||||||
|  | 		int alignment = k3M_ALIGN_CENTER; | ||||||
|  | 		 | ||||||
|  | 		struct k3MProperty *prop = k3MFindProperty(this, k3M_PROP_HORIZONTAL_ALIGNMENT, false); | ||||||
|  | 		if(prop) alignment = prop->si[0]; | ||||||
|  | 		 | ||||||
|  | 		immdraw_font_draw(this->font, this->x, this->y, this->w, this->sz, strlen(this->txt), this->txt, alignment, | ||||||
|  | 			1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	return false; | 	return false; | ||||||
| @ -274,7 +361,7 @@ struct k3MTextButton *k3MTextButton(struct k3Font *font, float sz, const char *t | |||||||
| 	 | 	 | ||||||
| 	ret->font = font; | 	ret->font = font; | ||||||
| 	ret->sz = sz; | 	ret->sz = sz; | ||||||
| 	ret->txt = txt; | 	ret->txt = strdup(txt); | ||||||
| 	 | 	 | ||||||
| 	k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textbutton_draw, NULL, 0); | 	k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textbutton_draw, NULL, 0); | ||||||
| 	 | 	 | ||||||
| @ -287,13 +374,16 @@ static bool textinput_draw(struct k3MEvent *ev, uint8_t *ud) { | |||||||
| 	obj_draw((void*) this); | 	obj_draw((void*) this); | ||||||
| 	 | 	 | ||||||
| 	if(this->txt) { | 	if(this->txt) { | ||||||
| 		int isPlaceholder = strlen(this->txt) == 0; | 		bool isPlaceholder = strlen(this->txt) == 0; | ||||||
| 		const char *txt = isPlaceholder ? this->placeholder : this->txt; | 		const char *txt = isPlaceholder ? this->placeholder : this->txt; | ||||||
| 		 | 		 | ||||||
| 		struct k3RectF txtsz; | 		/*struct k3RectF txtsz;
 | ||||||
| 		k3FontSz(this->font, this->sz, txt, &txtsz); | 		k3FontSz(this->font, this->sz, txt, &txtsz); | ||||||
| 		 | 		 | ||||||
| 		k3FontDraw(this->font, this->x, this->y, this->sz, txt, (vec4) {1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1}); | 		k3FontDraw(this->font, this->x, this->y, this->sz, txt, (vec4) {1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1});*/ | ||||||
|  | 		 | ||||||
|  | 		immdraw_font_draw(this->font, this->x, this->y, this->w, this->sz, strlen(txt), txt, k3M_ALIGN_LEFT, | ||||||
|  | 			1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	return false; | 	return false; | ||||||
| @ -302,7 +392,7 @@ static bool textinput_key(struct k3MEvent *ev, uint8_t *ud) { | |||||||
| 	struct k3MTextInput *this = (void*) ev->target; | 	struct k3MTextInput *this = (void*) ev->target; | ||||||
| 	 | 	 | ||||||
| 	if(ev->key.num == GLFW_KEY_BACKSPACE && ev->code != k3M_EVENT_KEY_RELEASE) { | 	if(ev->key.num == GLFW_KEY_BACKSPACE && ev->code != k3M_EVENT_KEY_RELEASE) { | ||||||
| 		char *last = k3UTF8LastCodepointZ(this->txt); | 		char *last = (char*) k3UTF8LastCodepointZ(this->txt); | ||||||
| 		if(last) { | 		if(last) { | ||||||
| 			*last = 0; | 			*last = 0; | ||||||
| 		} | 		} | ||||||
| @ -336,7 +426,7 @@ struct k3MTextInput *k3MTextInput(struct k3Font *font, float sz, const char *pla | |||||||
| 	 | 	 | ||||||
| 	ret->font = font; | 	ret->font = font; | ||||||
| 	ret->sz = sz; | 	ret->sz = sz; | ||||||
| 	ret->placeholder = placeholder ? placeholder : ""; | 	ret->placeholder = strdup(placeholder ? placeholder : ""); | ||||||
| 	ret->txt = strdup(txt ? txt : ""); | 	ret->txt = strdup(txt ? txt : ""); | ||||||
| 	 | 	 | ||||||
| 	k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textinput_draw, NULL, 0); | 	k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textinput_draw, NULL, 0); | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								src/k3menu.h
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								src/k3menu.h
									
									
									
									
									
								
							| @ -3,8 +3,9 @@ | |||||||
| #include<stdint.h> | #include<stdint.h> | ||||||
| #include<stdlib.h> | #include<stdlib.h> | ||||||
| #include<stdbool.h> | #include<stdbool.h> | ||||||
| #include"k3font.h" | #include<stddef.h> | ||||||
| 
 | 
 | ||||||
|  | struct k3Font; | ||||||
| struct k3MObj; | struct k3MObj; | ||||||
| 
 | 
 | ||||||
| #define k3M_EVENT_MOUSE_ENTER 0 | #define k3M_EVENT_MOUSE_ENTER 0 | ||||||
| @ -18,7 +19,9 @@ struct k3MObj; | |||||||
| #define k3M_EVENT_INPUT 8 | #define k3M_EVENT_INPUT 8 | ||||||
| #define k3M_EVENT_DRAW 9 | #define k3M_EVENT_DRAW 9 | ||||||
| #define k3M_EVENT_COMPLETE 10 | #define k3M_EVENT_COMPLETE 10 | ||||||
| #define k3M_EVENT_ALL 11 | #define k3M_EVENT_MEASURE 11 | ||||||
|  | #define k3M_EVENT_ARRANGE 12 | ||||||
|  | #define k3M_EVENT_ALL 13 | ||||||
| 
 | 
 | ||||||
| #define k3M_MOUSE_BUTTON_0 0 | #define k3M_MOUSE_BUTTON_0 0 | ||||||
| #define k3M_MOUSE_BUTTON_1 1 | #define k3M_MOUSE_BUTTON_1 1 | ||||||
| @ -30,6 +33,16 @@ struct k3MObj; | |||||||
| 
 | 
 | ||||||
| #define k3M_USERDATA_SIZE 16 | #define k3M_USERDATA_SIZE 16 | ||||||
| 
 | 
 | ||||||
|  | #define k3M_ALIGN_LEFT 0 | ||||||
|  | #define k3M_ALIGN_CENTER 1 | ||||||
|  | #define k3M_ALIGN_RIGHT 2 | ||||||
|  | 
 | ||||||
|  | #ifdef k3M_FIXED_POINT | ||||||
|  | typedef uint8_t k3MCC; | ||||||
|  | #else | ||||||
|  | typedef float k3MCC; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| struct k3MEvent { | struct k3MEvent { | ||||||
| 	uint16_t code; | 	uint16_t code; | ||||||
| 	 | 	 | ||||||
| @ -64,6 +77,8 @@ typedef struct k3MEventHandler { | |||||||
| enum k3MPropertyType { | enum k3MPropertyType { | ||||||
| 	k3M_PROP_BG_COLOR, | 	k3M_PROP_BG_COLOR, | ||||||
| 	k3M_PROP_BORDER_RADIUS, | 	k3M_PROP_BORDER_RADIUS, | ||||||
|  | 	k3M_PROP_MARGIN, | ||||||
|  | 	k3M_PROP_HORIZONTAL_ALIGNMENT, | ||||||
| }; | }; | ||||||
| struct k3MProperty { | struct k3MProperty { | ||||||
| 	enum k3MPropertyType type; | 	enum k3MPropertyType type; | ||||||
| @ -85,6 +100,9 @@ struct k3MObj { | |||||||
| 	int16_t w; | 	int16_t w; | ||||||
| 	int16_t h; | 	int16_t h; | ||||||
| 	 | 	 | ||||||
|  | 	int16_t wDesired; | ||||||
|  | 	int16_t hDesired; | ||||||
|  | 	 | ||||||
| 	bool invisible, hovered, disabled; | 	bool invisible, hovered, disabled; | ||||||
| 	 | 	 | ||||||
| 	k3MEventHandler *handlers; | 	k3MEventHandler *handlers; | ||||||
| @ -93,6 +111,16 @@ struct k3MObj { | |||||||
| 	struct k3MProperty *properties; | 	struct k3MProperty *properties; | ||||||
| 	size_t propertyCount; | 	size_t propertyCount; | ||||||
| }; | }; | ||||||
|  | struct k3MObj *k3MObj(); | ||||||
|  | 
 | ||||||
|  | /* Akin to the measure pass of WPF. Recursive, called by parent. Sets wDesired and hDesired. */ | ||||||
|  | void k3MMeasure(struct k3MObj *this); | ||||||
|  | 
 | ||||||
|  | /* Akin to the arrange pass of WPF. Recursive, called by parent after w and h is set. Adjusts all children using it's own definitive size. */ | ||||||
|  | void k3MArrange(struct k3MObj *this); | ||||||
|  | 
 | ||||||
|  | /* Set linear layout management on this object. Must not be called on descendants of k3MObj. */ | ||||||
|  | void k3MSetLayoutLinear(struct k3MObj *this, bool vertical); | ||||||
| 
 | 
 | ||||||
| #define k3MenuSetBounds(a, x, y, w, h) k3MenuSetBounds_((struct k3MObj*) (a), (x), (y), (w), (h)) | #define k3MenuSetBounds(a, x, y, w, h) k3MenuSetBounds_((struct k3MObj*) (a), (x), (y), (w), (h)) | ||||||
| void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h); | void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Mid
						Mid