void widgetResizeImpl(widget *self, int w, int h) { const size minSize = widgetGetMinSize(self); const size maxSize = widgetGetMaxSize(self); // Create an event eventResize evtResize; evtResize.event = widgetCreateEvent(EVT_RESIZE); // Save the current size in the event evtResize.oldSize = self->size; assert(minSize.x <= w); assert(minSize.y <= h); assert(w <= maxSize.x); assert(h <= maxSize.y); self->size.x = w; self->size.y = h; // Re-create the cairo context at this new size widgetCairoCreate(&self->cr, CAIRO_FORMAT_ARGB32, w, h); // If a mask is enabled; re-create it also if (self->maskEnabled) { widgetCairoCreate(&self->maskCr, CAIRO_FORMAT_A1, w, h); // Re-draw the mask (only done on resize) widgetDrawMask(self); } // If OpenGL is enabled disable and re-enable it if (self->openGLEnabled) { widgetDisableGL(self); widgetEnableGL(self); } // Set the needs redraw flag self->needsRedraw = true; // If we have any children, we need to redo their layout if (vectorSize(self->children)) { widgetDoLayout(self); } // Fire any EVT_RESIZE callbacks widgetFireCallbacks(self, (event *) &evtResize); }
/** * Computes the minimum row/column size for each row/column in the table. It is * important to note that the widths/heights are inclusive of padding. Therefore * all but the rightmost column and bottom row will have either self->rowPadding * or self->columnPadding added onto their sizes. * * @param self The table to get the minimum cell sizes of. * @param minRowHeight The array to place the minimum row heights for the table * into; assumed to be tableGetRowCount(self) in size. * @param minColumnWidth The array to place the minimum column widths for the * table into; assumed to be tableGetColumnCount(self) * in size. */ static void tableGetMinimumCellSizes(const table *self, int *minRowHeight, int *minColumnWidth) { int i; int spanningIndex; const int numChildren = vectorSize(WIDGET(self)->children); const int numRows = tableGetRowCount(self); const int numColumns = tableGetColumnCount(self); size *minChildSize = alloca(sizeof(size) * numChildren); // Zero the min row/column sizes memset(minRowHeight, '\0', sizeof(int) * numRows); memset(minColumnWidth, '\0', sizeof(int) * numColumns); // Get the minimum row/column sizes for single-spanning cells for (i = 0; i < numChildren; i++) { const childPositionInfo *pos = vectorAt(self->childPositions, i); const int row = pos->row - 1; const int col = pos->column - 1; // Get the minmum size of the cell minChildSize[i] = widgetGetMinSize(vectorAt(WIDGET(self)->children, i)); // Take cell padding into account where appropriate if (pos->column < numColumns) { minChildSize[i].x += self->columnPadding; } if (pos->row < numRows) { minChildSize[i].y += self->rowPadding; } // If the row has a rowspan of 1; see if it is the highest thus far if (pos->rowspan == 1) { minRowHeight[row] = MAX(minRowHeight[row], minChildSize[i].y); } // If the column has a colspan of 1; see if it is the widest thus far if (pos->colspan == 1) { minColumnWidth[col] = MAX(minColumnWidth[col], minChildSize[i].x); } } // Handle spanning rows while ((spanningIndex = tableGetMostOversizedRow(self, minRowHeight, minChildSize)) != -1) { int i; const childPositionInfo *pos = vectorAt(self->childPositions, spanningIndex); // Calculate how much larger we need to make the spanned rows int delta = minChildSize[spanningIndex].y - tablePartialSum(minRowHeight, pos->row - 1, pos->rowspan); // Loop over the rows spanned increasing their height by 1 for (i = pos->row; delta; i = pos->row + (i + 1) % pos->rowspan, delta--) { minRowHeight[i]++; } } // Handle spanning columns while ((spanningIndex = tableGetMostOversizedColumn(self, minColumnWidth, minChildSize)) != -1) { int i; const childPositionInfo *pos = vectorAt(self->childPositions, spanningIndex); // Calculate how much larger we need to make the spanned columns int delta = minChildSize[spanningIndex].x - tablePartialSum(minColumnWidth, pos->column - 1, pos->colspan); for (i = pos->column; delta; i = pos->column + (i + 1) % pos->colspan, delta--) { minColumnWidth[i]++; } } }