void tableDestroyImpl(widget *self) { // Destroy child positional info vectorMapAndDestroy(TABLE(self)->childPositions, free); // Call our parents destructor widgetDestroyImpl(self); }
void widgetSDLQuit() { // Get the window vector vector *windowVector = windowGetWindowVector(); // Release all active windows vectorMapAndDestroy(windowVector, (mapCallback) widgetDestroy); // Release any cached SVG images svgManagerQuit(); // Release all patterns patternManagerQuit(); }
void widgetDestroyImpl(widget *self) { eventTableEntry *currEntry; // Release the container vectorMapAndDestroy(self->children, (mapCallback) widgetDestroy); // Release the event handler table while ((currEntry = vectorHead(self->eventVtbl))) { widgetRemoveEventHandler(self, currEntry->id); } vectorDestroy(self->eventVtbl); // Destroy the cairo context cairo_destroy(self->cr); // Destroy the texture glDeleteTextures(1, &self->textureId); // If we use a mask, destroy it if (self->maskEnabled) { cairo_destroy(self->maskCr); } // If GL content support is enabled, disable it if (self->openGLEnabled) { widgetDisableGL(self); } // Free the ID free((char *) self->id); // Free the tool-tip (if any) free((char *) self->toolTip); // Free ourself free(self); }
static bool widgetAnimationTimerCallback(widget *self, const event *evt, int handlerId, void *userData) { int i; vector *frames = userData; animationFrame *currFrame; // Regular timer event if (evt->type == EVT_TIMER_PERSISTENT) { bool didInterpolate = false; // Currently active keyframes to be interpolated between struct { animationFrame *pre; animationFrame *post; } interpolateFrames[ANI_TYPE_COUNT] = { { NULL, NULL } }; // Work out what frames we need to interpolate between for (i = 0; i < vectorSize(frames); i++) { currFrame = vectorAt(frames, i); /* * We are only interested in the key frames which either directly * precede now or come directly after. (As it is these frames which * will be interpolated between.) */ if (currFrame->time <= evt->time) { interpolateFrames[currFrame->type].pre = currFrame; } else if (currFrame->time > evt->time && !interpolateFrames[currFrame->type].post) { interpolateFrames[currFrame->type].post = currFrame; } } // Do the interpolation for (i = 0; i < ANI_TYPE_COUNT; i++) { // If there are frames to interpolate between then do so if (interpolateFrames[i].pre && interpolateFrames[i].post) { // Get the points to interpolate between animationFrame k1 = *interpolateFrames[i].pre; animationFrame k2 = *interpolateFrames[i].post; int time = evt->time; switch (i) { case ANI_TYPE_TRANSLATE: { // Get the new position point pos = widgetAnimationInterpolateTranslate(self, k1, k2, time); // Set the new position widgetReposition(self, pos.x, pos.y); break; } case ANI_TYPE_ROTATE: // Update the widgets rotation self->rotate = widgetAnimationInterpolateRotate(self, k1, k2, time); break; case ANI_TYPE_SCALE: // Update the widgets scale factor self->scale = widgetAnimationInterpolateScale(self, k1, k2, time); break; case ANI_TYPE_ALPHA: // Update the widgets alpha self->alpha = widgetAnimationInterpolateAlpha(self, k1, k2, time); break; } // Make a note that we did interpolate didInterpolate = true; } } // If there was no interpolation then the animation is over if (!didInterpolate) { // Remove ourself (the event handler) widgetRemoveEventHandler(self, handlerId); } } else if (evt->type == EVT_DESTRUCT) { animationFrame *lastFrame[ANI_TYPE_COUNT] = { NULL }; // Find the last frame of each animation type for (i = 0; i < vectorSize(frames); i++) { currFrame = vectorAt(frames, i); lastFrame[currFrame->type] = currFrame; } // Set the position/rotation/scale/alpha to that of the final frame for (i = 0; i < ANI_TYPE_COUNT; i++) { if (lastFrame[i]) switch (i) { case ANI_TYPE_TRANSLATE: self->offset = lastFrame[ANI_TYPE_TRANSLATE]->data.translate; break; case ANI_TYPE_ROTATE: self->rotate = lastFrame[ANI_TYPE_ROTATE]->data.rotate; break; case ANI_TYPE_SCALE: self->scale = lastFrame[ANI_TYPE_SCALE]->data.scale; break; case ANI_TYPE_ALPHA: self->alpha = lastFrame[ANI_TYPE_ALPHA]->data.alpha; break; default: break; } } // Free the frames vector vectorMapAndDestroy(frames, free); } return true; }