Add some layout support code to the new widget system and clean-up some code in it.

git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@4944 4a71c877-e1ca-e34f-864e-861f7616d084
master
Freddie Witherden 2008-05-06 16:34:34 +00:00
parent b58d508ce6
commit 073a0e5d55
3 changed files with 162 additions and 15 deletions

View File

@ -102,4 +102,3 @@ int vectorSize(vector *v)
{
return v->head;
}

View File

@ -34,6 +34,13 @@ static void widgetInitVtbl(widget *self)
vtbl.enable = widgetEnableImpl;
vtbl.disable = widgetDisableImpl;
vtbl.getMinSize = widgetGetMinSizeImpl;
vtbl.getMaxSize = widgetGetMaxSizeImpl;
vtbl.setAlign = widgetSetAlignImpl;
vtbl.doLayout = NULL;
vtbl.doDraw = NULL;
vtbl.destroy = widgetDestroyImpl;
@ -108,7 +115,7 @@ static void widgetDrawChildren(widget *self, cairo_t *cr)
// Draw our children
for (i = 0; i < vectorSize(self->children); i++)
{
widget *child = WIDGET(vectorAt(self->children, i));
widget *child = vectorAt(self->children, i);
cairo_matrix_t current;
// Translate such that (0,0) is the location of the widget
@ -200,12 +207,25 @@ bool widgetAddChildImpl(widget *self, widget *child)
// Add the widget
vectorAdd(self->children, child);
// FIXME: We need to do some arbitration
// Set ourself as its parent
child->parent = self;
return true;
// Re-layout ourself
if (widgetDoLayout(self))
{
// Set ourself as its parent
child->parent = self;
return true;
}
// Not enough space to fit the widget
else
{
// Remove child
widgetRemoveChild(self, child);
// Restore the layout
widgetDoLayout(self);
return false;
}
}
/*
@ -294,7 +314,7 @@ void widgetEnableImpl(widget *self)
// Enable all of our children
for (i = 0; i < vectorSize(self->children); i++)
{
widgetEnable(WIDGET(vectorAt(self->children, i)));
widgetEnable(vectorAt(self->children, i));
}
}
@ -380,6 +400,26 @@ void widgetBlurImpl(widget *self)
widgetFireCallbacks(self, &evt);
}
point widgetGetMinSizeImpl(widget *self)
{
return self->minSize;
}
point widgetGetMaxSizeImpl(widget *self)
{
return self->maxSize;
}
void widgetSetAlignImpl(widget *self, vAlign v, hAlign h)
{
self->vAlignment = v;
self->hAlignment = h;
// Re-align our children
// TODO: We should check the return value here
widgetDoLayout(self);
}
widget *widgetGetCurrentlyFocused(widget *self)
{
int i;
@ -495,11 +535,35 @@ void widgetBlur(widget *self)
WIDGET_GET_VTBL(self)->blur(self);
}
point widgetGetMinSize(widget *self)
{
return WIDGET_GET_VTBL(self)->getMinSize(self);
}
point widgetGetMaxSize(widget *self)
{
return WIDGET_GET_VTBL(self)->getMaxSize(self);
}
void widgetSetAlign(widget *self, vAlign v, hAlign h)
{
WIDGET_GET_VTBL(self)->setAlign(self, v, h);
}
void widgetDoDraw(widget *self, cairo_t *cr)
{
WIDGET_CHECK_METHOD(self, doDraw);
WIDGET_GET_VTBL(self)->doDraw(self, cr);
}
bool widgetDoLayout(widget *self)
{
WIDGET_CHECK_METHOD(self, doLayout);
return WIDGET_GET_VTBL(self)->doLayout(self);
}
bool widgetHandleEvent(widget *self, event *evt)
{
return WIDGET_GET_VTBL(self)->handleEvent(self, evt);

View File

@ -1,6 +1,9 @@
#ifndef WIDGET_H_
#define WIDGET_H_
// TODO: Make this cross platform (MSVC)
#include <stdint.h>
#include <cairo.h>
#include "vector.h"
@ -25,6 +28,9 @@ typedef bool (*callback) (widget *widget, event *evt, void *userData);
typedef struct _eventTableEntry eventTableEntry;
typedef enum _hAlign hAlign;
typedef enum _vAlign vAlign;
/*
* The valid event types
*/
@ -140,7 +146,27 @@ struct _eventTableEntry
};
/*
* The widget classes virtual method table.
* The possible horizontal sides a child can be aligned to
*/
enum _hAlign
{
LEFT,
CENTRE,
RIGHT
};
/*
* The possible vertical sides a child can be aligned to
*/
enum _vAlign
{
TOP,
MIDDLE,
BOTTOM
};
/*
* The widget classes virtual method table
*/
struct _widgetVtbl
{
@ -160,7 +186,13 @@ struct _widgetVtbl
void (*enable) (widget *self);
void (*disable) (widget *self);
point (*getMinSize) (widget *self);
point (*getMaxSize) (widget *self);
void (*setAlign) (widget *self, vAlign v, hAlign h);
void (*doDraw) (widget *self, cairo_t *cr);
bool (*doLayout) (widget *self);
void (*destroy) (widget *self);
};
@ -190,6 +222,22 @@ struct _widget
*/
widget *parent;
/*
* The minimum size the widget can be
*/
point minSize;
/*
* The maximum size the widget can be
*/
point maxSize;
/*
* Child alignment
*/
vAlign vAlignment;
hAlign hAlignment;
//--------------------------------------
// Public members
//--------------------------------------
@ -203,7 +251,7 @@ struct _widget
* Arbitary user-defined data
*/
void *pUserData;
int userData;
int32_t userData;
/*
* The offset of the widget relative to its parent
@ -236,6 +284,7 @@ struct _widget
*/
#define WIDGET(self) ((widget *) (self))
#define WIDGET_GET_VTBL(self) ((WIDGET(self))->vtbl)
#define WIDGET_CHECK_METHOD(self, method) (assert(WIDGET_GET_VTBL(self)->method))
/*
* Protected methods
@ -252,6 +301,10 @@ void widgetEnableImpl(widget *self);
void widgetDisableImpl(widget *self);
void widgetFocusImpl(widget *self);
void widgetBlurImpl(widget *self);
point widgetGetMinSizeImpl(widget *self);
point widgetGetMaxSizeImpl(widget *self);
void widgetSetAlignImpl(widget *self, vAlign v, hAlign h);
void widgetDoAlignImpl(widget *self);
bool widgetHandleEventImpl(widget *instance, event *evt);
@ -297,8 +350,8 @@ widget *windgetGetRoot(widget *self);
/**
* Attempts to add child as a child widget of self. The exact location of the
* widget (as well as its dimensions) are decided during an arbitration process
* between the self and the child.
* widget (as well as its dimensions) are decided based off of the min & max
* sizes of the child.
*
* @param self The widget to add the child widget to.
* @param child The widget to be added.
@ -399,7 +452,7 @@ widget *widgetGetCurrentlyFocused(widget *self);
void widgetFocus(widget *self);
/**
c * Blurs the current widget (removes keyboard focus from it). Before self is
* Blurs the current widget (removes keyboard focus from it). Before self is
* blurred any child widget with focus is blurred first. Finally the EVT_BLUR
* event handlers for self are fired.
*
@ -407,6 +460,33 @@ c * Blurs the current widget (removes keyboard focus from it). Before self is
*/
void widgetBlur(widget *self);
/**
* Returns the minimum size that the widget can be.
*
* @param self The widget to return the miniumum size of.
* @return The miniumum (x,y) size of the widget.
*/
point widgetGetMinSize(widget *self);
/**
* Returns the maxiumum size that the widget can be. A value of -1 for either
* the x or y co-ordinate means that there is no maximum size.
*
* @param self The widget to return the maximum size of.
* @return The maximum (x,y) size of the widget.
*/
point widgetGetMaxSize(widget *self);
/**
* Sets the alignment of child widgets of self. This is used when the maximum
* size of the child widgets is less than that of the size of self.
*
* @param self The widget to set the alignment of.
* @param v The vertical alignment of the widget (TOP, MIDDLE, BOTTOM).
* @param h The horizontal alignment of the widget (LEFT, CENTRE, RIGHT).
*/
void widgetSetAlign(widget *self, vAlign v, hAlign h);
/**
* TODO
*/
@ -426,6 +506,11 @@ bool widgetHandleEvent(widget *self, event *evt);
*/
void widgetDoDraw(widget *self, cairo_t *cr);
/**
*
*/
bool widgetDoLayout(widget *self);
/**
* Fires all of the event handlers registered for evt->type on the widger self.
*
@ -435,4 +520,3 @@ void widgetDoDraw(widget *self, cairo_t *cr);
bool widgetFireCallbacks(widget *self, event *evt);
#endif /*WIDGET_H_*/