|
|
3f9996 |
|
|
|
3f9996 |
#include <glib.h></glib.h>
|
|
|
3f9996 |
#include <gtk gtk.h=""></gtk>
|
|
|
3f9996 |
#include <gdk gdk.h=""></gdk>
|
|
|
3f9996 |
|
|
|
3f9996 |
#include "private.h"
|
|
|
3f9996 |
|
|
|
3f9996 |
#include "world.h"
|
|
|
3f9996 |
|
|
|
3f9996 |
|
|
|
3f9996 |
static GtkWidget *window;
|
|
|
3f9996 |
|
|
|
1015c5 |
static GtkWidget *dialogMessage;
|
|
|
1015c5 |
static GtkWidget *dialogMessageLabel;
|
|
|
1015c5 |
static GtkWidget *dialogAsk;
|
|
|
1015c5 |
static GtkWidget *dialogAskLabel;
|
|
|
1015c5 |
static GtkWidget *dialogAskEntry;
|
|
|
1015c5 |
static GtkWidget *dialogAskMultiline;
|
|
|
1015c5 |
static GtkWidget *dialogAskMultilineLabel;
|
|
|
1015c5 |
static GtkWidget *dialogAskMultilineEntry;
|
|
|
1015c5 |
|
|
|
3f9996 |
static int started;
|
|
|
3f9996 |
static int stopped;
|
|
|
1015c5 |
static int inDialog;
|
|
|
3f9996 |
static unsigned long long frameCount;
|
|
|
3f9996 |
static gint64 startTime;
|
|
|
3f9996 |
static gint64 currentTime;
|
|
|
1015c5 |
static gint64 dialogTime;
|
|
|
3f9996 |
|
|
|
3f9996 |
static Callback initCallback;
|
|
|
3f9996 |
static Callback drawCallback;
|
|
|
1015c5 |
static Callback deinitCallback;
|
|
|
3f9996 |
|
|
|
650f35 |
static cairo_surface_t *cairoSurface;
|
|
|
981405 |
static int width = 400;
|
|
|
981405 |
static int height = 400;
|
|
|
8eb855 |
static int resizable;
|
|
|
8eb855 |
static char title[1000];
|
|
|
8eb855 |
static int titleSize = (int)(sizeof(title)/sizeof(*title));
|
|
|
546e3a |
static double frameRate = 24;
|
|
|
3f9996 |
|
|
|
3f9996 |
static int cameraEnabled;
|
|
|
3f9996 |
static double cameraX;
|
|
|
3f9996 |
static double cameraY;
|
|
|
3f9996 |
static double cameraZoom = 1;
|
|
|
3f9996 |
|
|
|
1015c5 |
static HeliArray keyEvents[6];
|
|
|
1015c5 |
static int keyEventsCount = (int)(sizeof(keyEvents)/sizeof(*keyEvents));
|
|
|
3f9996 |
|
|
|
3f9996 |
static int mouseMovedInFrame;
|
|
|
3f9996 |
static double _mouseX;
|
|
|
3f9996 |
static double _mouseY;
|
|
|
3f9996 |
|
|
|
3f9996 |
static char* buttonNames[] = {
|
|
|
3f9996 |
"left",
|
|
|
3f9996 |
"middle",
|
|
|
3f9996 |
"right" };
|
|
|
3f9996 |
static int buttonsCount = (int)(sizeof(buttonNames)/sizeof(*buttonNames));
|
|
|
3f9996 |
|
|
|
3f9996 |
|
|
|
1015c5 |
int keyEventGetCount(KeyEvent mode)
|
|
|
1015c5 |
{ return (int)mode >= 0 && (int)mode <= keyEventsCount ? keyEvents[mode].count : 0; }
|
|
|
1015c5 |
const char *keyEventGet(KeyEvent mode, int i)
|
|
|
1015c5 |
{ return (int)mode >= 0 && (int)mode <= keyEventsCount ? heliArrayGetValue(&keyEvents[mode], i) : NULL; }
|
|
|
1015c5 |
|
|
|
1015c5 |
static int keyEventCheck(KeyEvent mode, const char *code) {
|
|
|
1015c5 |
int count = keyEventGetCount(mode);
|
|
|
1015c5 |
for(int i = 0; i < count; ++i)
|
|
|
1015c5 |
if (strcmp(keyEventGet(mode, i), code) == 0)
|
|
|
1015c5 |
return TRUE;
|
|
|
1015c5 |
return FALSE;
|
|
|
1015c5 |
}
|
|
|
1015c5 |
|
|
|
1015c5 |
static void keyEventAdd(KeyEvent mode, const char *code) {
|
|
|
1015c5 |
if ((int)mode >= 0 && mode <= (int)keyEventsCount && !keyEventCheck(mode, code))
|
|
|
1015c5 |
heliArrayInsert(&keyEvents[mode], -1, heliStringCopy(code), &free);
|
|
|
1015c5 |
}
|
|
|
1015c5 |
|
|
|
1015c5 |
static void keyEventRemove(KeyEvent mode, const char *code) {
|
|
|
1015c5 |
if ((int)mode >= 0 && mode <= (int)keyEventsCount)
|
|
|
1015c5 |
for(int i = keyEvents[mode].count-1; i >= 0; --i)
|
|
|
1015c5 |
if (strcmp(keyEvents[mode].items[i].value, code) == 0)
|
|
|
1015c5 |
heliArrayRemove(&keyEvents[mode], i);
|
|
|
1015c5 |
}
|
|
|
3f9996 |
|
|
|
1015c5 |
|
|
|
8535a3 |
int keyDown(const char *code)
|
|
|
1015c5 |
{ return keyEventCheck(KEYEVENT_KEY_DOWN, code); }
|
|
|
07b70f |
int keyWentDown(const char *code)
|
|
|
1015c5 |
{ return keyEventCheck(KEYEVENT_KEY_WENTDOWN, code); }
|
|
|
07b70f |
int keyWentUp(const char *code)
|
|
|
1015c5 |
{ return keyEventCheck(KEYEVENT_KEY_WENTUP, code); }
|
|
|
3f9996 |
|
|
|
3f9996 |
int mouseDidMove()
|
|
|
3f9996 |
{ return mouseMovedInFrame; }
|
|
|
8535a3 |
int mouseDown(const char *code)
|
|
|
1015c5 |
{ return keyEventCheck(KEYEVENT_MOUSE_DOWN, code); }
|
|
|
8535a3 |
int mouseWentDown(const char *code)
|
|
|
1015c5 |
{ return keyEventCheck(KEYEVENT_MOUSE_WENTDOWN, code); }
|
|
|
8535a3 |
int mouseWentUp(const char *code)
|
|
|
1015c5 |
{ return keyEventCheck(KEYEVENT_MOUSE_WENTUP, code); }
|
|
|
3f9996 |
double mouseX()
|
|
|
3f9996 |
{ return _mouseX; }
|
|
|
3f9996 |
double mouseY()
|
|
|
3f9996 |
{ return _mouseY; }
|
|
|
3f9996 |
|
|
|
3f9996 |
int mousePressedOver(Sprite sprite)
|
|
|
1015c5 |
{ return keyEventGetCount(KEYEVENT_MOUSE_DOWN) && mouseIsOver(sprite); }
|
|
|
3f9996 |
|
|
|
981405 |
static void resize(int w, int h) {
|
|
|
981405 |
width = w > 200 ? w : 100;
|
|
|
981405 |
height = h > 200 ? h : 200;
|
|
|
8eb855 |
if (started && !stopped && window) {
|
|
|
981405 |
gtk_window_set_default_size(GTK_WINDOW(window), width, height);
|
|
|
981405 |
gtk_widget_set_size_request(window, width, height);
|
|
|
981405 |
}
|
|
|
981405 |
}
|
|
|
981405 |
|
|
|
3f9996 |
int worldGetWidth()
|
|
|
3f9996 |
{ return width; }
|
|
|
981405 |
void worldSetWidth(int w)
|
|
|
981405 |
{ resize(w, height); }
|
|
|
3f9996 |
|
|
|
07b70f |
int worldGetHeight()
|
|
|
3f9996 |
{ return height; }
|
|
|
981405 |
void worldSetHeight(int h)
|
|
|
981405 |
{ resize(width, h); }
|
|
|
3f9996 |
|
|
|
8eb855 |
int worldGetResizable()
|
|
|
8eb855 |
{ return resizable; }
|
|
|
8eb855 |
void worldSetResizable(int r) {
|
|
|
8eb855 |
if (resizable == r) return;
|
|
|
8eb855 |
resizable = r ? TRUE : FALSE;
|
|
|
8eb855 |
if (started && !stopped && window)
|
|
|
8eb855 |
gtk_window_set_resizable(GTK_WINDOW(window), resizable);
|
|
|
8eb855 |
}
|
|
|
8eb855 |
|
|
|
8eb855 |
const char* worldGetTitle()
|
|
|
8eb855 |
{ return title; }
|
|
|
8eb855 |
void worldSetTitle(const char *t) {
|
|
|
8eb855 |
int changed = FALSE;
|
|
|
8eb855 |
for(int i = 0; i < titleSize-1; ++i) {
|
|
|
8eb855 |
if (title[i] != t[i]) changed = TRUE;
|
|
|
8eb855 |
title[i] = t[i];
|
|
|
8eb855 |
if (!t[i]) break;
|
|
|
8eb855 |
}
|
|
|
8eb855 |
if (changed && started && !stopped && window)
|
|
|
8eb855 |
gtk_window_set_title(GTK_WINDOW(window), title);
|
|
|
8eb855 |
}
|
|
|
8eb855 |
|
|
|
3f9996 |
double worldGetFrameRate()
|
|
|
3f9996 |
{ return frameRate; }
|
|
|
e034e4 |
void worldSetFrameRate(double fps) {
|
|
|
e034e4 |
if (!(fps > 1)) fps = 1;
|
|
|
e034e4 |
if (!(fps < 100)) fps = 100;
|
|
|
e034e4 |
frameRate = fps;
|
|
|
3f9996 |
}
|
|
|
3f9996 |
|
|
|
981405 |
double worldGetTimeStep()
|
|
|
981405 |
{ return 1/frameRate; }
|
|
|
981405 |
|
|
|
3f9996 |
int worldGetFrameCount()
|
|
|
3f9996 |
{ return (int)frameCount; }
|
|
|
3f9996 |
double worldGetSeconds()
|
|
|
1c7488 |
{ return started ? (currentTime - startTime)*HELI_PRECISION : 0.0; }
|
|
|
3f9996 |
|
|
|
3f9996 |
void worldSetInit(Callback init)
|
|
|
3f9996 |
{ initCallback = init; }
|
|
|
3f9996 |
void worldSetDraw(Callback draw)
|
|
|
3f9996 |
{ drawCallback = draw; }
|
|
|
1015c5 |
void worldSetDeinit(Callback deinit)
|
|
|
1015c5 |
{ deinitCallback = deinit; }
|
|
|
3f9996 |
void worldStop()
|
|
|
3f9996 |
{ if (started) stopped = TRUE; }
|
|
|
3f9996 |
|
|
|
3f9996 |
|
|
|
3f9996 |
void cameraOn()
|
|
|
3f9996 |
{ cameraEnabled = TRUE; }
|
|
|
3f9996 |
void cameraOff()
|
|
|
3f9996 |
{ cameraEnabled = FALSE; }
|
|
|
3f9996 |
int cameraIsActive()
|
|
|
3f9996 |
{ return cameraEnabled; }
|
|
|
3f9996 |
|
|
|
3f9996 |
double cameraMouseX()
|
|
|
3f9996 |
{ return _mouseX/cameraZoom + cameraX; }
|
|
|
3f9996 |
double cameraMouseY()
|
|
|
3f9996 |
{ return _mouseY/cameraZoom + cameraY; }
|
|
|
3f9996 |
|
|
|
3f9996 |
double cameraGetX()
|
|
|
3f9996 |
{ return cameraX; }
|
|
|
3f9996 |
void cameraSetX(double x)
|
|
|
3f9996 |
{ cameraX = x; }
|
|
|
3f9996 |
|
|
|
3f9996 |
double cameraGetY()
|
|
|
3f9996 |
{ return cameraY; }
|
|
|
3f9996 |
void cameraSetY(double y)
|
|
|
3f9996 |
{ cameraY = y; }
|
|
|
3f9996 |
|
|
|
3f9996 |
double cameraGetZoom()
|
|
|
3f9996 |
{ return cameraZoom; }
|
|
|
3f9996 |
void cameraSetZoom(double x)
|
|
|
1c7488 |
{ cameraZoom = x > HELI_PRECISION ? x : HELI_PRECISION; }
|
|
|
3f9996 |
|
|
|
1015c5 |
|
|
|
1015c5 |
static void beginDialog() {
|
|
|
1015c5 |
inDialog = TRUE;
|
|
|
1015c5 |
dialogTime = g_get_monotonic_time() - startTime;
|
|
|
1015c5 |
}
|
|
|
1015c5 |
|
|
|
1015c5 |
static void endDialog() {
|
|
|
1015c5 |
for(int i = 0; i < 100; ++i) gtk_main_iteration();
|
|
|
1015c5 |
currentTime = g_get_monotonic_time();
|
|
|
1015c5 |
startTime = currentTime - dialogTime;
|
|
|
1015c5 |
inDialog = FALSE;
|
|
|
1015c5 |
}
|
|
|
1015c5 |
|
|
|
1015c5 |
|
|
|
1015c5 |
void messageBox(const char *message) {
|
|
|
1015c5 |
if (!started || stopped || !window)
|
|
|
1015c5 |
return;
|
|
|
1015c5 |
beginDialog();
|
|
|
1015c5 |
gtk_label_set_label(GTK_LABEL(dialogMessageLabel), message);
|
|
|
1015c5 |
gtk_dialog_run(GTK_DIALOG(dialogMessage));
|
|
|
1015c5 |
gtk_widget_hide(dialogMessage);
|
|
|
1015c5 |
endDialog();
|
|
|
1015c5 |
}
|
|
|
1015c5 |
|
|
|
1015c5 |
void askTextEx(const char *question, char *answer, int maxAnswerSize, int multiline, int password) {
|
|
|
1015c5 |
if (!started || stopped || !window)
|
|
|
1015c5 |
return;
|
|
|
1015c5 |
beginDialog();
|
|
|
1015c5 |
if (multiline) {
|
|
|
1015c5 |
gtk_label_set_label(GTK_LABEL(dialogAskMultilineLabel), question);
|
|
|
1015c5 |
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(dialogAskMultilineEntry));
|
|
|
1015c5 |
gtk_text_buffer_set_text(buffer, answer, -1);
|
|
|
1015c5 |
gtk_dialog_run(GTK_DIALOG(dialogAskMultiline));
|
|
|
1015c5 |
gtk_widget_hide(dialogAskMultiline);
|
|
|
1015c5 |
|
|
|
1015c5 |
GtkTextIter start, end;
|
|
|
1015c5 |
gtk_text_buffer_get_bounds(buffer, &start, &end);
|
|
|
1015c5 |
const char *a = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
|
|
|
1015c5 |
for(int i = 0; i < maxAnswerSize; ++i)
|
|
|
1015c5 |
{ answer[i] = a[i]; if (!a[i]) break; }
|
|
|
1015c5 |
} else {
|
|
|
1015c5 |
gtk_label_set_label(GTK_LABEL(dialogAskLabel), question);
|
|
|
1015c5 |
gtk_entry_set_text(GTK_ENTRY(dialogAskEntry), answer);
|
|
|
1015c5 |
gtk_entry_set_input_purpose(GTK_ENTRY(dialogAskEntry), password ? GTK_INPUT_PURPOSE_PASSWORD : GTK_INPUT_PURPOSE_FREE_FORM);
|
|
|
1015c5 |
gtk_entry_set_visibility(GTK_ENTRY(dialogAskEntry), !password);
|
|
|
1015c5 |
gtk_dialog_run(GTK_DIALOG(dialogAsk));
|
|
|
1015c5 |
gtk_widget_hide(dialogAsk);
|
|
|
1015c5 |
const char *a = gtk_entry_get_text(GTK_ENTRY(dialogAskEntry));
|
|
|
1015c5 |
for(int i = 0; i < maxAnswerSize; ++i)
|
|
|
1015c5 |
{ answer[i] = a[i]; if (!a[i]) break; }
|
|
|
1015c5 |
}
|
|
|
1015c5 |
endDialog();
|
|
|
1015c5 |
}
|
|
|
1015c5 |
|
|
|
1015c5 |
void askText(const char *question, char *answer, int maxAnswerSize)
|
|
|
1015c5 |
{ askTextEx(question, answer, maxAnswerSize, FALSE, FALSE); }
|
|
|
1015c5 |
|
|
|
1015c5 |
|
|
|
650f35 |
static gboolean idle(gpointer data G_GNUC_UNUSED) {
|
|
|
3f9996 |
if (stopped) {
|
|
|
650f35 |
if (window) {
|
|
|
650f35 |
gtk_window_close(GTK_WINDOW(window));
|
|
|
650f35 |
window = NULL;
|
|
|
650f35 |
}
|
|
|
3f9996 |
return FALSE;
|
|
|
3f9996 |
}
|
|
|
650f35 |
gtk_widget_queue_draw(window);
|
|
|
3f9996 |
return TRUE;
|
|
|
3f9996 |
}
|
|
|
3f9996 |
|
|
|
3f9996 |
static gboolean draw(GtkWidget *widget G_GNUC_UNUSED, cairo_t *cr, gpointer data G_GNUC_UNUSED) {
|
|
|
650f35 |
int doFrame = FALSE;
|
|
|
d1f083 |
|
|
|
650f35 |
if ( cairoSurface
|
|
|
650f35 |
&& cairo_image_surface_get_width(cairoSurface) != width
|
|
|
650f35 |
&& cairo_image_surface_get_height(cairoSurface) != height )
|
|
|
650f35 |
{ cairo_surface_destroy(cairoSurface); cairoSurface = NULL; }
|
|
|
650f35 |
if (!cairoSurface) {
|
|
|
650f35 |
cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
|
|
650f35 |
doFrame = TRUE;
|
|
|
650f35 |
}
|
|
|
650f35 |
|
|
|
650f35 |
if (frameCount == 0) {
|
|
|
650f35 |
currentTime = startTime = g_get_monotonic_time();
|
|
|
650f35 |
doFrame = TRUE;
|
|
|
650f35 |
}
|
|
|
650f35 |
|
|
|
981405 |
double dt = 1/frameRate;
|
|
|
650f35 |
gint64 timeStep = (gint64)round(dt*1e6);
|
|
|
650f35 |
gint64 newTime = g_get_monotonic_time();
|
|
|
650f35 |
if (currentTime < newTime)
|
|
|
650f35 |
doFrame = TRUE;
|
|
|
650f35 |
|
|
|
1015c5 |
if (inDialog)
|
|
|
1015c5 |
doFrame = FALSE;
|
|
|
1015c5 |
|
|
|
650f35 |
if (doFrame) {
|
|
|
650f35 |
if (frameCount == 0) heliDoTests();
|
|
|
650f35 |
|
|
|
650f35 |
heliCairo = cairo_create(cairoSurface);
|
|
|
07b70f |
heliDrawingPrepareFrame();
|
|
|
3f9996 |
if (drawCallback) drawCallback();
|
|
|
650f35 |
cairo_surface_flush(cairoSurface);
|
|
|
650f35 |
cairo_destroy(heliCairo);
|
|
|
650f35 |
heliCairo = NULL;
|
|
|
650f35 |
|
|
|
981405 |
currentTime += timeStep;
|
|
|
981405 |
++frameCount;
|
|
|
981405 |
heliSpriteUpdate(dt);
|
|
|
09c823 |
heliSoundUpdate();
|
|
|
650f35 |
|
|
|
1015c5 |
heliArrayClear(&keyEvents[KEYEVENT_KEY_WENTDOWN]);
|
|
|
1015c5 |
heliArrayClear(&keyEvents[KEYEVENT_KEY_WENTUP]);
|
|
|
1015c5 |
heliArrayClear(&keyEvents[KEYEVENT_MOUSE_WENTDOWN]);
|
|
|
1015c5 |
heliArrayClear(&keyEvents[KEYEVENT_MOUSE_WENTUP]);
|
|
|
650f35 |
|
|
|
650f35 |
if (stopped) g_idle_add_full(G_PRIORITY_DEFAULT, idle, NULL, NULL);
|
|
|
3f9996 |
}
|
|
|
650f35 |
|
|
|
650f35 |
gint64 delta = newTime - currentTime - 2000000;
|
|
|
650f35 |
if (delta > 0) {
|
|
|
650f35 |
startTime += delta;
|
|
|
650f35 |
currentTime += delta;
|
|
|
650f35 |
}
|
|
|
650f35 |
|
|
|
650f35 |
heliDrawingClearFrame(cr);
|
|
|
650f35 |
cairo_save(cr);
|
|
|
650f35 |
cairo_set_source_surface(cr, cairoSurface, 0, 0);
|
|
|
650f35 |
cairo_paint(cr);
|
|
|
650f35 |
cairo_restore(cr);
|
|
|
650f35 |
|
|
|
e034e4 |
if (!stopped) {
|
|
|
e034e4 |
gtk_widget_queue_draw(window);
|
|
|
e034e4 |
delta = currentTime - g_get_monotonic_time();
|
|
|
e034e4 |
if (delta > 100) g_usleep(delta - 100);
|
|
|
e034e4 |
}
|
|
|
650f35 |
|
|
|
3f9996 |
return TRUE;
|
|
|
3f9996 |
}
|
|
|
3f9996 |
|
|
|
3f9996 |
static gboolean handleEvent(GtkWidget *widget G_GNUC_UNUSED, GdkEvent *event, gpointer data G_GNUC_UNUSED) {
|
|
|
3f9996 |
gchar *keyname;
|
|
|
3f9996 |
int button;
|
|
|
3f9996 |
|
|
|
3f9996 |
switch(event->type) {
|
|
|
3f9996 |
case GDK_KEY_PRESS:
|
|
|
3f9996 |
keyname = heliStringCopy( gdk_keyval_name(event->key.keyval) );
|
|
|
3f9996 |
heliLowercase(keyname);
|
|
|
1015c5 |
keyEventAdd(KEYEVENT_KEY_DOWN, keyname);
|
|
|
1015c5 |
keyEventAdd(KEYEVENT_KEY_WENTDOWN, keyname);
|
|
|
3f9996 |
free(keyname);
|
|
|
3f9996 |
return TRUE;
|
|
|
3f9996 |
case GDK_KEY_RELEASE:
|
|
|
3f9996 |
keyname = heliStringCopy( gdk_keyval_name(event->key.keyval) );
|
|
|
3f9996 |
heliLowercase(keyname);
|
|
|
1015c5 |
keyEventRemove(KEYEVENT_KEY_DOWN, keyname);
|
|
|
1015c5 |
keyEventAdd(KEYEVENT_KEY_WENTUP, keyname);
|
|
|
3f9996 |
free(keyname);
|
|
|
3f9996 |
return TRUE;
|
|
|
3f9996 |
case GDK_BUTTON_PRESS:
|
|
|
3f9996 |
button = event->button.button;
|
|
|
09c823 |
if (button >= 1 && button <= buttonsCount) {
|
|
|
1015c5 |
keyEventAdd(KEYEVENT_MOUSE_DOWN, buttonNames[button - 1]);
|
|
|
1015c5 |
keyEventAdd(KEYEVENT_MOUSE_WENTDOWN, buttonNames[button - 1]);
|
|
|
3f9996 |
}
|
|
|
3f9996 |
_mouseX = event->button.x;
|
|
|
3f9996 |
_mouseY = event->button.y;
|
|
|
3f9996 |
return TRUE;
|
|
|
3f9996 |
case GDK_BUTTON_RELEASE:
|
|
|
3f9996 |
button = event->button.button;
|
|
|
09c823 |
if (button >= 1 && button <= buttonsCount) {
|
|
|
1015c5 |
keyEventRemove(KEYEVENT_MOUSE_DOWN, buttonNames[button - 1]);
|
|
|
1015c5 |
keyEventAdd(KEYEVENT_MOUSE_WENTUP, buttonNames[button - 1]);
|
|
|
3f9996 |
}
|
|
|
3f9996 |
_mouseX = event->button.x;
|
|
|
3f9996 |
_mouseY = event->button.y;
|
|
|
3f9996 |
return TRUE;
|
|
|
3f9996 |
case GDK_MOTION_NOTIFY:
|
|
|
3f9996 |
_mouseX = event->motion.x;
|
|
|
3f9996 |
_mouseY = event->motion.y;
|
|
|
3f9996 |
return TRUE;
|
|
|
1015c5 |
case GDK_FOCUS_CHANGE:
|
|
|
1015c5 |
if (!event->focus_change.in) {
|
|
|
1015c5 |
int count = keyEventGetCount(KEYEVENT_KEY_DOWN);
|
|
|
1015c5 |
for(int i = 0; i < count; ++i)
|
|
|
1015c5 |
keyEventAdd(KEYEVENT_KEY_WENTUP, keyEventGet(KEYEVENT_KEY_DOWN, i));
|
|
|
1015c5 |
heliArrayClear(&keyEvents[KEYEVENT_KEY_DOWN]);
|
|
|
1015c5 |
}
|
|
|
1015c5 |
break;
|
|
|
650f35 |
case GDK_DELETE:
|
|
|
650f35 |
stopped = TRUE;
|
|
|
650f35 |
window = NULL;
|
|
|
650f35 |
break;
|
|
|
3f9996 |
default:
|
|
|
3f9996 |
break;
|
|
|
3f9996 |
}
|
|
|
3f9996 |
return FALSE;
|
|
|
3f9996 |
}
|
|
|
3f9996 |
|
|
|
3f9996 |
static void activate(GtkApplication* app, gpointer data G_GNUC_UNUSED) {
|
|
|
3f9996 |
window = gtk_application_window_new(app);
|
|
|
3f9996 |
g_signal_connect(window, "draw", G_CALLBACK(draw), NULL);
|
|
|
3f9996 |
g_signal_connect(window, "event", G_CALLBACK(handleEvent), NULL);
|
|
|
1015c5 |
gtk_window_set_resizable(GTK_WINDOW(window), resizable);
|
|
|
981405 |
gtk_window_set_default_size(GTK_WINDOW(window), width, height);
|
|
|
8eb855 |
gtk_window_set_title(GTK_WINDOW(window), title);
|
|
|
3f9996 |
gtk_widget_add_events( window,
|
|
|
3f9996 |
GDK_POINTER_MOTION_MASK
|
|
|
3f9996 |
| GDK_BUTTON_PRESS_MASK
|
|
|
3f9996 |
| GDK_BUTTON_RELEASE_MASK
|
|
|
3f9996 |
| GDK_KEY_PRESS_MASK
|
|
|
1015c5 |
| GDK_KEY_RELEASE_MASK
|
|
|
1015c5 |
| GDK_FOCUS_CHANGE_MASK );
|
|
|
3f9996 |
gtk_widget_set_size_request(window, width, height);
|
|
|
3f9996 |
gtk_widget_show(window);
|
|
|
981405 |
|
|
|
1015c5 |
dialogMessage = gtk_dialog_new_with_buttons(
|
|
|
1015c5 |
"", GTK_WINDOW(window),
|
|
|
1015c5 |
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
|
1015c5 |
"_OK", GTK_RESPONSE_OK, NULL);
|
|
|
1015c5 |
gtk_dialog_set_default_response(GTK_DIALOG(dialogMessage), GTK_RESPONSE_OK);
|
|
|
1015c5 |
dialogMessageLabel = gtk_label_new("");
|
|
|
1015c5 |
gtk_widget_show(dialogMessageLabel);
|
|
|
1015c5 |
gtk_container_add(
|
|
|
1015c5 |
GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialogMessage))),
|
|
|
1015c5 |
dialogMessageLabel );
|
|
|
1015c5 |
|
|
|
1015c5 |
dialogAsk = gtk_dialog_new_with_buttons(
|
|
|
1015c5 |
"", GTK_WINDOW(window),
|
|
|
1015c5 |
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
|
1015c5 |
"_OK", GTK_RESPONSE_OK, NULL);
|
|
|
1015c5 |
gtk_dialog_set_default_response(GTK_DIALOG(dialogAsk), GTK_RESPONSE_OK);
|
|
|
1015c5 |
GtkWidget *askBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
|
|
|
1015c5 |
dialogAskLabel = gtk_label_new("");
|
|
|
1015c5 |
dialogAskEntry = gtk_entry_new();
|
|
|
1015c5 |
gtk_entry_set_activates_default(GTK_ENTRY(dialogAskEntry), TRUE);
|
|
|
1015c5 |
gtk_container_add(GTK_CONTAINER(askBox), dialogAskLabel);
|
|
|
1015c5 |
gtk_container_add(GTK_CONTAINER(askBox), dialogAskEntry);
|
|
|
1015c5 |
gtk_widget_show_all(askBox);
|
|
|
1015c5 |
gtk_container_add(
|
|
|
1015c5 |
GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialogAsk))),
|
|
|
1015c5 |
askBox );
|
|
|
1015c5 |
|
|
|
1015c5 |
dialogAskMultiline = gtk_dialog_new_with_buttons(
|
|
|
1015c5 |
"", GTK_WINDOW(window),
|
|
|
1015c5 |
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
|
1015c5 |
"_OK", GTK_RESPONSE_OK, NULL);
|
|
|
1015c5 |
gtk_dialog_set_default_response(GTK_DIALOG(dialogAskMultiline), GTK_RESPONSE_OK);
|
|
|
1015c5 |
GtkWidget *askMultilineBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
|
|
|
1015c5 |
dialogAskMultilineLabel = gtk_label_new("");
|
|
|
1015c5 |
dialogAskMultilineEntry = gtk_text_view_new();
|
|
|
1015c5 |
GtkWidget *askMultilineScrollBox = gtk_scrolled_window_new(NULL, NULL);
|
|
|
1015c5 |
gtk_container_add(GTK_CONTAINER(askMultilineScrollBox), dialogAskMultilineEntry);
|
|
|
1015c5 |
gtk_container_add(GTK_CONTAINER(askMultilineBox), dialogAskMultilineLabel);
|
|
|
5b96a1 |
gtk_container_add_with_properties(
|
|
|
5b96a1 |
GTK_CONTAINER(askMultilineBox), askMultilineScrollBox,
|
|
|
5b96a1 |
"expand", TRUE, "fill", TRUE, NULL );
|
|
|
1015c5 |
gtk_widget_show_all(askMultilineBox);
|
|
|
5b96a1 |
gtk_container_add_with_properties(
|
|
|
1015c5 |
GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialogAskMultiline))),
|
|
|
5b96a1 |
askMultilineBox,
|
|
|
5b96a1 |
"expand", TRUE, "fill", TRUE, NULL );
|
|
|
1015c5 |
|
|
|
650f35 |
currentTime = startTime = 0;
|
|
|
8eb855 |
heliInitialized = TRUE;
|
|
|
3f9996 |
if (initCallback) initCallback();
|
|
|
650f35 |
g_idle_add(idle, NULL);
|
|
|
3f9996 |
}
|
|
|
3f9996 |
|
|
|
8eb855 |
void worldRun() {
|
|
|
3f9996 |
if (started) return;
|
|
|
3f9996 |
started = TRUE;
|
|
|
3f9996 |
stopped = FALSE;
|
|
|
3f9996 |
|
|
|
3f9996 |
frameCount = 0;
|
|
|
3f9996 |
srand(time(NULL));
|
|
|
3f9996 |
|
|
|
3f9996 |
GtkApplication *application = gtk_application_new(NULL, 0);
|
|
|
3f9996 |
g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
|
|
|
3f9996 |
g_application_run(G_APPLICATION(application), 0, NULL);
|
|
|
3f9996 |
g_object_unref(application);
|
|
|
1015c5 |
window = NULL;
|
|
|
1015c5 |
dialogMessage = NULL;
|
|
|
1015c5 |
dialogMessageLabel = NULL;
|
|
|
1015c5 |
dialogAsk = NULL;
|
|
|
1015c5 |
dialogAskEntry = NULL;
|
|
|
1015c5 |
dialogAskLabel = NULL;
|
|
|
1015c5 |
dialogAskMultiline = NULL;
|
|
|
1015c5 |
dialogAskMultilineEntry = NULL;
|
|
|
1015c5 |
dialogAskMultilineLabel = NULL;
|
|
|
1015c5 |
|
|
|
1015c5 |
if (deinitCallback) deinitCallback();
|
|
|
3f9996 |
|
|
|
8eb855 |
heliArrayClear(&heliObjectsSet);
|
|
|
07b70f |
heliSpriteFinish();
|
|
|
07b70f |
heliDrawingFinish();
|
|
|
07b70f |
heliAnimationFinish();
|
|
|
09c823 |
heliSoundFinish();
|
|
|
8eb855 |
heliArrayDestroy(&heliObjectsSet);
|
|
|
8eb855 |
|
|
|
8eb855 |
heliInitialized = FALSE;
|
|
|
650f35 |
|
|
|
650f35 |
if (cairoSurface) cairo_surface_destroy(cairoSurface);
|
|
|
650f35 |
cairoSurface = NULL;
|
|
|
650f35 |
|
|
|
1015c5 |
for(int i = 0; i < keyEventsCount; ++i)
|
|
|
1015c5 |
heliArrayDestroy(&keyEvents[i]);
|
|
|
3f9996 |
|
|
|
3f9996 |
started = FALSE;
|
|
|
3f9996 |
}
|