Beispiel #1
0
/*
Function: wz_ask_parent_for_focus

Asks the parent to defocus everyone but the widget that calls this function.

Returns:
1 if the widget already has focus, or succesfully obtained the focus

0 if the widget cannot be focused
*/
int wz_ask_parent_for_focus(WZ_WIDGET* wgt)
{
	if(wgt->flags & WZ_STATE_HAS_FOCUS)
		return 1;

	if(wgt->flags & WZ_STATE_NOTWANT_FOCUS)
		return 0;

	if(wgt->flags & WZ_STATE_DISABLED)
		return 0;

	if(wgt->flags & WZ_STATE_HIDDEN)
		return 0;

	if(wgt->parent == 0)
	{
		ALLEGRO_EVENT event;
		wz_craft_event(&event, WZ_TAKE_FOCUS, wgt, 0);
		wz_send_event(wgt, &event);
	}
	else
	{
		ALLEGRO_EVENT event;

		if(!(wgt->parent->flags & WZ_STATE_HAS_FOCUS))
		{
			wz_ask_parent_for_focus(wgt->parent);
		}

		wz_craft_event(&event, WZ_WANT_FOCUS, wgt, 0);
		wz_send_event(wgt->parent, &event);
	}

	return 1;
}
Beispiel #2
0
/*
Function: wz_update

Updates the widget tree, call this every frame
Doesn't update the disabled widgets

Parameters:
dt - Time that has passed since the last update
*/
void wz_update(WZ_WIDGET* wgt, double dt)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, WZ_UPDATE, 0, 0);
	wz_broadcast_event(wgt, &event);
	wz_craft_event(&event, WZ_UPDATE_POSITION, 0, 0);
	wz_broadcast_event(wgt, &event);
}
Beispiel #3
0
/*
Function: wz_enable

Enables/disables the widget tree

Parameters:
enable - pass 1 to enable the widget tree, or 0 to disable it
*/
void wz_enable(WZ_WIDGET* wgt, int enable)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, enable ? WZ_ENABLE : WZ_DISABLE, 0, 0);
	
	wz_broadcast_event(wgt, &event);
}
Beispiel #4
0
/*
Function: wz_show

Shows/hides the widget tree

Parameters:
show - pass 1 to show the widget tree, or 0 to hide it
*/
void wz_show(WZ_WIDGET* wgt, int show)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, show ? WZ_SHOW : WZ_HIDE, 0, 0);
	
	wz_broadcast_event(wgt, &event);
}
Beispiel #5
0
/*
Function: wz_destroy

Destroys the widget tree. Call it to free all of the memory used by the widget tree.
*/
void wz_destroy(WZ_WIDGET* wgt)
{
	ALLEGRO_EVENT event;
	wz_detach(wgt);
	wz_craft_event(&event, WZ_DESTROY, 0, 0);
	wz_broadcast_event(wgt, &event);
}
Beispiel #6
0
/*
Function: wz_focus

Focuses/defocuses the widget tree. This function propagates the focus down the tree.

Parameters:
focus - pass 1 to focus the widget tree, or 0 to defocus it
*/
void wz_focus(WZ_WIDGET* wgt, int focus)
{
	if (focus)
	{
		wz_ask_parent_for_focus(wgt);
	}
	else
	{
		ALLEGRO_EVENT event;
		wz_craft_event(&event, WZ_LOSE_FOCUS, 0, 0);
		wz_broadcast_event(wgt, &event);
	}
}
Beispiel #7
0
/*
Title: Button

Section: Internal

Function: wz_button_proc

See also:
<wz_widget_proc>
*/
int wz_button_proc(WZ_WIDGET* wgt, const ALLEGRO_EVENT* event)
{
	int ret = 1;
	WZ_BUTTON* but = (WZ_BUTTON*)wgt;
	float x, y;

	switch(event->type)
	{
		case WZ_LOSE_FOCUS:
		{
			ret = 0;
			break;
		}
		case WZ_DRAW:
		{
            if(wgt->flags & WZ_STATE_HIDDEN)
            {
                ret = 0;
            }
            else
            {
                int flags = 0;
                if(wgt->flags & WZ_STATE_DISABLED)
                    flags |= WZ_STYLE_DISABLED;
                else if (wgt->flags & WZ_STATE_HAS_FOCUS)
                    flags |= WZ_STYLE_FOCUSED;
                
                if(but->down) flags |= WZ_STYLE_DOWN;
                
                wgt->theme->draw_button(wgt->theme, wgt->local_x, wgt->local_y, wgt->w, wgt->h, but->text, flags);
            }
            
            break;
        }
#if (ALLEGRO_SUB_VERSION > 0)
		case ALLEGRO_EVENT_TOUCH_MOVE:
			x = event->touch.x;
			y = event->touch.y;
#endif
		case ALLEGRO_EVENT_MOUSE_AXES:
		{
			if(event->type == ALLEGRO_EVENT_MOUSE_AXES)
			{
				x = event->mouse.x;
				y = event->mouse.y;
			}

			if(wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else if((event->mouse.dx != 0 || event->mouse.dy != 0) && wz_widget_rect_test(wgt, x, y) && !(wgt->flags & WZ_STATE_HAS_FOCUS))
			{
				wz_ask_parent_for_focus(wgt);
			}
			else
			{
				ret = 0;
			}

			break;
		}
#if (ALLEGRO_SUB_VERSION > 0)
		case ALLEGRO_EVENT_TOUCH_BEGIN:
			x = event->touch.x;
			y = event->touch.y;
#endif
		case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
		{
			if(event->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
			{
				x = event->mouse.x;
				y = event->mouse.y;
			}

			if(wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else if(wz_widget_rect_test(wgt, x, y))
			{
				wz_ask_parent_for_focus(wgt);
				but->down = 1;
				wgt->hold_focus = 1;
			}
			else
				ret = 0;

			break;
		}
		case ALLEGRO_EVENT_KEY_DOWN:
		{
			switch(event->keyboard.keycode)
			{
				case ALLEGRO_KEY_ENTER:
				{
					if(wgt->flags & WZ_STATE_DISABLED)
					{
						ret = 0;
					}
					else if(wgt->flags & WZ_STATE_HAS_FOCUS)
					{
						but->down = 1;
					}
					else
						ret = 0;

					break;
				}
				default:
					ret = 0;
			}

			break;
		}
		case ALLEGRO_EVENT_KEY_UP:
		{
			switch(event->keyboard.keycode)
			{
				case ALLEGRO_KEY_ENTER:
				{
					if(wgt->flags & WZ_STATE_DISABLED)
					{
						ret = 0;
					}
					else if(wgt->flags & WZ_STATE_HAS_FOCUS)
					{
						wz_trigger(wgt);
					}
					else
						ret = 0;

					break;
				}
				default:
					ret = 0;
			}

			break;
		}
		case WZ_HANDLE_SHORTCUT:
		{
			if(wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else
			{
				if(!(wgt->flags & WZ_STATE_HAS_FOCUS))
				{
					wz_ask_parent_for_focus(wgt);
				}

				wz_trigger(wgt);
			}

			break;
		}
#if (ALLEGRO_SUB_VERSION > 0)
		case ALLEGRO_EVENT_TOUCH_END:
			x = event->touch.x;
			y = event->touch.y;
#endif
		case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
		{
			if(event->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)
			{
				x = event->mouse.x;
				y = event->mouse.y;
			}

			if(wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else if(but->down == 1)
			{
				if(wz_widget_rect_test(wgt, x, y))
					wz_trigger(wgt);

				but->down = 0;
				wgt->hold_focus = 0;
			}
			else
			{
				ret = 0;
			}

			break;
		}
		case WZ_DESTROY:
		{
			if(but->own)
				al_ustr_free(but->text);

			ret = 0;
			break;
		}
		case WZ_SET_TEXT:
		{
			if(but->own)
			{
				al_ustr_free(but->text);
				but->text = al_ustr_dup((ALLEGRO_USTR*)event->user.data3);
			}
			else
			{
				but->text = (ALLEGRO_USTR*)event->user.data3;
			}

			break;
		}
		case WZ_TRIGGER:
		{
			ALLEGRO_EVENT ev;
			but->down = 0;
			wz_craft_event(&ev, WZ_BUTTON_PRESSED, wgt, 0);
			al_emit_user_event(wgt->source,	&ev, 0);
			break;
		}
		default:
			ret = 0;
	}

	if(ret == 0)
		ret = wz_widget_proc(wgt, event);

	return ret;
}
Beispiel #8
0
/*
Title: Edit Box

Section: Internal

Function: wz_editbox_proc

See also:
<wz_widget_proc>
*/
int wz_editbox_proc(WZ_WIDGET* wgt, ALLEGRO_EVENT* event)
{
	int ret = 1;
	WZ_EDITBOX* box = (WZ_EDITBOX*)wgt;
	switch (event->type)
	{
		case WZ_DRAW:
		{
			if (wgt->flags & WZ_STATE_HIDDEN)
			{
				ret = 0;
			}
			else
			{
				int size = al_ustr_size(box->text);
				int scroll_offset = al_ustr_offset(box->text, box->scroll_pos);
				ALLEGRO_USTR_INFO info;
				ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, scroll_offset, size);
				
				int pos = box->cursor_pos - box->scroll_pos;
			
				int flags = 0;
				if(wgt->flags & WZ_STATE_DISABLED)
					flags = WZ_STYLE_DISABLED;
				else if(wgt->flags & WZ_STATE_HAS_FOCUS)
					flags = WZ_STYLE_FOCUSED;
			
				wgt->theme->draw_editbox(wgt->theme, wgt->local_x, wgt->local_y, wgt->w, wgt->h, pos, text, flags);
			}
			break;
		}
		case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
		{
			if (wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else if (event->mouse.button == 1 && wz_widget_rect_test(wgt, event->mouse.x, event->mouse.y))
			{
				int len = al_ustr_length(box->text);
				ALLEGRO_USTR_INFO info;
				ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, box->scroll_pos, len - 1);
			
				ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0);
				wz_ask_parent_for_focus(wgt);
				box->cursor_pos = wz_get_text_pos(font, text, event->mouse.x - wgt->x) + box->scroll_pos;
			}
			else
				ret = 0;
			break;
		}
#if (ALLEGRO_SUB_VERSION > 0)
		case ALLEGRO_EVENT_TOUCH_BEGIN:
		{
			if (wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else if (wz_widget_rect_test(wgt, event->touch.x, event->touch.y))
			{
				int len = al_ustr_length(box->text);
				ALLEGRO_USTR_INFO info;
				ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, box->scroll_pos, len - 1);

				ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0);
				wz_ask_parent_for_focus(wgt);
				box->cursor_pos = wz_get_text_pos(font, text, event->touch.x - wgt->x) + box->scroll_pos;
			}
			else
				ret = 0;
			break;
		}
#endif
		case WZ_HANDLE_SHORTCUT:
		{
			wz_ask_parent_for_focus(wgt);
			break;
		}
		case WZ_DESTROY:
		{
			if(box->own)
				al_ustr_free(box->text);
			ret = 0;
			break;
		}
		case ALLEGRO_EVENT_KEY_CHAR:
		{
			int len;
			if(wgt->flags & WZ_STATE_DISABLED || !(wgt->flags & WZ_STATE_HAS_FOCUS))
			{
				ret = 0;
				break;
			}
			else if(event->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL || event->keyboard.modifiers & ALLEGRO_KEYMOD_ALT)
			{
				ret = 0;
			}
			
			len = al_ustr_length(box->text);
			
			if((int)(event->keyboard.unichar) > 31 && (int)(event->keyboard.unichar) != 127)
			{
				al_ustr_insert_chr(box->text, al_ustr_offset(box->text, box->cursor_pos), event->keyboard.unichar);
				box->cursor_pos++;
			}
			else
			{
				switch (event->keyboard.keycode)
				{
					case ALLEGRO_KEY_BACKSPACE:
					{
						if (len > 0 && box->cursor_pos > 0)
						{
							al_ustr_remove_chr(box->text, al_ustr_offset(box->text, box->cursor_pos - 1));
							box->cursor_pos--;
						}
						break;
					}
					case ALLEGRO_KEY_DELETE:
					{
						if (len > 0 && box->cursor_pos < len)
						{
							al_ustr_remove_chr(box->text, al_ustr_offset(box->text, box->cursor_pos));
						}
						break;
					}
					case ALLEGRO_KEY_LEFT:
					{
						if (box->cursor_pos > 0)
						{
							box->cursor_pos--;
						}
						else
							ret = 0;
						break;
					}
					case ALLEGRO_KEY_RIGHT:
					{
						if (box->cursor_pos < len)
						{
							box->cursor_pos++;
						}
						else
							ret = 0;
						break;
					}
					case ALLEGRO_KEY_HOME:
					{
						box->cursor_pos = 0;
						break;
					}
					case ALLEGRO_KEY_END:
					{
						len = al_ustr_length(box->text);
						box->cursor_pos = len;
						break;
					}
					case ALLEGRO_KEY_ENTER:
					{
						wz_trigger(wgt);
						break;
					}
					default:
						ret = 0;
				}
			}
			
			wz_snap_editbox(box);
			
			break;
		}
		case WZ_SET_CURSOR_POS:
		{
			box->cursor_pos = event->user.data3;
			wz_snap_editbox(box);
		}
		case WZ_SET_TEXT:
		{
			if(box->own)
			{
				al_ustr_assign(box->text, (ALLEGRO_USTR*)event->user.data3);
			}
			else
				box->text = (ALLEGRO_USTR*)event->user.data3;
			wz_snap_editbox(box);
			break;
		}
		case WZ_TRIGGER:
		{
			ALLEGRO_EVENT ev;
			wz_craft_event(&ev, WZ_TEXT_CHANGED, wgt, 0);
			al_emit_user_event(wgt->source,	&ev, 0);
			break;
		}
		case ALLEGRO_EVENT_MOUSE_AXES:
		{
			if (wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			if (wz_widget_rect_test(wgt, event->mouse.x, event->mouse.y))
			{
				wz_ask_parent_for_focus(wgt);
			}
			return wz_widget_proc(wgt, event);
			break;
		}
		default:
			ret = 0;
	}
	if (ret == 0)
		ret = wz_widget_proc(wgt, event);
	return ret;
}
Beispiel #9
0
/*
Title: Widget

Section: Internal

Function: wz_widget_proc

Callback function that handles the operations of a general widget.
All widget procs call this function as their default handler.

Returns:

1 if the event was handled by the widget, 0 otherwise
*/
int wz_widget_proc(WZ_WIDGET* wgt, ALLEGRO_EVENT* event)
{
	int ret = 1;
	switch (event->type)
	{
		case WZ_HIDE:
		{
			wgt->flags |= WZ_STATE_HIDDEN;
			break;
		}
		case WZ_SHOW:
		{
			wgt->flags &= ~WZ_STATE_HIDDEN;
			break;
		}
		case WZ_DISABLE:
		{
			wgt->flags |= WZ_STATE_DISABLED;
			break;
		}
		case WZ_ENABLE:
		{
			wgt->flags &= ~WZ_STATE_DISABLED;
			break;
		}
		case WZ_UPDATE_POSITION:
		{
			if (wgt->parent)
			{
				wgt->local_x = wgt->parent->local_x + wgt->x;
				wgt->local_y = wgt->parent->local_y + wgt->y;
			}
			else
			{
				wgt->local_x = wgt->x;
				wgt->local_y = wgt->y;
			}
			break;
		}
		case WZ_DESTROY:
		{
			al_destroy_user_event_source(wgt->source);
			free(wgt->source);
			free(wgt);
			break;
		}
		case WZ_LOSE_FOCUS:
		{
			wgt->flags &= ~WZ_STATE_HAS_FOCUS;
			break;
		}
		case WZ_TAKE_FOCUS:
		{
			wz_focus(wgt, 0);
			wgt->flags |= WZ_STATE_HAS_FOCUS;
			if (wgt->first_child)
				wz_focus(wgt->first_child, 1);
			break;
		}
		case WZ_WANT_FOCUS:
		{
			WZ_WIDGET* child = wgt->first_child;
			while (child)
			{
				wz_focus(child, 0);
				child = child->next_sib;
			}
			{
			ALLEGRO_EVENT ev;
			wz_craft_event(&ev, WZ_TAKE_FOCUS, wgt, 0);
			
			child = wgt->first_child;
			wz_send_event((WZ_WIDGET*)event->user.data2, &ev);
			}
			break;
		}
		case ALLEGRO_EVENT_MOUSE_AXES:
		{
			if (wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else if (event->mouse.dz != 0 && wgt->first_child == 0 && wgt->parent != 0)
			{
				if (event->mouse.dz > 0)
				{
					wz_ask_parent_to_focus_prev(wgt);
				}
				else
				{
					wz_ask_parent_to_focus_next(wgt);
				}
			}
			else
			{
				ret = 0;
			}
			break;
		}
		/* Switch through elements on Touch:
		case ALLEGRO_EVENT_TOUCH_BEGIN:
		{
			if (wgt->flags & WZ_STATE_DISABLED)
			{
				ret = 0;
			}
			else if (wgt->first_child == 0 && wgt->parent != 0)
			{
				wz_ask_parent_to_focus_next(wgt);
			}
			else
			{
				ret = 0;
			}
			break;
		}
		*/
		case ALLEGRO_EVENT_KEY_CHAR:
		{
			if(event->keyboard.keycode == wgt->shortcut.keycode && ((event->keyboard.modifiers & wgt->shortcut.modifiers) || wgt->shortcut.modifiers == 0))
			{
				ALLEGRO_EVENT ev;
				wz_craft_event(&ev, WZ_HANDLE_SHORTCUT, wgt, 0);
				wz_send_event(wgt, &ev);
			}
			else
			{
				switch (event->keyboard.keycode)
				{
					case ALLEGRO_KEY_TAB:
					{
						if (wgt->first_child != 0)
						{
							ret = 0;
						}
						else if (event->keyboard.modifiers & 1)
						{
							wz_ask_parent_to_focus_prev(wgt);
						}
						else
						{
							wz_ask_parent_to_focus_next(wgt);
						}
						break;
					}
					case ALLEGRO_KEY_UP:
					{
						if (wgt->first_child != 0)
						{
							ret = 0;
						}
						else if (wgt->parent != 0)
						{
							wz_ask_parent_for_focus(wz_get_widget_dir(wgt, 0));
						}
						else
							ret = 0;
						break;
					}
					case ALLEGRO_KEY_RIGHT:
					{
						if (wgt->first_child != 0)
						{
							ret = 0;
						}
						else if (wgt->parent != 0)
						{
							wz_ask_parent_for_focus(wz_get_widget_dir(wgt, 1));
						}
						else
							ret = 0;
						break;
					}
					case ALLEGRO_KEY_DOWN:
					{
						if (wgt->first_child != 0)
						{
							ret = 0;
						}
						else if (wgt->parent != 0)
						{
							wz_ask_parent_for_focus(wz_get_widget_dir(wgt, 2));
						}
						else
							ret = 0;
						break;
					}
					case ALLEGRO_KEY_LEFT:
					{
						if (wgt->first_child != 0)
						{
							ret = 0;
						}
						else if (wgt->parent != 0)
						{
							wz_ask_parent_for_focus(wz_get_widget_dir(wgt, 3));
						}
						else
							ret = 0;
						break;
					}
					default:
						ret = 0;
				}
			}
			break;
		}
		default:
			ret = 0;
	}
	return ret;
}
Beispiel #10
0
/*
Function: wz_set_cursor_pos

Sets the cursor position
*/
void wz_set_cursor_pos(WZ_WIDGET* wgt, int pos)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, WZ_SET_CURSOR_POS, 0, pos);
	wz_send_event(wgt, &event);
}
Beispiel #11
0
/*
Function: wz_set_scroll_pos

Sets the scroll position

Parameters:
max - Pass 1 to say that pos is actually the max position, 0 otherwise
*/
void wz_set_scroll_pos(WZ_WIDGET* wgt, int pos, int max)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, max ? WZ_SET_SCROLL_MAX_POS : WZ_SET_SCROLL_POS, 0, pos);
	wz_send_event(wgt, &event);
}
Beispiel #12
0
/*
Function: wz_set_text

Sets the text of a widget. The widget makes a local copy of the text.
*/
void wz_set_text(WZ_WIDGET* wgt, ALLEGRO_USTR* text)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, WZ_SET_TEXT, 0, (intptr_t)text);
	wz_send_event(wgt, &event);
}
Beispiel #13
0
/*
Function: wz_draw

Draws the widget tree. Only affects the visible widgets
*/
void wz_draw(WZ_WIDGET* wgt)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, WZ_DRAW, 0, 0);
	wz_broadcast_event(wgt, &event);
}
Beispiel #14
0
/*
Function: wz_trigger

Triggers a widget. What the widget does depends on the widget. Generally, it will send
an event that is characteristic of the events that it usually sends. For example,
triggering a button will simulate an impression of the button, causing it to send <WZ_BUTTON_PRESSED>
event.
*/
void wz_trigger(WZ_WIDGET* wgt)
{
	ALLEGRO_EVENT event;
	wz_craft_event(&event, WZ_TRIGGER, 0, 0);
	wz_send_event(wgt, &event);
}
Beispiel #15
0
/*
 Function: wz_resize
 
 Resizes the widget tree. 
 
 Parameters:
 factor: scaling factor
 */
void wz_resize(WZ_WIDGET* wgt, float factor)
{
    ALLEGRO_EVENT event;
    wz_craft_event(&event, WZ_RESIZE, 0, *(intptr_t*)&factor);
    wz_broadcast_event(wgt, &event);
}