155 lines
3.1 KiB
C
155 lines
3.1 KiB
C
|
#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;
|
||
|
}
|