bool tableAddChildWithSpanAlign(table *self, widget *child, int row, int rowspan, vAlign v, int column, int colspan, hAlign h) { int i, j; const int rowCount = tableGetRowCount(self); const int columnCount = tableGetColumnCount(self); childPositionInfo *pos; // First, check the row and column is valid assert(row > 0 && row <= tableGetRowCount(self) + 1); assert(column > 0 && column <= tableGetColumnCount(self) + 1); // Second, check all of the cells spanned are empty for (i = row; i < row + rowspan && i <= rowCount; i++) { for (j = column; j < column + colspan && j <= columnCount; j++) { assert(tableGetCell(self, i, j) == NULL); } } // Update the row and column counts self->numRows = MAX(rowCount, row + rowspan - 1); self->numColumns = MAX(columnCount, column + colspan - 1); // Add positional information regarding the child to our list pos = malloc(sizeof(childPositionInfo)); pos->row = row; pos->rowspan = rowspan; pos->column = column; pos->colspan = colspan; pos->vAlignment = v; pos->hAlignment = h; vectorAdd(self->childPositions, pos); // Call widgetAddChildImpl, which will add the child and re-do the layout if (widgetAddChildImpl(WIDGET(self), child)) { return true; } // Problem adding the child; positional information needs to be restored else { vectorRemoveAt(self->childPositions, vectorSize(self->childPositions) - 1); // Release the memory we malloc'ed earlier free(pos); // Restore the row and column counts self->numRows = rowCount; self->numColumns = columnCount; return false; } }
void widgetRemoveChildImpl(widget *self, widget *child) { int i; for (i = 0; i < vectorSize(self->children); i++) { // If the child is the to-be-removed widget, remove it if (vectorAt(self->children, i) == child) { // Call the destructor for the widget widgetDestroy(vectorAt(self->children, i)); // Remove it from the list of children vectorRemoveAt(self->children, i); // Re-layout the window (so long as we are part of one) if (self->size.x != -1.0f && self->size.y != -1.0f) { widgetDoLayout(widgetGetRoot(self)); } } // See if it is one of its children else if (child->parent != self) { widgetRemoveChild(vectorAt(self->children, i), child); } } }
void widgetRemoveEventHandlerImpl(widget *self, int id) { int i; // Search for the handler with the id for (i = 0; i < vectorSize(self->eventVtbl); i++) { eventTableEntry *handler = vectorAt(self->eventVtbl, i); // If the handler matches, remove it if (handler->id == id) { // If there is a destructor; call it if (handler->destructor) { // Generate an EVT_DESTRUCT event eventMisc evtDestruct; evtDestruct.event = widgetCreateEvent(EVT_DESTRUCT); handler->destructor(self, (event *) &evtDestruct, handler->id, handler->userData); } // Release the handler free(handler); // Finally, remove the event handler from the table vectorRemoveAt(self->eventVtbl, i); break; } } }
bool widgetAddChildImpl(widget *self, widget *child) { // Make sure the id of the child is unquie assert(widgetFindById(widgetGetRoot(self), child->id) == NULL); // Make sure the child does not currently have a parent assert(child->parent == NULL); // Add the widget vectorAdd(self->children, child); // So long as our size is not (-1,-1) (NULL-size), re-layout the window if ((self->size.x == -1.0f && self->size.y == -1.0f) || widgetDoLayout(widgetGetRoot(self))) { // Set ourself as its parent child->parent = self; return true; } // Not enough space to fit the widget (widgetDoLayout returned false) else { // Remove child *without* calling its destructor vectorRemoveAt(self->children, vectorSize(self->children) - 1); // Restore the layout widgetDoLayout(widgetGetRoot(self)); return false; } }
void tableRemoveChildImpl(widget *self, widget *child) { // If we are not the childs parent, delegate to widgetRemoveChildImpl if (self != child->parent) { widgetRemoveChildImpl(self, child); } // We are the childs parent, so there is some bookkeeping to tend to else { int i; // Find the index of the child for (i = 0; i < vectorSize(self->children); i++) { if (child == vectorAt(self->children, i)) { break; } } // Call the child's destructor and remove it widgetDestroy(vectorAt(self->children, i)); vectorRemoveAt(self->children, i); // Remove the childs positional information free(vectorAt(TABLE(self)->childPositions, i)); vectorRemoveAt(TABLE(self)->childPositions, i); // Remove any empty rows/columns tableRemoveEmptyRows(TABLE(self)); tableRemoveEmptyColumns(TABLE(self)); // Redo the layout of the window if (self->size.x != -1 && self->size.y != -1) { widgetDoLayout(widgetGetRoot(self)); } } }