/* * Copyright (c) 2007 Hypertriton, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "socket.h" #include "icon.h" #include "window.h" #include "primitive.h" #include AG_Icon * AG_IconNew(void *parent, Uint flags) { AG_Icon *icon; icon = Malloc(sizeof(AG_Icon)); AG_ObjectInit(icon, &agIconClass); icon->flags |= flags; AG_ObjectAttach(parent, icon); return (icon); } AG_Icon * AG_IconFromSurface(AG_Surface *su) { AG_Icon *icon; icon = Malloc(sizeof(AG_Icon)); AG_ObjectInit(icon, &agIconClass); AG_IconSetSurface(icon, su); return (icon); } AG_Icon * AG_IconFromBMP(const char *bmpfile) { AG_Icon *icon; AG_Surface *bmp; if ((bmp = AG_SurfaceFromBMP(bmpfile)) == NULL) { return (NULL); } icon = Malloc(sizeof(AG_Icon)); AG_ObjectInit(icon, &agIconClass); AG_IconSetSurfaceNODUP(icon, bmp); return (icon); } static void Init(void *obj) { AG_Icon *icon = obj; WIDGET(icon)->flags |= AG_WIDGET_FOCUSABLE; icon->flags = 0; icon->surface = -1; icon->wDND = NULL; icon->sock = NULL; icon->labelTxt[0] = '\0'; icon->labelSurface = -1; icon->labelPad = 4; icon->xSaved = -1; icon->ySaved = -1; icon->wSaved = -1; icon->hSaved = -1; icon->cBackground = 0; } static void SizeRequest(void *obj, AG_SizeReq *r) { AG_Icon *icon = obj; int wLbl, hLbl; if (icon->surface == -1) { r->w = 0; r->h = 0; } r->w = WSURFACE(icon,icon->surface)->w; r->h = WSURFACE(icon,icon->surface)->h; if (icon->labelTxt[0] != '\0') { if (icon->labelSurface != -1) { wLbl = WSURFACE(icon,icon->labelSurface)->w; hLbl = WSURFACE(icon,icon->labelSurface)->h; } else { AG_TextSize(icon->labelTxt, &wLbl, &hLbl); } r->h += icon->labelPad + hLbl; r->w = MAX(r->w, wLbl); } } static int SizeAllocate(void *obj, const AG_SizeAlloc *a) { if (a->w < 1 || a->h < 1) { return (-1); } return (0); } static void Draw(void *obj) { AG_Icon *icon = obj; int hIcon; if (icon->surface == -1) { return; } AG_WidgetBlitSurface(icon, icon->surface, WIDGET(icon)->w/2 - WSURFACE(icon,icon->surface)->w/2, 0); if (icon->labelTxt[0] != '\0') { if (icon->labelSurface != -1 && icon->flags & AG_ICON_REGEN_LABEL) { AG_WidgetUnmapSurface(icon, icon->labelSurface); icon->labelSurface = -1; } if (icon->labelSurface == -1) { AG_PushTextState(); icon->labelSurface = AG_WidgetMapSurface(icon, AG_TextRender(icon->labelTxt)); AG_PopTextState(); } hIcon = WSURFACE(icon,icon->surface)->h; if (icon->flags & AG_ICON_BGFILL) { AG_DrawRectFilled(icon, AG_RECT(0, hIcon, WIDTH(icon), HEIGHT(icon)-hIcon), icon->cBackground); } AG_WidgetBlitSurface(icon, icon->labelSurface, WIDTH(icon)/2 - WSURFACE(icon,icon->labelSurface)->w/2, WSURFACE(icon,icon->surface)->h + icon->labelPad); } } void AG_IconSetBackgroundFill(AG_Icon *icon, int enable, Uint32 color) { AG_SETFLAGS(icon->flags, AG_ICON_BGFILL, enable); icon->cBackground = color; } void AG_IconSetSurface(AG_Icon *icon, AG_Surface *su) { AG_Surface *suDup = (su != NULL) ? AG_DupSurface(su) : NULL; AG_ObjectLock(icon); if (icon->surface != -1) { AG_WidgetReplaceSurface(icon, icon->surface, suDup); } else { icon->surface = AG_WidgetMapSurface(icon, suDup); } AG_ObjectUnlock(icon); } void AG_IconSetSurfaceNODUP(AG_Icon *icon, AG_Surface *su) { AG_ObjectLock(icon); if (icon->surface != -1) { AG_WidgetReplaceSurface(icon, icon->surface, su); } else { icon->surface = AG_WidgetMapSurface(icon, su); } AG_ObjectUnlock(icon); } void AG_IconSetText(AG_Icon *icon, const char *fmt, ...) { va_list ap; AG_ObjectLock(icon); if (fmt == NULL || fmt[0] == '\0') { AG_WidgetUnmapSurface(icon, icon->labelSurface); icon->labelSurface = -1; icon->labelTxt[0] = '\0'; } else { va_start(ap, fmt); Vsnprintf(icon->labelTxt, sizeof(icon->labelTxt), fmt, ap); va_end(ap); icon->flags |= AG_ICON_REGEN_LABEL; } AG_ObjectUnlock(icon); } AG_WidgetClass agIconClass = { { "Agar(Widget:Icon)", sizeof(AG_Icon), { 0,0 }, Init, NULL, /* free */ NULL, /* destroy */ NULL, /* load */ NULL, /* save */ NULL /* edit */ }, Draw, SizeRequest, SizeAllocate };