@@ -18,7 +18,7 @@ test_map_CXXFLAGS = `pkg-config --cflags sdl gl SDL_image` | |||||
test_map_LDADD = libcommon.a | test_map_LDADD = libcommon.a | ||||
test_map_LDFLAGS = `pkg-config --libs sdl gl SDL_image` -lpipi | test_map_LDFLAGS = `pkg-config --libs sdl gl SDL_image` -lpipi | ||||
editor_SOURCES = gtk/editor.cpp | |||||
editor_SOURCES = gtk/editor.cpp gtk/glmapview.cpp gtk/glmapview.h | |||||
editor_CXXFLAGS = `pkg-config --cflags sdl gl SDL_image gtk+-2.0 gtkgl-2.0` | editor_CXXFLAGS = `pkg-config --cflags sdl gl SDL_image gtk+-2.0 gtkgl-2.0` | ||||
editor_LDADD = libcommon.a | editor_LDADD = libcommon.a | ||||
editor_LDFLAGS = `pkg-config --libs sdl gl gtk+-2.0 gtkgl-2.0 SDL_image` | editor_LDFLAGS = `pkg-config --libs sdl gl gtk+-2.0 gtkgl-2.0 SDL_image` | ||||
@@ -7,178 +7,15 @@ | |||||
# include "config.h" | # include "config.h" | ||||
#endif | #endif | ||||
#include <cstdio> | |||||
#include <cstdlib> | #include <cstdlib> | ||||
#include <cmath> | |||||
#include <gtk/gtk.h> | #include <gtk/gtk.h> | ||||
#include <gtkgl/gtkglarea.h> | #include <gtkgl/gtkglarea.h> | ||||
#include "core.h" | #include "core.h" | ||||
#include "glmapview.h" | |||||
#include "debugfps.h" | #include "debugfps.h" | ||||
static volatile int quit = 0; | |||||
static int ticking = 0; | |||||
static int panning = 0; | |||||
static double xpan = 0.0f, ypan = 0.0f; | |||||
static float const FPS = 30.0f; | |||||
static MapViewer *mv; | |||||
static GtkWidget *glarea; | |||||
static GtkAdjustment *hadj, *vadj; | |||||
static gint main_quit(GtkWidget *widget, GdkEventExpose *event) | |||||
{ | |||||
(void)widget; | |||||
(void)event; | |||||
quit = 1; | |||||
gtk_main_quit(); | |||||
return FALSE; | |||||
} | |||||
static gboolean tick(void *widget) | |||||
{ | |||||
// FIXME: do not do anything if the previous tick was too recent? | |||||
// FIXME: only quit if all entities have been cleaned | |||||
if (quit) | |||||
return FALSE; | |||||
ticking = 1; | |||||
mv->SetPOV(gtk_adjustment_get_value(hadj), gtk_adjustment_get_value(vadj)); | |||||
/* Tick the game */ | |||||
Ticker::TickGame(); | |||||
gtk_widget_draw(GTK_WIDGET(widget), NULL); | |||||
return TRUE; | |||||
} | |||||
static gboolean mouse_button(GtkWidget *widget, GdkEventButton *event, | |||||
gpointer user_data) | |||||
{ | |||||
if (event->type == GDK_BUTTON_PRESS && event->button == 2) | |||||
{ | |||||
panning = 1; | |||||
xpan = event->x; | |||||
ypan = event->y; | |||||
GdkCursor *cursor = gdk_cursor_new(GDK_HAND1); | |||||
gdk_window_set_cursor(widget->window, cursor); | |||||
gdk_cursor_unref(cursor); | |||||
return FALSE; | |||||
} | |||||
else if (event->type == GDK_BUTTON_RELEASE && event->button == 2) | |||||
{ | |||||
panning = 0; | |||||
gdk_window_set_cursor(widget->window, NULL); | |||||
return FALSE; | |||||
} | |||||
return TRUE; | |||||
} | |||||
static gboolean mouse_motion(GtkWidget *widget, GdkEventMotion *event, | |||||
gpointer user_data) | |||||
{ | |||||
if (panning) | |||||
{ | |||||
if (event->x != xpan) | |||||
{ | |||||
double val = gtk_adjustment_get_value(hadj); | |||||
val += xpan - event->x; | |||||
xpan = event->x; | |||||
if (val + widget->allocation.width > mv->GetWidth()) | |||||
val = mv->GetWidth() - widget->allocation.width; | |||||
gtk_adjustment_set_value(hadj, val); | |||||
gtk_adjustment_value_changed(hadj); | |||||
} | |||||
if (event->y != ypan) | |||||
{ | |||||
double val = gtk_adjustment_get_value(vadj); | |||||
val += ypan - event->y; | |||||
ypan = event->y; | |||||
if (val + widget->allocation.height > mv->GetHeight()) | |||||
val = mv->GetHeight() - widget->allocation.height; | |||||
gtk_adjustment_set_value(vadj, val); | |||||
gtk_adjustment_value_changed(vadj); | |||||
} | |||||
} | |||||
return TRUE; | |||||
} | |||||
static gint init(GtkWidget *widget) | |||||
{ | |||||
/* Manage adjustments */ | |||||
struct | |||||
{ | |||||
GtkAdjustment *adj; | |||||
float map_size, sw_size; | |||||
} | |||||
s[2] = | |||||
{ | |||||
{ hadj, mv->GetWidth(), widget->allocation.width }, | |||||
{ vadj, mv->GetHeight(), widget->allocation.height }, | |||||
}; | |||||
for (int i = 0; i < 2; i++) | |||||
{ | |||||
gtk_adjustment_set_lower(s[i].adj, 0); | |||||
gtk_adjustment_set_upper(s[i].adj, s[i].map_size); | |||||
gtk_adjustment_set_step_increment(s[i].adj, 1); | |||||
gtk_adjustment_set_page_increment(s[i].adj, s[i].sw_size); | |||||
gtk_adjustment_set_page_size(s[i].adj, s[i].sw_size); | |||||
float val = gtk_adjustment_get_value(s[i].adj); | |||||
if (val + s[i].sw_size > s[i].map_size) | |||||
{ | |||||
gtk_adjustment_set_value(s[i].adj, s[i].map_size - s[i].sw_size); | |||||
gtk_adjustment_value_changed(s[i].adj); | |||||
} | |||||
} | |||||
/* Set up display */ | |||||
if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) | |||||
Video::Setup(widget->allocation.width, widget->allocation.height); | |||||
return TRUE; | |||||
} | |||||
static gint reshape(GtkWidget *widget, GdkEventConfigure *event) | |||||
{ | |||||
(void)event; | |||||
return init(widget); | |||||
} | |||||
static gint draw(GtkWidget *widget, GdkEventExpose *event) | |||||
{ | |||||
if (event->count > 0) | |||||
return TRUE; | |||||
/* OpenGL functions can be called only if make_current returns true */ | |||||
if (ticking && gtk_gl_area_make_current(GTK_GL_AREA(widget))) | |||||
{ | |||||
ticking = 0; | |||||
/* Clear the screen, tick the renderer, show the frame and | |||||
* clamp to desired framerate */ | |||||
Video::Clear(); | |||||
Ticker::TickDraw(); | |||||
gtk_gl_area_swapbuffers(GTK_GL_AREA(widget)); | |||||
while (g_main_context_iteration(NULL, FALSE)) | |||||
; | |||||
Ticker::ClampFps(1000.0f / FPS); | |||||
} | |||||
return TRUE; | |||||
} | |||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
{ | { | ||||
/* Initialize GTK */ | /* Initialize GTK */ | ||||
@@ -191,69 +28,29 @@ int main(int argc, char **argv) | |||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
/* Build the application interface and keep a few member pointers */ | |||||
/* Build the application interface */ | |||||
GtkBuilder *builder = gtk_builder_new(); | GtkBuilder *builder = gtk_builder_new(); | ||||
if (!gtk_builder_add_from_file(builder, "src/gtk/editor.xml", NULL)) | if (!gtk_builder_add_from_file(builder, "src/gtk/editor.xml", NULL)) | ||||
{ | { | ||||
g_print("Cannot build from XML\n"); | g_print("Cannot build from XML\n"); | ||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
gtk_builder_connect_signals(builder, NULL); | |||||
GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window1")); | |||||
GtkWidget *viewport = GTK_WIDGET( | |||||
gtk_builder_get_object(builder, "viewport1")); | |||||
hadj = gtk_range_get_adjustment(GTK_RANGE( | |||||
gtk_builder_get_object(builder, "hscrollbar1"))); | |||||
vadj = gtk_range_get_adjustment(GTK_RANGE( | |||||
gtk_builder_get_object(builder, "vscrollbar1"))); | |||||
g_object_unref(G_OBJECT(builder)); | |||||
/* Add our custom GL map viewer */ | |||||
GlMapView *glmapview = new GlMapView(builder); | |||||
/* Create new OpenGL widget */ | |||||
int attrlist[] = | |||||
{ | |||||
GDK_GL_RGBA, | |||||
GDK_GL_RED_SIZE, 1, | |||||
GDK_GL_GREEN_SIZE, 1, | |||||
GDK_GL_BLUE_SIZE, 1, | |||||
GDK_GL_DOUBLEBUFFER, | |||||
GDK_GL_NONE | |||||
}; | |||||
glarea = gtk_gl_area_new(attrlist); | |||||
gtk_widget_set_usize(glarea, 400, 300); | |||||
gtk_widget_set_events(glarea, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | |||||
| GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); | |||||
gtk_container_add(GTK_CONTAINER(viewport), glarea); | |||||
/* We tick from the idle function instead of a timeout to avoid | |||||
* stealing time from the GTK loop when the callback time exceeds | |||||
* the timeout value. */ | |||||
gtk_idle_add(tick, glarea); | |||||
/* Connect signals and show window */ | |||||
gtk_signal_connect(GTK_OBJECT(window), "delete_event", | |||||
GTK_SIGNAL_FUNC(main_quit), NULL); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "expose_event", | |||||
GTK_SIGNAL_FUNC(draw), NULL); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "configure_event", | |||||
GTK_SIGNAL_FUNC(reshape), NULL); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "realize", | |||||
GTK_SIGNAL_FUNC(init), NULL); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "button_press_event", | |||||
GTK_SIGNAL_FUNC(mouse_button), NULL); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "button_release_event", | |||||
GTK_SIGNAL_FUNC(mouse_button), NULL); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "motion_notify_event", | |||||
GTK_SIGNAL_FUNC(mouse_motion), NULL); | |||||
/* Show window. We're good to go! */ | |||||
gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "window1"))); | |||||
g_object_unref(G_OBJECT(builder)); | |||||
// FIXME: detect when the map viewer is killed | |||||
mv = new MapViewer("maps/testmap.tmx"); | |||||
new DebugFps(); | new DebugFps(); | ||||
glmapview->LoadMap("maps/testmap.tmx"); | |||||
gtk_widget_show_all(window); | |||||
gtk_main(); | gtk_main(); | ||||
delete glmapview; | |||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||||
} | } | ||||
@@ -4,6 +4,7 @@ | |||||
<!-- interface-naming-policy project-wide --> | <!-- interface-naming-policy project-wide --> | ||||
<object class="GtkWindow" id="window1"> | <object class="GtkWindow" id="window1"> | ||||
<property name="title" translatable="yes">Deus Hax Editor</property> | <property name="title" translatable="yes">Deus Hax Editor</property> | ||||
<signal name="delete_event" handler="gtk_main_quit"/> | |||||
<child> | <child> | ||||
<object class="GtkVBox" id="vbox1"> | <object class="GtkVBox" id="vbox1"> | ||||
<property name="visible">True</property> | <property name="visible">True</property> | ||||
@@ -160,6 +161,7 @@ | |||||
<child> | <child> | ||||
<object class="GtkHScrollbar" id="hscrollbar1"> | <object class="GtkHScrollbar" id="hscrollbar1"> | ||||
<property name="visible">True</property> | <property name="visible">True</property> | ||||
<property name="adjustment">gl_hadj</property> | |||||
</object> | </object> | ||||
<packing> | <packing> | ||||
<property name="top_attach">1</property> | <property name="top_attach">1</property> | ||||
@@ -171,6 +173,7 @@ | |||||
<object class="GtkVScrollbar" id="vscrollbar1"> | <object class="GtkVScrollbar" id="vscrollbar1"> | ||||
<property name="visible">True</property> | <property name="visible">True</property> | ||||
<property name="orientation">vertical</property> | <property name="orientation">vertical</property> | ||||
<property name="adjustment">gl_vadj</property> | |||||
</object> | </object> | ||||
<packing> | <packing> | ||||
<property name="left_attach">1</property> | <property name="left_attach">1</property> | ||||
@@ -179,7 +182,7 @@ | |||||
</packing> | </packing> | ||||
</child> | </child> | ||||
<child> | <child> | ||||
<object class="GtkViewport" id="viewport1"> | |||||
<object class="GtkViewport" id="gl_container"> | |||||
<property name="visible">True</property> | <property name="visible">True</property> | ||||
<property name="resize_mode">queue</property> | <property name="resize_mode">queue</property> | ||||
<child> | <child> | ||||
@@ -229,4 +232,16 @@ | |||||
</object> | </object> | ||||
</child> | </child> | ||||
</object> | </object> | ||||
<object class="GtkAdjustment" id="gl_hadj"> | |||||
<property name="upper">100</property> | |||||
<property name="step_increment">1</property> | |||||
<property name="page_increment">10</property> | |||||
<property name="page_size">10</property> | |||||
</object> | |||||
<object class="GtkAdjustment" id="gl_vadj"> | |||||
<property name="upper">100</property> | |||||
<property name="step_increment">1</property> | |||||
<property name="page_increment">10</property> | |||||
<property name="page_size">10</property> | |||||
</object> | |||||
</interface> | </interface> |
@@ -0,0 +1,257 @@ | |||||
// | |||||
// Deus Hax (working title) | |||||
// Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
#if defined HAVE_CONFIG_H | |||||
# include "config.h" | |||||
#endif | |||||
#include <gtk/gtk.h> | |||||
#include <gtkgl/gtkglarea.h> | |||||
#include "core.h" | |||||
#include "glmapview.h" | |||||
static float const FPS = 30.0f; | |||||
GlMapView::GlMapView(GtkBuilder *builder) | |||||
: hadj(GTK_ADJUSTMENT(gtk_builder_get_object(builder, "gl_hadj"))), | |||||
vadj(GTK_ADJUSTMENT(gtk_builder_get_object(builder, "gl_vadj"))), | |||||
ticking(FALSE), panning(FALSE), | |||||
mapviewer(0), | |||||
xpan(0.0), ypan(0.0) | |||||
{ | |||||
/* Create new OpenGL widget */ | |||||
int attrlist[] = | |||||
{ | |||||
GDK_GL_RGBA, | |||||
GDK_GL_RED_SIZE, 1, | |||||
GDK_GL_GREEN_SIZE, 1, | |||||
GDK_GL_BLUE_SIZE, 1, | |||||
GDK_GL_DOUBLEBUFFER, | |||||
GDK_GL_NONE | |||||
}; | |||||
glarea = gtk_gl_area_new(attrlist); | |||||
gtk_widget_set_usize(glarea, 400, 300); | |||||
gtk_widget_set_events(glarea, GDK_EXPOSURE_MASK | | |||||
GDK_POINTER_MOTION_MASK | | |||||
GDK_BUTTON_PRESS_MASK | | |||||
GDK_BUTTON_RELEASE_MASK); | |||||
GtkContainer *cont = GTK_CONTAINER(gtk_builder_get_object(builder, | |||||
"gl_container")); | |||||
gtk_container_add(cont, glarea); | |||||
/* We tick from the idle function instead of a timeout to avoid | |||||
* stealing time from the GTK loop when the callback time exceeds | |||||
* the timeout value. */ | |||||
g_idle_add((GSourceFunc)IdleTickSignal, this); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "realize", | |||||
GTK_SIGNAL_FUNC(SetupSignal), this); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "destroy", | |||||
GTK_SIGNAL_FUNC(DestroySignal), this); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "expose_event", | |||||
GTK_SIGNAL_FUNC(DrawSignal), this); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "configure_event", | |||||
GTK_SIGNAL_FUNC(ReshapeSignal), this); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "button_press_event", | |||||
GTK_SIGNAL_FUNC(MouseButtonSignal), this); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "button_release_event", | |||||
GTK_SIGNAL_FUNC(MouseButtonSignal), this); | |||||
gtk_signal_connect(GTK_OBJECT(glarea), "motion_notify_event", | |||||
GTK_SIGNAL_FUNC(MouseMotionSignal), this); | |||||
} | |||||
void GlMapView::LoadMap(char const *path) | |||||
{ | |||||
// FIXME: detect when the map viewer is killed | |||||
mapviewer = new MapViewer(path); | |||||
} | |||||
gboolean GlMapView::IdleTick() | |||||
{ | |||||
// FIXME: do not do anything if the previous tick was too recent? | |||||
ticking = TRUE; | |||||
if (mapviewer) | |||||
mapviewer->SetPOV(gtk_adjustment_get_value(hadj), | |||||
gtk_adjustment_get_value(vadj)); | |||||
/* Tick the game */ | |||||
Ticker::TickGame(); | |||||
gtk_widget_draw(GTK_WIDGET(glarea), NULL); | |||||
return TRUE; | |||||
} | |||||
gboolean GlMapView::Setup() | |||||
{ | |||||
if (mapviewer) | |||||
{ | |||||
/* Manage adjustments */ | |||||
struct { GtkAdjustment *adj; float map_size, sw_size; } s[2] = | |||||
{ | |||||
{ hadj, mapviewer->GetWidth(), glarea->allocation.width }, | |||||
{ vadj, mapviewer->GetHeight(), glarea->allocation.height }, | |||||
}; | |||||
for (int i = 0; i < 2; i++) | |||||
{ | |||||
gtk_adjustment_set_lower(s[i].adj, 0); | |||||
gtk_adjustment_set_upper(s[i].adj, s[i].map_size); | |||||
gtk_adjustment_set_step_increment(s[i].adj, 1); | |||||
gtk_adjustment_set_page_increment(s[i].adj, s[i].sw_size); | |||||
gtk_adjustment_set_page_size(s[i].adj, s[i].sw_size); | |||||
float val = gtk_adjustment_get_value(s[i].adj); | |||||
if (val + s[i].sw_size > s[i].map_size) | |||||
{ | |||||
gtk_adjustment_set_value(s[i].adj, | |||||
s[i].map_size - s[i].sw_size); | |||||
gtk_adjustment_value_changed(s[i].adj); | |||||
} | |||||
} | |||||
} | |||||
/* Set up display */ | |||||
if (gtk_gl_area_make_current(GTK_GL_AREA(glarea))) | |||||
Video::Setup(glarea->allocation.width, glarea->allocation.height); | |||||
return TRUE; | |||||
} | |||||
gboolean GlMapView::Destroy() | |||||
{ | |||||
g_idle_remove_by_data(this); | |||||
return TRUE; | |||||
} | |||||
gboolean GlMapView::Draw(GdkEventExpose *event) | |||||
{ | |||||
if (event->count > 0) | |||||
return TRUE; | |||||
/* OpenGL functions can be called only if make_current returns true */ | |||||
if (ticking && gtk_gl_area_make_current(GTK_GL_AREA(glarea))) | |||||
{ | |||||
ticking = FALSE; | |||||
/* Clear the screen, tick the renderer, show the frame and | |||||
* clamp to desired framerate */ | |||||
Video::Clear(); | |||||
Ticker::TickDraw(); | |||||
gtk_gl_area_swapbuffers(GTK_GL_AREA(glarea)); | |||||
while (g_main_context_iteration(NULL, FALSE)) | |||||
; | |||||
Ticker::ClampFps(1000.0f / FPS); | |||||
} | |||||
return TRUE; | |||||
} | |||||
gboolean GlMapView::MouseButton(GdkEventButton *event) | |||||
{ | |||||
if (event->type == GDK_BUTTON_PRESS && event->button == 2) | |||||
{ | |||||
panning = TRUE; | |||||
xpan = event->x; | |||||
ypan = event->y; | |||||
GdkCursor *cursor = gdk_cursor_new(GDK_HAND1); | |||||
gdk_window_set_cursor(glarea->window, cursor); | |||||
gdk_cursor_unref(cursor); | |||||
return FALSE; | |||||
} | |||||
else if (event->type == GDK_BUTTON_RELEASE && event->button == 2) | |||||
{ | |||||
panning = FALSE; | |||||
gdk_window_set_cursor(glarea->window, NULL); | |||||
return FALSE; | |||||
} | |||||
return TRUE; | |||||
} | |||||
gboolean GlMapView::MouseMotion(GdkEventMotion *event) | |||||
{ | |||||
if (panning) | |||||
{ | |||||
if (event->x != xpan) | |||||
{ | |||||
double val = gtk_adjustment_get_value(hadj); | |||||
int map_width = mapviewer->GetWidth(); | |||||
val += xpan - event->x; | |||||
xpan = event->x; | |||||
if (val + glarea->allocation.width > map_width) | |||||
val = map_width - glarea->allocation.width; | |||||
gtk_adjustment_set_value(hadj, val); | |||||
gtk_adjustment_value_changed(hadj); | |||||
} | |||||
if (event->y != ypan) | |||||
{ | |||||
double val = gtk_adjustment_get_value(vadj); | |||||
int map_height = mapviewer->GetHeight(); | |||||
val += ypan - event->y; | |||||
ypan = event->y; | |||||
if (val + glarea->allocation.height > map_height) | |||||
val = map_height - glarea->allocation.height; | |||||
gtk_adjustment_set_value(vadj, val); | |||||
gtk_adjustment_value_changed(vadj); | |||||
} | |||||
} | |||||
return TRUE; | |||||
} | |||||
/* Private signal slots */ | |||||
gboolean GlMapView::IdleTickSignal(GlMapView *that) | |||||
{ | |||||
return that->IdleTick(); | |||||
} | |||||
gboolean GlMapView::SetupSignal(GtkWidget *w, GlMapView *that) | |||||
{ | |||||
(void)w; | |||||
return that->Setup(); | |||||
} | |||||
gboolean GlMapView::DestroySignal(GtkWidget *w, GlMapView *that) | |||||
{ | |||||
(void)w; | |||||
return that->Destroy(); | |||||
} | |||||
gboolean GlMapView::DrawSignal(GtkWidget *w, GdkEventExpose *event, | |||||
GlMapView *that) | |||||
{ | |||||
(void)w; | |||||
return that->Draw(event); | |||||
} | |||||
gboolean GlMapView::ReshapeSignal(GtkWidget *w, GdkEventConfigure *event, | |||||
GlMapView *that) | |||||
{ | |||||
(void)w; | |||||
(void)event; | |||||
return that->Setup(); | |||||
} | |||||
gboolean GlMapView::MouseButtonSignal(GtkWidget *w, GdkEventButton *event, | |||||
GlMapView *that) | |||||
{ | |||||
(void)w; | |||||
return that->MouseButton(event); | |||||
} | |||||
gboolean GlMapView::MouseMotionSignal(GtkWidget *w, GdkEventMotion *event, | |||||
GlMapView *that) | |||||
{ | |||||
(void)w; | |||||
return that->MouseMotion(event); | |||||
} | |||||
@@ -0,0 +1,49 @@ | |||||
// | |||||
// Deus Hax (working title) | |||||
// Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
#if !defined __DH_GLMAPVIEW_H__ | |||||
#define __DH_GLMAPVIEW_H__ | |||||
#include <gtk/gtk.h> | |||||
class GlMapView | |||||
{ | |||||
public: | |||||
GlMapView(GtkBuilder *builder); | |||||
void LoadMap(char const *path); | |||||
private: | |||||
/* Private methods */ | |||||
gboolean IdleTick(); | |||||
gboolean Setup(); | |||||
gboolean Destroy(); | |||||
gboolean Draw(GdkEventExpose *event); | |||||
gboolean MouseButton(GdkEventButton *event); | |||||
gboolean MouseMotion(GdkEventMotion *event); | |||||
/* Private signal slots */ | |||||
static gboolean IdleTickSignal(GlMapView *that); | |||||
static gboolean SetupSignal(GtkWidget *w, GlMapView *that); | |||||
static gboolean DestroySignal(GtkWidget *w, GlMapView *that); | |||||
static gboolean DrawSignal(GtkWidget *w, GdkEventExpose *event, | |||||
GlMapView *that); | |||||
static gboolean ReshapeSignal(GtkWidget *w, GdkEventConfigure *event, | |||||
GlMapView *that); | |||||
static gboolean MouseButtonSignal(GtkWidget *w, GdkEventButton *event, | |||||
GlMapView *that); | |||||
static gboolean MouseMotionSignal(GtkWidget *w, GdkEventMotion *event, | |||||
GlMapView *that); | |||||
private: | |||||
GtkAdjustment *hadj, *vadj; | |||||
GtkWidget *glarea; | |||||
gboolean ticking, panning; | |||||
MapViewer *mapviewer; | |||||
double xpan, ypan; | |||||
}; | |||||
#endif // __DH_GLMAPVIEW_H__ | |||||