2013-07-01 12:48:03 +02:00

368 lines
7.0 KiB
C

#include "SDL.h"
#include <stdio.h>
#include <emgui/Emgui.h>
#include "Editor.h"
#include "Menu.h"
static SDL_Surface *screen;
void swapBuffers()
{
SDL_GL_SwapBuffers();
}
void Window_populateRecentList(text_t** files)
{
int i;
for (i = 0; i < 4; i++)
if (files[i][0] != 0)
printf("recent %d: %s\n", i, files[i]);
}
void Window_setTitle(const text_t *title)
{
SDL_WM_SetCaption(title, NULL);
}
int getFilename(text_t *path)
{
fgets(path, 512, stdin);
if (path[0] == 0)
{
printf("Aborted\n");
return 0;
}
else
{
if (path[0] != 0 && path[strlen(path) - 1] == '\n')
path[strlen(path) - 1] = 0; // cut newline
return 1;
}
}
int Dialog_open(text_t *path)
{
printf("Load from: ");
return getFilename(path);
}
int Dialog_save(text_t *path)
{
printf("Save to: ");
return getFilename(path);
}
void Dialog_showColorPicker(unsigned int* color)
{
printf("dialog_showColorPicker() not implemented\n");
}
void Dialog_showError(const text_t* text)
{
printf("Error %s\n", text);
}
int mapSdlEmKeycode(SDLKey key)
{
switch (key)
{
case SDLK_LEFT: return EMGUI_KEY_ARROW_LEFT;
case SDLK_RIGHT: return EMGUI_KEY_ARROW_RIGHT;
case SDLK_UP: return EMGUI_KEY_ARROW_UP;
case SDLK_DOWN: return EMGUI_KEY_ARROW_DOWN;
case SDLK_RETURN: return EMGUI_KEY_ENTER;
case SDLK_ESCAPE: return EMGUI_KEY_ESC;
case SDLK_TAB: return EMGUI_KEY_TAB;
case SDLK_BACKSPACE: return EMGUI_KEY_BACKSPACE;
case SDLK_SPACE: return EMGUI_KEY_SPACE;
default: return key >= ' ' && key <= 127 ? key : 0;
}
}
static int modifiers;
int getModifiers()
{
return modifiers;
}
void updateModifier(int mask, int flag)
{
modifiers = (modifiers & ~mask) | (flag ? mask : 0);
}
int updateModifiers(SDLMod mod)
{
updateModifier(EMGUI_KEY_SHIFT, !!(mod & (KMOD_LSHIFT | KMOD_RSHIFT)));
updateModifier(EMGUI_KEY_CTRL, !!(mod & (KMOD_LCTRL | KMOD_RCTRL)));
updateModifier(EMGUI_KEY_ALT, !!(mod & (KMOD_LALT | KMOD_RALT)));
return getModifiers();
}
int updateModifierPress(SDLKey key, int state)
{
switch (key)
{
case SDLK_LSHIFT: updateModifier(EMGUI_KEY_SHIFT, state); return 0;
case SDLK_RSHIFT: updateModifier(EMGUI_KEY_SHIFT, state); return 0;
case SDLK_LCTRL: updateModifier(EMGUI_KEY_CTRL, state); return 0;
case SDLK_RCTRL: updateModifier(EMGUI_KEY_CTRL, state); return 0;
case SDLK_LALT: updateModifier(EMGUI_KEY_ALT, state); return 0;
case SDLK_RALT: updateModifier(EMGUI_KEY_ALT, state); return 0;
default: return 1;
}
}
int checkMenu(int key, int mod, const MenuDescriptor *item)
{
for (; item->name; item++)
{
if (key == item->key && mod == item->winMod)
{
printf("Menuevent %d %s\n", item->id, item->name);
if (key== EMGUI_KEY_TAB ||
key== EMGUI_KEY_ENTER ||
key== EDITOR_MENU_DELETE_KEY)
{
Emgui_sendKeyinput(key, getModifiers());
}
Editor_menuEvent(item->id);
return 0;
}
}
return 1;
}
int checkRecent(int key, int mod)
{
if (mod == EMGUI_KEY_CTRL && key >= '1' && key <= '4') {
printf("Load recent %d\n", key - '1');
Editor_menuEvent(EDITOR_MENU_RECENT_FILE_0 + key - '1');
return 0;
}
return 1;
}
int sendMenu(int key, int mod)
{
if (!checkMenu(key, mod, g_fileMenu))
return 0;
if (!checkMenu(key, mod, g_editMenu))
return 0;
if (!checkMenu(key, mod, g_viewMenu))
return 0;
if (!checkRecent(key, mod))
return 0;
return 1;
}
void sendKey(int key, int modifiers)
{
Emgui_sendKeyinput(key, modifiers);
Editor_keyDown(key, -1, modifiers);
Editor_update();
}
// sdl keycodes used only internally, mapped to emgui items in the very beginning
void updateKey(SDL_keysym *sym)
{
int keycode = mapSdlEmKeycode(sym->sym);
int modifiers = updateModifiers(sym->mod);
if (!keycode)
{
if (updateModifierPress(sym->sym, 1))
printf("bad key\n");
}
else
{
if (sendMenu(keycode, modifiers))
sendKey(keycode, modifiers);
}
}
int handleKeyDown(SDL_KeyboardEvent *ev)
{
updateKey(&ev->keysym);
return 0;
}
void handleKeyUp(SDL_KeyboardEvent *ev)
{
updateModifierPress(ev->keysym.sym, 0);
}
void handleMouseMotion(SDL_MouseMotionEvent *ev)
{
Emgui_setMouseLmb(!!(ev->state & SDL_BUTTON_LMASK));
Emgui_setMousePos(ev->x, ev->y);
Editor_update();
}
void handleMouseButton(SDL_MouseButtonEvent *ev)
{
switch (ev->button)
{
case SDL_BUTTON_LEFT:
Emgui_setMouseLmb(ev->state == SDL_PRESSED);
Editor_update();
break;
case SDL_BUTTON_WHEELUP:
case SDL_BUTTON_WHEELDOWN:
if (ev->state == SDL_PRESSED)
{
float dir = ev->button == SDL_BUTTON_WHEELDOWN ? 1.0f : -1.0f;
Editor_scroll(0.0f, dir, getModifiers());
Editor_update();
}
break;
default:
break;
}
}
void resize(int w, int h)
{
screen = SDL_SetVideoMode(w, h, 32,
SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE);
EMGFXBackend_updateViewPort(w, h);
Editor_setWindowSize(w, h);
Editor_update();
}
int handleEvent(SDL_Event *ev)
{
switch (ev->type)
{
case SDL_QUIT:
return 1;
case SDL_KEYDOWN:
return handleKeyDown(&ev->key);
case SDL_KEYUP:
handleKeyUp(&ev->key);
break;
case SDL_MOUSEMOTION:
handleMouseMotion(&ev->motion);
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
handleMouseButton(&ev->button);
break;
case SDL_ACTIVEEVENT:
case SDL_VIDEOEXPOSE:
Editor_update();
break;
case SDL_VIDEORESIZE:
resize(ev->resize.w, ev->resize.h);
break;
default:
printf("Unknown SDL event %d\n", ev->type);
}
return 0;
}
int doEvents()
{
SDL_Event ev;
int quit = 0;
while (SDL_PollEvent(&ev)) // SDL_WaitEvent()
quit |= handleEvent(&ev);
return quit;
}
void run(SDL_Surface *screen)
{
for (;;)
{
if (doEvents())
break;
Editor_timedUpdate();
SDL_Delay(16);
}
}
// this just in working directory
#define RECENTS_FILE ".rocket-recents.txt"
void saveRecents()
{
int i;
text_t **recents = Editor_getRecentFiles();
FILE *fh = fopen(RECENTS_FILE, "w");
if (!fh)
return;
for (i = 0; i < 4; i++)
fprintf(fh, "%s\n", recents[i]);
fclose(fh);
}
void loadRecents()
{
int i;
text_t **recents = Editor_getRecentFiles();
FILE *fh = fopen(RECENTS_FILE, "r");
if (!fh)
return;
printf("Recent files:\n");
for (i = 0; i < 4; i++) {
fgets(recents[i], 2048, fh); // size looked up in Editor.c
if (strlen(recents[i]) < 2 ||
recents[i][strlen(recents[i]) - 1] != '\n') {
recents[i][0] = 0;
break; // eof or too long line
}
recents[i][strlen(recents[i]) - 1] = 0; // strip newline
printf("%d: %s\n", i, recents[i]);
fprintf(fh, "%s\n", recents[i]);
}
printf("total %d\n", i);
for (; i < 4; i++) // clear the rest if less than 4 recents
recents[i][0] = 0;
fclose(fh);
}
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "SDL_Init(): %s\n", SDL_GetError());
return 1;
}
SDL_EnableKeyRepeat(200, 20);
screen = SDL_SetVideoMode(800, 600, 32,
SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE);
if (!screen)
{
fprintf(stderr, "SDL_SetVideoMode(): %s\n", SDL_GetError());
return 1;
}
loadRecents();
EMGFXBackend_create();
Editor_create();
EMGFXBackend_updateViewPort(800, 600);
Editor_setWindowSize(800, 600);
Editor_update();
run(screen);
saveRecents();
SDL_Quit();
return 0;
}