mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-27 06:34:11 +00:00
817aeb334e
Much of the nq/qw HUD system is quite broken, but the basic status bar seems to be working nicely. As is the console (both client and server). Possibly the biggest benefit is separating the rendering of HUD elements from the updating of them, and much less traversing of invisible views whose only purpose is to control the positioning of the visible views. The view flow tests are currently disabled until I adapt the flow code to ECS. There seems to be a problem with view resizing in that some gravities don't follow resizing correctly.
357 lines
9.2 KiB
C
357 lines
9.2 KiB
C
/*
|
|
view.h
|
|
|
|
console view object
|
|
|
|
Copyright (C) 2003 Bill Currie
|
|
|
|
Author: Bill Currie <bill@taniwha.org>
|
|
Date: 2003/5/5
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to:
|
|
|
|
Free Software Foundation, Inc.
|
|
59 Temple Place - Suite 330
|
|
Boston, MA 02111-1307, USA
|
|
|
|
*/
|
|
|
|
#ifndef __QF_ui_view_h
|
|
#define __QF_ui_view_h
|
|
|
|
#include "QF/ecs/component.h"
|
|
#include "QF/ecs/hierarchy.h"
|
|
|
|
/** \defgroup console_view Console View Objects
|
|
\ingroup console
|
|
*/
|
|
///@{
|
|
|
|
/** Control the positioning of a view within its parent. The directions are
|
|
the standard compass rose (north, east, south, west in clockwise order)
|
|
with north at the top.
|
|
|
|
The origin of the view is taken to be the corresponding point on the edge
|
|
of the view (eg, southeast is bottom right), or the view's center for
|
|
center gravity. When the relative coordinates of the view are (0,0), the
|
|
view's origin is placed on the parent view's gravity point using the view's
|
|
gravity (\em not the parent view's gravity). That is, the parent view's
|
|
gravity has no effect on the view's position within the parent view.
|
|
|
|
The gravity also affects the direction the view moves as the relative
|
|
coordinates of the view change.
|
|
|
|
No checking is done to ensure the view stays within the parent, or that the
|
|
view is smaller than the parent. This is by design. It is up to the drawing
|
|
callbacks to do any necessary clipping.
|
|
*/
|
|
typedef enum {
|
|
grav_center, ///< +ve X right, +ve Y down, -X left, -ve Y up
|
|
grav_north, ///< +ve X right, +ve Y down, -X left, -ve Y up
|
|
grav_northeast, ///< +ve X left, +ve Y down, -X right, -ve Y up
|
|
grav_east, ///< +ve X left, +ve Y down, -X right, -ve Y up
|
|
grav_southeast, ///< +ve X left, +ve Y up, -X right, -ve Y down
|
|
grav_south, ///< +ve X right, +ve Y up, -X left, -ve Y down
|
|
grav_southwest, ///< +ve X right, +ve Y up, -X left, -ve Y down
|
|
grav_west, ///< +ve X right, +ve Y down, -X left, -ve Y up
|
|
grav_northwest, ///< +ve X right, +ve Y down, -X left, -ve Y up
|
|
grav_flow, ///< controlled by view_flow
|
|
} grav_t;
|
|
|
|
extern struct exprtype_s grav_t_type;
|
|
|
|
typedef struct view_pos_s {
|
|
int x;
|
|
int y;
|
|
} view_pos_t;
|
|
|
|
typedef struct viewcont_s {
|
|
grav_t gravity; ///< The gravity of the view.
|
|
unsigned visible:1; ///< If false, view_draw() skips this view.
|
|
unsigned resize_x:1; ///< If true, view's width follows parent's.
|
|
unsigned resize_y:1; ///< If true, view's height follows parent's.
|
|
unsigned bol_suppress:1; ///< If true, view_flow skips at start of line.
|
|
unsigned flow_size:1; ///< If true, view's size is adjusted to flow.
|
|
} viewcont_t;
|
|
|
|
enum {
|
|
/// Coordinates of view's origin relative to parent's gravity point.
|
|
view_pos,
|
|
/// Size of the view.
|
|
view_len,
|
|
/** Absolute coordinates of the top left (northwest) corner of the view.
|
|
Set interally.
|
|
*/
|
|
view_abs,
|
|
/** Coordinates of the top left (northwest) corner of the view relative to
|
|
the parent view's top left corner. Set internally.
|
|
*/
|
|
view_rel,
|
|
view_oldlen,
|
|
view_control,
|
|
view_modified,
|
|
view_onresize,
|
|
view_onmove,
|
|
|
|
view_type_count
|
|
};
|
|
|
|
/** The view object.
|
|
*/
|
|
typedef struct view_s {
|
|
ecs_registry_t *reg;
|
|
uint32_t id;
|
|
uint32_t comp;
|
|
} view_t;
|
|
|
|
#define nullview ((view_t) {})
|
|
|
|
typedef void (*view_resize_f) (view_t view, view_pos_t len);
|
|
typedef void (*view_move_f) (view_t view, view_pos_t abs);
|
|
|
|
#define VIEWINLINE GNU89INLINE inline
|
|
|
|
view_t View_New (ecs_registry_t *reg, view_t parent);
|
|
void View_SetParent (view_t view, view_t parent);
|
|
void View_UpdateHierarchy (view_t view);
|
|
|
|
VIEWINLINE hierref_t *View_GetRef (view_t view);
|
|
VIEWINLINE int View_Valid (view_t view);
|
|
|
|
VIEWINLINE view_t View_GetParent (view_t view);
|
|
VIEWINLINE uint32_t View_ChildCount (view_t view);
|
|
VIEWINLINE view_t View_GetChild (view_t view, uint32_t index);
|
|
|
|
VIEWINLINE void View_SetPos (view_t view, int x, int y);
|
|
VIEWINLINE view_pos_t View_GetPos (view_t view);
|
|
VIEWINLINE view_pos_t View_GetAbs (view_t view);
|
|
VIEWINLINE view_pos_t View_GetRel (view_t view);
|
|
VIEWINLINE void View_SetLen (view_t view, int x, int y);
|
|
VIEWINLINE view_pos_t View_GetLen (view_t view);
|
|
VIEWINLINE void View_SetGravity (view_t view, grav_t grav);
|
|
VIEWINLINE grav_t View_GetGravity (view_t view);
|
|
VIEWINLINE void View_SetVisible (view_t view, int visible);
|
|
VIEWINLINE int View_GetVisible (view_t view);
|
|
VIEWINLINE void View_SetResize (view_t view, int resize_x, int resize_y);
|
|
VIEWINLINE void View_SetOnResize (view_t view, view_resize_f onresize);
|
|
VIEWINLINE void View_SetOnMove (view_t view, view_move_f onmove);
|
|
|
|
#undef VIEWINLINE
|
|
#ifndef IMPLEMENT_VIEW_Funcs
|
|
#define VIEWINLINE GNU89INLINE inline
|
|
#else
|
|
#define VIEWINLINE VISIBLE
|
|
#endif
|
|
|
|
VIEWINLINE
|
|
hierref_t *
|
|
View_GetRef (view_t view)
|
|
{
|
|
return Ent_GetComponent (view.id, view.comp, view.reg);
|
|
}
|
|
|
|
VIEWINLINE
|
|
int
|
|
View_Valid (view_t view)
|
|
{
|
|
return view.reg && ECS_EntValid (view.id, view.reg);
|
|
}
|
|
|
|
VIEWINLINE
|
|
view_t
|
|
View_GetParent (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
if (ref->index == 0) {
|
|
return nullview;
|
|
}
|
|
hierarchy_t *h = ref->hierarchy;
|
|
return (view_t) {
|
|
.reg = view.reg,
|
|
.id = h->ent[h->parentIndex[ref->index]],
|
|
.comp = view.comp,
|
|
};
|
|
}
|
|
|
|
VIEWINLINE
|
|
uint32_t
|
|
View_ChildCount (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
return h->childCount[ref->index];
|
|
}
|
|
|
|
VIEWINLINE
|
|
view_t
|
|
View_GetChild (view_t view, uint32_t childIndex)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
if (childIndex >= h->childCount[ref->index]) {
|
|
return nullview;
|
|
}
|
|
return (view_t) {
|
|
.reg = view.reg,
|
|
.id = h->ent[h->childIndex[ref->index] + childIndex],
|
|
.comp = view.comp,
|
|
};
|
|
}
|
|
|
|
|
|
VIEWINLINE
|
|
void
|
|
View_SetPos (view_t view, int x, int y)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_pos_t *pos = h->components[view_pos];
|
|
byte *modified = h->components[view_modified];
|
|
pos[ref->index] = (view_pos_t) { x, y };
|
|
modified[ref->index] |= 1;
|
|
}
|
|
|
|
VIEWINLINE
|
|
view_pos_t
|
|
View_GetPos (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_pos_t *pos = h->components[view_pos];
|
|
return pos[ref->index];
|
|
}
|
|
|
|
VIEWINLINE
|
|
view_pos_t
|
|
View_GetAbs (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_pos_t *abs = h->components[view_abs];
|
|
return abs[ref->index];
|
|
}
|
|
|
|
VIEWINLINE
|
|
view_pos_t
|
|
View_GetRel (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_pos_t *rel = h->components[view_rel];
|
|
return rel[ref->index];
|
|
}
|
|
|
|
VIEWINLINE
|
|
void
|
|
View_SetLen (view_t view, int x, int y)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_pos_t *len = h->components[view_len];
|
|
view_pos_t *oldlen = h->components[view_oldlen];
|
|
byte *modified = h->components[view_modified];
|
|
if (!(modified[ref->index] & 2)) {
|
|
oldlen[ref->index] = len[ref->index];
|
|
}
|
|
len[ref->index] = (view_pos_t) { x, y };
|
|
modified[ref->index] |= 2;
|
|
}
|
|
|
|
VIEWINLINE
|
|
view_pos_t
|
|
View_GetLen (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_pos_t *len = h->components[view_len];
|
|
return len[ref->index];
|
|
}
|
|
|
|
VIEWINLINE
|
|
void
|
|
View_SetGravity (view_t view, grav_t grav)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
viewcont_t *cont = h->components[view_control];
|
|
byte *modified = h->components[view_modified];
|
|
cont[ref->index].gravity = grav;
|
|
modified[ref->index] |= 1;
|
|
}
|
|
|
|
VIEWINLINE
|
|
grav_t
|
|
View_GetGravity (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
viewcont_t *cont = h->components[view_control];
|
|
return cont[ref->index].gravity;
|
|
}
|
|
|
|
VIEWINLINE
|
|
void
|
|
View_SetVisible (view_t view, int visible)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
viewcont_t *cont = h->components[view_control];
|
|
cont[ref->index].visible = !!visible;
|
|
}
|
|
|
|
VIEWINLINE
|
|
int
|
|
View_GetVisible (view_t view)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
viewcont_t *cont = h->components[view_control];
|
|
return cont[ref->index].visible;
|
|
}
|
|
|
|
VIEWINLINE
|
|
void
|
|
View_SetResize (view_t view, int resize_x, int resize_y)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
viewcont_t *cont = h->components[view_control];
|
|
cont[ref->index].resize_x = resize_x;
|
|
cont[ref->index].resize_y = resize_y;
|
|
}
|
|
|
|
VIEWINLINE
|
|
void
|
|
View_SetOnResize (view_t view, view_resize_f onresize)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_resize_f *resize = h->components[view_onresize];
|
|
resize[ref->index] = onresize;
|
|
}
|
|
|
|
VIEWINLINE
|
|
void
|
|
View_SetOnMove (view_t view, view_move_f onmove)
|
|
{
|
|
__auto_type ref = View_GetRef (view);
|
|
hierarchy_t *h = ref->hierarchy;
|
|
view_move_f *move = h->components[view_onmove];
|
|
move[ref->index] = onmove;
|
|
}
|
|
|
|
///@}
|
|
|
|
#endif//__QF_ui_view_h
|