widget_t *widgetCreate(int id, int type, int x, int y, int width, int height, unsigned int flags, flubGuiTheme_t *theme, widgetHandlers_t *handlers, layoutNode_t *layout, int dataSize) { widget_t *widget; widget = util_calloc(sizeof(widget_t) + dataSize, 0, NULL); widget->id = id; widget->type = type; widget->x = x; widget->y = y; widget->handlers = handlers; if((widget->handlers != NULL) && (widget->handlers->init != NULL)) { widget->handlers->init(widget); } widgetThemeApply(widget, theme); widgetAddToLayout(widget, layout); if((widget->handlers != NULL) && (widget->handlers->state != NULL)) { widget->handlers->state(widget, 1, flags); } widgetResize(widget, width, height); return widget; }
void widgetMove(widget_t *widget, int x, int y) { if(widget == NULL) { return; } widget->x = x; widget->y = y; widgetResize(widget, widget->width, width->height); }
void buttonInit(button *self, const char *id, int w, int h) { // Buttons need to be redrawn when the following events fire int i, handlers[] = { EVT_ENABLE, EVT_DISABLE, EVT_MOUSE_ENTER, EVT_MOUSE_LEAVE, EVT_MOUSE_DOWN, EVT_MOUSE_UP }; // Init our parent widgetInit((widget *)self, id); // Prepare our vtable buttonInitVtbl(self); // Set our type ((widget *)self)->classInfo = &buttonClassInfo; // initialise button state self->state = BUTTON_STATE_NORMAL; // Mask for exact mouse events widgetEnableMask(WIDGET(self)); // Install necessary event handlers for (i = 0; i < sizeof(handlers) / sizeof(int); i++) { widgetAddEventHandler(WIDGET(self), handlers[i], buttonSetButtonStateHandler, NULL, NULL); } buttonSetPatternsForState(self, BUTTON_STATE_NORMAL, "button/normal/fill", "button/normal/contour"); buttonSetPatternsForState(self, BUTTON_STATE_DISABLED, "button/disabled/fill", "button/disabled/contour"); buttonSetPatternsForState(self, BUTTON_STATE_MOUSEOVER, "button/mouseover/fill", "button/mouseover/contour"); buttonSetPatternsForState(self, BUTTON_STATE_MOUSEDOWN, "button/mousedown/fill", "button/mousedown/contour"); widgetResize(WIDGET(self), w, h); }
static bool timer(widget *self, const event *evt, int handlerId, void *userData) { widgetResize(self, self->size.x + 100, self->size.y + 100); }
bool tableDoLayoutImpl(widget *self) { table *selfTable = TABLE(self); const int numChildren = vectorSize(self->children); const int numRows = tableGetRowCount(selfTable); const int numColumns = tableGetColumnCount(selfTable); int i; int dx, dy; int *minColumnWidth = alloca(sizeof(int) * numColumns); int *maxColumnWidth = alloca(sizeof(int) * numColumns); int *minRowHeight = alloca(sizeof(int) * numRows); int *maxRowHeight = alloca(sizeof(int) * numRows); // Syntatic sugar int *columnWidth = minColumnWidth; int *rowHeight = minRowHeight; // Get the minimum and maximum cell sizes tableGetMinimumCellSizes(selfTable, minRowHeight, minColumnWidth); tableGetMaximumCellSizes(selfTable, maxRowHeight, maxColumnWidth); // Calculate how much space we have left to fill dx = self->size.x - tablePartialSum(minColumnWidth, 0, numColumns); dy = self->size.y - tablePartialSum(minRowHeight, 0, numRows); // Increase the column size until we run out of space for (i = 0; dx; i = (i + 1) % numColumns) { // If the column is not maxed out, increases its size by one if (columnWidth[i] < maxColumnWidth[i]) { columnWidth[i]++; dx--; } } // Increase the row size until we run out of space for (i = 0; dy; i = (i + 1) % numRows) { // If the row is not maxed out, increase its size by one if (rowHeight[i] < minRowHeight[i]) { rowHeight[i]++; dy--; } } // Now we need to position the children, taking padding into account for (i = 0; i < numChildren; i++) { // Get the child and its position info widget *child = vectorAt(self->children, i); const childPositionInfo *pos = vectorAt(selfTable->childPositions, i); size maxChildSize = widgetGetMaxSize(child); // left is the sum of all of the preceding columns int left = tablePartialSum(columnWidth, 0, pos->column); // top is the sum of all of the preceding rows int top = tablePartialSum(rowHeight, 0, pos->row); // cellWidth is the sum of the columns we span int cellWidth = tablePartialSum(columnWidth, pos->column - 1, pos->colspan); // cellHeight is the sum of the rows we span int cellHeight = tablePartialSum(rowHeight, pos->row - 1, pos->rowspan); // Final width and height of the child int w, h; // Final x,y offsets of the child int x, y; // If we are not the last row/column, subtract the row/column padding if (pos->column + pos->colspan - 1 != numColumns) { cellWidth -= selfTable->columnPadding; } if (pos->row + pos->rowspan - 1 != numRows) { cellHeight -= selfTable->rowPadding; } // Compute the final width and height of the child w = MIN(cellWidth, maxChildSize.x); h = MIN(cellHeight, maxChildSize.y); // Pad out any remaining space switch (pos->hAlignment) { case LEFT: x = left; break; case CENTRE: x = left + (cellWidth - w) / 2; break; case RIGHT: x = left + cellWidth - w; break; } switch (pos->vAlignment) { case TOP: y = top; break; case MIDDLE: y = top + (cellHeight - h) / 2; break; case BOTTOM: y = top + cellHeight - h; break; } // Resize and reposition the widget widgetResize(child, w, h); widgetReposition(child, x, y); } return true; }