[Tux4kids-commits] r1136 - tuxmath/trunk/src
Bolesław Kulbabiński
bolekk-guest at alioth.debian.org
Fri Jul 3 00:42:41 UTC 2009
Author: bolekk-guest
Date: 2009-07-03 00:42:41 +0000 (Fri, 03 Jul 2009)
New Revision: 1136
Modified:
tuxmath/trunk/src/SDL_extras.c
tuxmath/trunk/src/SDL_extras.h
tuxmath/trunk/src/menu.c
tuxmath/trunk/src/menu.h
tuxmath/trunk/src/titlescreen.c
Log:
added primitive menu rendering functions to test xml menus
Modified: tuxmath/trunk/src/SDL_extras.c
===================================================================
--- tuxmath/trunk/src/SDL_extras.c 2009-07-02 22:26:35 UTC (rev 1135)
+++ tuxmath/trunk/src/SDL_extras.c 2009-07-03 00:42:41 UTC (rev 1136)
@@ -25,23 +25,30 @@
int radius,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
+ SDL_Surface* tmp_surf = CreateButton(target_rect->w, target_rect->h,
+ radius, r, g, b, a);
+ SDL_BlitSurface(tmp_surf, NULL, screen, target_rect);
+ SDL_FreeSurface(tmp_surf);
+}
+
+SDL_Surface* CreateButton(int w, int h, int radius,
+ Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
/* NOTE - we use a 32-bit temp surface even if we have a 16-bit */
/* screen - it gets converted during blitting. */
SDL_Surface* tmp_surf = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
- target_rect->w,
- target_rect->h,
+ w,
+ h,
32,
rmask, gmask, bmask, amask);
+
Uint32 color = SDL_MapRGBA(tmp_surf->format, r, g, b, a);
SDL_FillRect(tmp_surf, NULL, color);
RoundCorners(tmp_surf, radius);
-
- SDL_BlitSurface(tmp_surf, NULL, screen, target_rect);
- SDL_FreeSurface(tmp_surf);
+ return tmp_surf;
}
-
void RoundCorners(SDL_Surface* s, Uint16 radius)
{
int y = 0;
Modified: tuxmath/trunk/src/SDL_extras.h
===================================================================
--- tuxmath/trunk/src/SDL_extras.h 2009-07-02 22:26:35 UTC (rev 1135)
+++ tuxmath/trunk/src/SDL_extras.h 2009-07-03 00:42:41 UTC (rev 1136)
@@ -30,6 +30,8 @@
/* Non-text graphics functions: */
void DrawButton(SDL_Rect* target_rect, int radius, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+SDL_Surface* CreateButton(int w, int h, int radius,
+ Uint8 r, Uint8 g, Uint8 b, Uint8 a);
void RoundCorners(SDL_Surface* s, Uint16 radius);
SDL_Surface* Flip(SDL_Surface *in, int x, int y);
int inRect(SDL_Rect r, int x, int y);
Modified: tuxmath/trunk/src/menu.c
===================================================================
--- tuxmath/trunk/src/menu.c 2009-07-02 22:26:35 UTC (rev 1135)
+++ tuxmath/trunk/src/menu.c 2009-07-03 00:42:41 UTC (rev 1136)
@@ -11,8 +11,11 @@
Copyright: See COPYING file that comes with this distribution.
*/
-#include "globals.h"
#include "menu.h"
+#include "SDL_extras.h"
+#include "titlescreen.h"
+#include "options.h"
+#include "fileops.h"
#include <stdio.h>
#include <stdlib.h>
@@ -43,16 +46,21 @@
MenuNode* load_menu_from_file(FILE* xml_file);
void free_menu(MenuNode* menu);
+SDL_Surface** render_buttons(MenuNode* menu, bool selected);
-/* creates new MenuNode struct with all field set to NULL (or 0) */
+
+
+/* creates new MenuNode struct with all fields set to NULL (or 0) */
MenuNode* create_empty_node()
{
MenuNode* new_node = malloc(sizeof(MenuNode));
new_node->title = NULL;
- new_node->sprite = NULL;
- new_node->choice = 0;
+ new_node->icon_name = NULL;
+ new_node->icon = NULL;
new_node->submenu_size = 0;
new_node->submenu = NULL;
+ new_node->activity = 0;
+ new_node->begin = 0;
return new_node;
}
@@ -81,12 +89,12 @@
else if(strcmp(attr_name, "entries") == 0)
node->submenu_size = atoi(attr_val);
else if(strcmp(attr_name, "sprite") == 0)
- node->sprite = strdup(attr_val);
+ node->icon_name = strdup(attr_val);
else if(strcmp(attr_name, "run") == 0)
{
for(i = 0; i < N_OF_ACTIVITIES; i++)
if(strcmp(attr_val, activities[i]) == 0)
- node->choice = i;
+ node->activity = i;
}
else
DEBUGMSG(debug_menu_parser, "read_attributes(): unknown attribute %s , omitting\n", attr_name);
@@ -154,8 +162,10 @@
{
if(menu->title != NULL)
free(menu->title);
- if(menu->sprite != NULL)
- free(menu->sprite);
+ if(menu->icon_name != NULL)
+ free(menu->icon_name);
+ if(menu->icon != NULL)
+ FreeSprite(menu->icon);
if(menu->submenu != NULL)
{
@@ -172,14 +182,206 @@
}
}
-/* display the menu
+
+
+/* Display the menu and run the event loop.
if return_choice = true then return chosen value instead of
running handle_choice() */
int run_menu(MenuNode* menu, bool return_choice)
{
-
+ SDL_Surface **menu_item_unselected = NULL;
+ SDL_Surface **menu_item_selected = NULL;
+ SDL_Event event;
+ int redraw, i;
+ int stop = 0;
+ int items;
+
+ for(;;) /* one execution for one menu level */
+ {
+ /* render buttons for current menu page */
+ menu_item_unselected = render_buttons(menu, false);
+ menu_item_selected = render_buttons(menu, true);
+ items = min(menu->entries_per_page, menu->submenu_size - menu->begin);
+
+
+ redraw = 1; // force a full redraw on first pass
+ while (SDL_PollEvent(&event)); // clear pending events
+ while (!stop)
+ {
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_MOUSEMOTION:
+ {
+ for (i = menu->begin; i < menu->begin + items; i++)
+ {
+ if (inRect(menu->submenu[i]->button_rect, event.motion.x, event.motion.y))
+ {
+ // Play sound if loc is being changed:
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ playsound(SND_TOCK);
+ }
+ break; /* from for loop */
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if(redraw)
+ {
+ for(i = 0; i < menu->submenu_size; i++)
+ SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu->submenu[i]->button_rect);
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+ redraw = 0;
+ }
+ }
+ break;
+
+ /* free button surfaces */
+ for(i = 0; i < items; i++)
+ {
+ SDL_FreeSurface(menu_item_unselected[i]);
+ SDL_FreeSurface(menu_item_selected[i]);
+ }
+ free(menu_item_unselected);
+ free(menu_item_selected);
+ }
+
+ return -1;
}
+SDL_Surface** render_buttons(MenuNode* menu, bool selected)
+{
+ SDL_Surface** menu_items = NULL;
+ SDL_Rect curr_rect, tmp_rect;
+ SDL_Surface* tmp_surf = NULL;
+ int i;
+ int items = min(menu->entries_per_page, menu->submenu_size - menu->begin);
+
+ menu_items = (SDL_Surface**) malloc(items * sizeof(SDL_Surface*));
+ if(NULL == menu_items)
+ {
+ DEBUGMSG(debug_menu, "render_buttons(): failed to allocate memory for buttons!");
+ return NULL; // error
+ }
+
+ for (i = 0; i < items; i++)
+ {
+ curr_rect = menu->submenu[menu->begin + i]->button_rect;
+ menu_items[i] = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
+ curr_rect.w,
+ curr_rect.h,
+ 32,
+ rmask, gmask, bmask, amask);
+
+ SDL_BlitSurface(screen, &curr_rect, menu_items[i], NULL);
+ /* button */
+ if(selected)
+ tmp_surf = CreateButton(curr_rect.w, curr_rect.h, 10, SEL_RGBA);
+ else
+ tmp_surf = CreateButton(curr_rect.w, curr_rect.h, 10, REG_RGBA);
+
+ SDL_BlitSurface(tmp_surf, NULL, menu_items[i], NULL);
+ SDL_FreeSurface(tmp_surf);
+
+ /* text */
+ tmp_surf = BlackOutline(_(menu->submenu[menu->begin + i]->title),
+ DEFAULT_MENU_FONT_SIZE, selected ? &yellow : &white);
+ tmp_rect = tmp_surf->clip_rect;
+ tmp_rect.x = curr_rect.h * 2;
+ tmp_rect.y = (curr_rect.h - tmp_surf->h) / 2;
+ SDL_BlitSurface(tmp_surf, NULL, menu_items[i], &tmp_rect);
+ SDL_FreeSurface(tmp_surf);
+
+ /* icon */
+ if(menu->submenu[menu->begin + i]->icon)
+ {
+ tmp_rect = menu->submenu[menu->begin + i]->icon->default_img->clip_rect;
+ tmp_rect.x = 0;
+ tmp_rect.y = 0;
+ SDL_BlitSurface(menu->submenu[menu->begin + i]->icon->default_img, NULL, menu_items[i], &tmp_rect);
+ }
+ }
+
+ return menu_items;
+}
+
+/* recursively load sprites and calculate button rects
+ to fit into current screen */
+void render_menu(MenuNode* menu)
+{
+ SDL_Rect menu_rect;
+ SDL_Surface* temp_surf;
+ MenuNode* curr_node;
+ int i, max_text_h = 0, max_text_w = 0;
+ int button_h, button_w;
+ float gap;
+ char filename[buf_size];
+
+ if(NULL == menu)
+ {
+ DEBUGMSG(debug_menu, "render_menu(): NULL pointer, exiting !");
+ return;
+ }
+
+ if(0 == menu->submenu_size)
+ {
+ DEBUGMSG(debug_menu, "render_menu(): no submenu, exiting.");
+ return;
+ }
+
+ menu_rect.x = 0.3 * screen->w;
+ menu_rect.y = 0.25 * screen->h;
+ menu_rect.w = 0.65 * screen->w;
+ menu_rect.h = 0.75 * screen->h;
+
+ for(i = 0; i < menu->submenu_size; i++)
+ {
+ temp_surf = NULL;
+ temp_surf = SimpleText(menu->submenu[i]->title, DEFAULT_MENU_FONT_SIZE, &black);
+ if(temp_surf)
+ {
+ max_text_h = max(max_text_h, temp_surf->h);
+ max_text_w = max(max_text_w, temp_surf->w);
+ SDL_FreeSurface(temp_surf);
+ }
+ }
+
+ button_h = 2 * max_text_h;
+ button_w = max_text_w + 3 * max_text_h;
+
+ gap = 0.2;
+ menu->entries_per_page = (int) ( (menu_rect.h - gap * button_h) / (1.0 + gap) );
+
+ for(i = 0; i < menu->submenu_size; i++)
+ {
+ curr_node = menu->submenu[i];
+ curr_node->button_rect.x = menu_rect.x;
+ curr_node->button_rect.y = menu_rect.y + i * button_h + (i + 1) * gap * button_h;
+ curr_node->button_rect.w = button_w;
+ curr_node->button_rect.h = button_h;
+ curr_node->font_size = DEFAULT_MENU_FONT_SIZE;
+
+ if(curr_node->icon)
+ FreeSprite(curr_node->icon);
+
+ if(curr_node->icon_name)
+ {
+ sprintf(filename, "sprites/%s", curr_node->icon_name);
+ DEBUGMSG(debug_menu, "render_menu(): loading sprite %s for item #%d.\n", filename, i);
+ curr_node->icon = LoadSpriteOfBoundingBox(filename, IMG_ALPHA, button_h, button_h);
+ }
+ else
+ DEBUGMSG(debug_menu, "render_menu(): no sprite for item #%d.\n", i);
+ }
+
+}
+
/* load menu trees from disk */
void LoadMenus(void)
{
@@ -213,22 +415,18 @@
0 indicates that a choice has been made. */
int RunLoginMenu(void)
{
-
+ return 0;
}
-/* run main menu. If this function ends it means that tuxmath is going to quit */
+/* run main menu. If this function ends it means that tuxmath is going to quit */
void RunMainMenu(void)
{
+ DEBUGMSG(debug_menu, "Entering RunMainMenu()\n");
+ render_menu(menus[MENU_MAIN]);
run_menu(menus[MENU_MAIN], false);
+ DEBUGMSG(debug_menu, "Leaving RunMainMenu()\n");
}
-/* calculate proper sizes and positions of menu elements,
- load sprites */
-void RenderMenus(void)
-{
-
-}
-
/* free all loaded menu trees */
void UnloadMenus(void)
{
Modified: tuxmath/trunk/src/menu.h
===================================================================
--- tuxmath/trunk/src/menu.h 2009-07-02 22:26:35 UTC (rev 1135)
+++ tuxmath/trunk/src/menu.h 2009-07-03 00:42:41 UTC (rev 1136)
@@ -15,6 +15,10 @@
#ifndef MENU_H
#define MENU_H
+#include "SDL.h"
+#include "globals.h"
+#include "loaders.h"
+
/* these are all menu choices that are available in tuxmath.
By using a define we can create both an enum and
a string array without writing these names twice */
@@ -49,15 +53,27 @@
#undef X
struct mNode {
+ struct mNode* parent;
+
char* title;
- char* sprite;
+ int font_size;
+ char* icon_name;
+ sprite* icon;
+
+ SDL_Rect button_rect;
+
/* submenu_size = 0 if no submenu */
int submenu_size;
struct mNode** submenu;
- /* available only if submenu_size = 0 */
- int choice;
+ /* these fields are used only if submenu_size = 0 */
+ int activity;
+
+ /* these fields are used only if submenu_size > 0 */
+ bool display_title;
+ int entries_per_page;
+ int begin;
};
typedef struct mNode MenuNode;
@@ -66,7 +82,6 @@
void LoadMenus(void);
int RunLoginMenu(void);
void RunMainMenu(void);
-void RenderMenus(void);
void UnloadMenus(void);
#endif // MENU_H
Modified: tuxmath/trunk/src/titlescreen.c
===================================================================
--- tuxmath/trunk/src/titlescreen.c 2009-07-02 22:26:35 UTC (rev 1135)
+++ tuxmath/trunk/src/titlescreen.c 2009-07-03 00:42:41 UTC (rev 1136)
@@ -374,6 +374,7 @@
audioMusicLoad("tuxi.ogg", -1);
}
+ //RunMainMenu();
/* If necessary, have the user log in */
if (run_login_menu() != -1) {
/* Finish parsing user options */
More information about the Tux4kids-commits
mailing list