Atrinik Client 2.5
toolkit/popup.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00041 #include <global.h>
00042 
00044 static popup_struct *popup_visible = NULL;
00045 
00049 static void popup_create_overlay(popup_struct *popup)
00050 {
00051     int j, k;
00052     uint8 r, g, b, a;
00053 
00054     /* Already exists? Free it. */
00055     if (popup->overlay)
00056     {
00057         SDL_FreeSurface(popup->overlay);
00058     }
00059 
00060     /* Create SDL surface with the same size as the ScreenSurface. */
00061     popup->overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenSurface->w, ScreenSurface->h, 32, 0, 0, 0, 0);
00062 
00063     /* Copy pixels from ScreenSurface. */
00064     for (k = 0; k < ScreenSurface->h; k++)
00065     {
00066         for (j = 0; j < ScreenSurface->w; j++)
00067         {
00068             SDL_GetRGBA(getpixel(ScreenSurface, j, k), ScreenSurface->format, &r, &g, &b, &a);
00069             /* Gray out the pixel. */
00070             r = g = b = (r + g + b) / 3;
00071             putpixel(popup->overlay, j, k, SDL_MapRGBA(popup->overlay->format, r, g, b, a));
00072         }
00073     }
00074 }
00075 
00079 static void popup_free(popup_struct *popup)
00080 {
00081     SDL_FreeSurface(popup->surface);
00082     SDL_FreeSurface(popup->overlay);
00083 
00084     if (popup->buf)
00085     {
00086         free(popup->buf);
00087     }
00088 
00089     free(popup);
00090 }
00091 
00096 popup_struct *popup_create(int bitmap_id)
00097 {
00098     popup_struct *popup = calloc(1, sizeof(popup_struct));
00099 
00100     /* Create the surface used by the popup. */
00101     popup->surface = SDL_ConvertSurface(Bitmaps[bitmap_id]->bitmap, Bitmaps[bitmap_id]->bitmap->format, Bitmaps[bitmap_id]->bitmap->flags);
00102     /* Store the bitmap used. */
00103     popup->bitmap_id = bitmap_id;
00104     /* Create overlay. */
00105     popup_create_overlay(popup);
00106     popup_visible = popup;
00107 
00108     return popup;
00109 }
00110 
00115 void popup_destroy_visible()
00116 {
00117     if (popup_visible)
00118     {
00119         if (popup_visible->destroy_callback_func && !popup_visible->destroy_callback_func(popup_visible))
00120         {
00121             return;
00122         }
00123 
00124         popup_free(popup_visible);
00125         popup_visible = NULL;
00126     }
00127 }
00128 
00133 int popup_overlay_need_update(popup_struct *popup)
00134 {
00135     return popup->overlay->w != ScreenSurface->w || popup->overlay->h != ScreenSurface->h;
00136 }
00137 
00140 void popup_draw()
00141 {
00142     SDL_Rect box;
00143     _BLTFX bltfx;
00144 
00145     /* No visible popup, nothing to do. */
00146     if (!popup_visible)
00147     {
00148         return;
00149     }
00150 
00151     /* Update the overlay if surface size was changed. */
00152     if (popup_overlay_need_update(popup_visible))
00153     {
00154         popup_create_overlay(popup_visible);
00155     }
00156 
00157     /* Draw the overlay. */
00158     box.x = 0;
00159     box.y = 0;
00160     SDL_BlitSurface(popup_visible->overlay, NULL, ScreenSurface, &box);
00161 
00162     /* Draw the background of the popup. */
00163     bltfx.surface = popup_visible->surface;
00164     bltfx.flags = 0;
00165     bltfx.alpha = 0;
00166     sprite_blt(Bitmaps[popup_visible->bitmap_id], 0, 0, NULL, &bltfx);
00167 
00168     /* Handle drawing inside the popup. */
00169     if (popup_visible->draw_func)
00170     {
00171         popup_visible->draw_func(popup_visible);
00172     }
00173 
00174     if (!popup_visible)
00175     {
00176         return;
00177     }
00178 
00179     /* Show the popup in the middle of the screen. */
00180     box.x = ScreenSurface->w / 2 - popup_visible->surface->w / 2;
00181     box.y = ScreenSurface->h / 2 - popup_visible->surface->h / 2;
00182     SDL_BlitSurface(popup_visible->surface, NULL, ScreenSurface, &box);
00183 
00184     popup_visible->x = box.x;
00185     popup_visible->y = box.y;
00186 
00187     if (popup_visible->draw_func_post)
00188     {
00189         popup_visible->draw_func_post(popup_visible);
00190     }
00191 
00192     if (!popup_visible)
00193     {
00194         return;
00195     }
00196 
00197     /* Show close button. */
00198     if (button_show(BITMAP_BUTTON_ROUND, -1, BITMAP_BUTTON_ROUND_DOWN, box.x + popup_visible->surface->w - Bitmaps[BITMAP_BUTTON_ROUND_DOWN]->bitmap->w - 10, box.y + 12, "X", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0))
00199     {
00200         popup_destroy_visible();
00201     }
00202 }
00203 
00208 int popup_handle_event(SDL_Event *event)
00209 {
00210     /* No popup is visible. */
00211     if (!popup_visible)
00212     {
00213         return 0;
00214     }
00215 
00216     /* Handle custom events? */
00217     if (popup_visible->event_func)
00218     {
00219         int ret = popup_visible->event_func(popup_visible, event);
00220 
00221         if (ret != -1)
00222         {
00223             return ret;
00224         }
00225     }
00226 
00227     /* Key is down. */
00228     if (event->type == SDL_KEYDOWN)
00229     {
00230         /* Escape, destroy the popup. */
00231         if (event->key.keysym.sym == SDLK_ESCAPE)
00232         {
00233             popup_destroy_visible();
00234         }
00235     }
00236 
00237     return 1;
00238 }
00239 
00243 popup_struct *popup_get_visible()
00244 {
00245     return popup_visible;
00246 }