Add textEntry class (warning: unfinished) to betawidget.

git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@5920 4a71c877-e1ca-e34f-864e-861f7616d084
master
Freddie Witherden 2008-09-02 17:53:34 +00:00
parent a31fbb4561
commit 7453cee5bb
2 changed files with 286 additions and 0 deletions

154
lib/betawidget/textEntry.c Normal file
View File

@ -0,0 +1,154 @@
#include <string.h>
#include "textEntry.h"
static textEntryVtbl vtbl;
// Default size of the text buffer
static const int defautSize = 128;
const classInfo textEntryClassInfo =
{
&widgetClassInfo,
"textEntry"
};
textEntry *textEntryCreate(const char *id)
{
textEntry *instance = malloc(sizeof(textEntry));
if (instance == NULL)
{
return NULL;
}
// Call the constructor
textEntryInit(instance, id);
// Return the new object
return instance;
}
static void textEntryInitVtbl(textEntry *self)
{
static bool initialised = false;
if (!initialised)
{
// Copy our parents vtable into ours
vtbl.widgetVtbl = *(WIDGET(self)->vtbl);
// Overload the destroy method
vtbl.widgetVtbl.destroy = textEntryDestroyImpl;
// Draw method
vtbl.widgetVtbl.doDraw = textEntryDoDrawImpl;
initialised = true;
}
// Replace our parents vtable with our own
WIDGET(self)->vtbl = &vtbl.widgetVtbl;
// Set our vtable
self->vtbl = &vtbl;
}
void textEntryInit(textEntry *self, const char *id)
{
// Init our parent
widgetInit(WIDGET(self), id);
// Prepare our vtable
textEntryInitVtbl(self);
// Set our type
WIDGET(self)->classInfo = &textEntryClassInfo;
// Allocate a modestly sized text buffer
self->text = calloc(defautSize, 1);
self->textSize = defautSize;
// On account of there being no text, all of these are 0
self->textHead = 0;
self->insertPosition = 0;
self->renderLeftOffset = 0;
}
void textEntryDestroyImpl(widget *self)
{
// Free the text buffer
free(TEXT_ENTRY(self)->text);
// Call our parents destructor
widgetDestroyImpl(self);
}
void textEntryDoDrawImpl(widget *self)
{
// Draw our frame
textEntryDoDrawFrame(TEXT_ENTRY(self));
textEntryDoDrawText(TEXT_ENTRY(self));
}
void textEntryDoDrawFrame(textEntry *self)
{
cairo_t *cr = WIDGET(self)->cr;
// Lets keep it simple
cairo_rectangle(cr, 0, 0, WIDGET(self)->size.x, WIDGET(self)->size.y);
cairo_set_source_rgba(cr, 0.0, 1.0, 1.0, 0.4);
cairo_fill_preserve(cr);
// Black stroke
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_set_line_width(cr, 2);
cairo_stroke(cr);
}
void textEntryDoDrawText(textEntry *self)
{
cairo_t *cr = WIDGET(self)->cr;
// Set the render left offset
cairo_translate(cr, -self->renderLeftOffset, 0);
// Draw the text
cairo_move_to(cr, 0, WIDGET(self)->size.y);
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 25);
cairo_show_text(cr, self->text);
// Restore the offset
cairo_translate(cr, self->renderLeftOffset, 0);
}
const char *textEntryGetContents(textEntry *self)
{
return self->text;
}
bool textEntrySetContents(textEntry *self, const char *contents)
{
// Free the current contents
free(self->text);
// Copy the new contents
self->text = strdup(contents);
// TODO: Check for NULL and return false
// Update the size information
self->textHead = self->textSize = strlen(contents);
// Place the caret at the start of the string
self->insertPosition = 0;
// Since the insert position is the far left, the render offset is 0
self->renderLeftOffset = 0;
return true;
}

132
lib/betawidget/textEntry.h Normal file
View File

@ -0,0 +1,132 @@
#ifndef TEXTENTRY_H_
#define TEXTENTRY_H_
#include "widget.h"
/*
* Forward declarations
*/
typedef struct _textEntry textEntry;
typedef struct _textEntryVtbl textEntryVtbl;
struct _textEntryVtbl
{
widgetVtbl widgetVtbl;
};
struct _textEntry
{
/*
* Parent
*/
widget widget;
/*
* Our vtable
*/
textEntryVtbl *vtbl;
/*
* The character buffer (contents), UTF-8 encoded
*/
char *text;
/*
* The size of text (how much space was allocated), not including the '\0'
* byte
*/
size_t textSize;
/*
* The actual length of the string (how much space is used); since text is
* encoded in UTF-8 this is *not* the character count
*/
size_t textHead;
/*
* The current insert position (where in the byte-stream characters should
* be inserted to); again this has no relation to the character count
*/
int insertPosition;
/*
* The offet of the leftmost pixel that is to be rendered:
* |*-------------------|
* "The rain in S|pain falls mainly on|the..."
* |--------------------|
*
* The * shows the location represented by this value
*/
int renderLeftOffset;
};
/*
* Type information
*/
extern const classInfo textEntryClassInfo;
/*
* Helper macros
*/
#define TEXT_ENTRY(self) (assert(widgetIsA(WIDGET(self), &textEntryClassInfo)), \
(textEntry *) (self))
/*
* Protected methods
*/
void textEntryInit(textEntry *self, const char *id);
void textEntryDestroyImpl(widget *self);
void textEntryDoDrawImpl(widget *self);
size textEntryGetMinSizeImpl(widget *self);
size textEntryGetMaxSizeImpl(widget *self);
/*
* Public methods
*/
/**
* Constructs a new textEntry object and returns it.
*
* @param id The id of the widget.
* @return A pointer to an textEntry on success; otherwise NULL.
*/
textEntry *textEntryCreate(const char *id);
/**
* Fetches the contents of the text entry field, returning a copy of them. It is
* important to note that the returned string remains the responsibility of the
* user and must be free'ed when no longer required.
*
* @param self The text entry field to get the contents of.
* @return A pointer to a freshly allocated copy of the contents on success;
* otherwise NULL.
*/
const char *textEntryGetContents(textEntry *self);
/**
* Sets the contents of the entry field to a copy of the contents of contents.
*
* @param self The text entry to set the contents of.
* @param contents The string to set the contents to. This should be UTF-8
* encoded and NULL terminated.
* @return true if the contents were successfully set; otherwise false.
*/
bool textEntrySetContents(textEntry *self, const char *contents);
/*
* Protected methods
*/
/**
* Called by widgetDoDraw to draw the frame of the text entry field. The frame
* consists of the background and border of the entry field. This method will be
* called before the text and caret are rendered.
*
* @param self The text entry to draw the frame of.
*/
void textEntryDoDrawFrame(textEntry *self);
void textEntryDoDrawText(textEntry *self);
#endif /*TEXTENTRY_H_*/