source: trunk/src/gtk/editor.cpp @ 157

Last change on this file since 157 was 157, checked in by sam, 10 years ago

Implement scrolling in the GTK window using the scrollbars.

  • Property svn:keywords set to Id
File size: 5.0 KB
Line 
1//
2// Deus Hax (working title)
3// Copyright (c) 2010 Sam Hocevar <sam@hocevar.net>
4//
5
6#if defined HAVE_CONFIG_H
7#   include "config.h"
8#endif
9
10#include <cstdio>
11#include <cstdlib>
12#include <cmath>
13
14#include <gtk/gtk.h>
15#include <gtkgl/gtkglarea.h>
16
17#include "core.h"
18#include "debugfps.h"
19
20static volatile int quit = 0;
21
22static int ticking = 0;
23static float const FPS = 30.0f;
24
25static MapViewer *mv;
26static GtkWidget *glarea;
27static GtkAdjustment *hadj, *vadj;
28
29static gint main_quit(GtkWidget *widget, GdkEventExpose *event)
30{
31    (void)widget;
32    (void)event;
33
34    quit = 1;
35    gtk_main_quit();
36    return FALSE;
37}
38
39static gboolean tick(void *widget)
40{
41    // FIXME: do not do anything if the previous tick was too recent?
42
43    // FIXME: only quit if all entities have been cleaned
44    if (quit)
45        return FALSE;
46
47    ticking = 1;
48
49    mv->SetPOV(gtk_adjustment_get_value(hadj), gtk_adjustment_get_value(vadj));
50
51    /* Tick the game */
52    Ticker::TickGame();
53
54    gtk_widget_draw(GTK_WIDGET(widget), NULL);
55
56    return TRUE;
57}
58
59static gint init(GtkWidget *widget)
60{
61    struct
62    {
63        GtkAdjustment *adj;
64        float map_size, sw_size;
65    }
66    s[2] =
67    {
68        { hadj, mv->GetWidth(), widget->allocation.width },
69        { vadj, mv->GetHeight(), widget->allocation.height },
70    };
71
72    for (int i = 0; i < 2; i++)
73    {
74        gtk_adjustment_set_lower(s[i].adj, 0);
75        gtk_adjustment_set_upper(s[i].adj, s[i].map_size);
76        gtk_adjustment_set_step_increment(s[i].adj, 1);
77        gtk_adjustment_set_page_increment(s[i].adj, s[i].sw_size);
78        gtk_adjustment_set_page_size(s[i].adj, s[i].sw_size);
79
80        float hval = gtk_adjustment_get_value(s[i].adj);
81        if (hval + s[i].sw_size > s[i].map_size)
82        {
83            gtk_adjustment_set_value(s[i].adj, s[i].map_size - s[i].sw_size);
84            gtk_adjustment_value_changed(s[i].adj);
85        }
86    }
87
88    if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
89        Video::Setup(widget->allocation.width, widget->allocation.height);
90
91    return TRUE;
92}
93
94static gint reshape_gl(GtkWidget *widget, GdkEventConfigure *event)
95{
96    (void)event;
97
98    return init(widget);
99}
100
101static gint draw(GtkWidget *widget, GdkEventExpose *event)
102{
103    if (event->count > 0)
104        return TRUE;
105
106    /* OpenGL functions can be called only if make_current returns true */
107    if (ticking && gtk_gl_area_make_current(GTK_GL_AREA(widget)))
108    {
109        ticking = 0;
110
111        /* Clear the screen, tick the renderer, show the frame and
112         * clamp to desired framerate */
113        Video::Clear();
114        Ticker::TickDraw();
115        gtk_gl_area_swapbuffers(GTK_GL_AREA(widget));
116        while (g_main_context_iteration(NULL, FALSE))
117            ;
118        Ticker::ClampFps(1000.0f / FPS);
119    }
120
121    return TRUE;
122}
123
124int main(int argc, char **argv)
125{
126    /* Initialize GTK */
127    g_thread_init(NULL);
128    gtk_init(&argc, &argv);
129
130    if (gdk_gl_query() == FALSE)
131    {
132        g_print("OpenGL not supported\n");
133        return EXIT_FAILURE;
134    }
135
136    /* Build the application interface and keep a few member pointers */
137    GtkBuilder *builder = gtk_builder_new();
138    if (!gtk_builder_add_from_file(builder, "src/gtk/editor.xml", NULL))
139    {
140        g_print("Cannot build from XML\n");
141        return EXIT_FAILURE;
142    }
143
144    GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
145    GtkWidget *viewport = GTK_WIDGET(
146                              gtk_builder_get_object(builder, "viewport1"));
147    hadj = gtk_range_get_adjustment(GTK_RANGE(
148                              gtk_builder_get_object(builder, "hscrollbar1")));
149    vadj = gtk_range_get_adjustment(GTK_RANGE(
150                              gtk_builder_get_object(builder, "vscrollbar1")));
151    g_object_unref(G_OBJECT(builder));
152
153    /* Create new OpenGL widget */
154    int attrlist[] =
155    {
156        GDK_GL_RGBA,
157        GDK_GL_RED_SIZE, 1,
158        GDK_GL_GREEN_SIZE, 1,
159        GDK_GL_BLUE_SIZE, 1,
160        GDK_GL_DOUBLEBUFFER,
161        GDK_GL_NONE
162    };
163
164    glarea = gtk_gl_area_new(attrlist);
165    gtk_widget_set_usize(glarea, 400, 300);
166    gtk_widget_set_events(glarea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
167    gtk_container_add(GTK_CONTAINER(viewport), glarea);
168
169    /* Connect signals and show window */
170    gtk_signal_connect(GTK_OBJECT(window), "delete_event",
171                       GTK_SIGNAL_FUNC(main_quit), NULL);
172
173    gtk_signal_connect(GTK_OBJECT(glarea), "expose_event",
174                       GTK_SIGNAL_FUNC(draw), NULL);
175    gtk_signal_connect(GTK_OBJECT(glarea), "configure_event",
176                       GTK_SIGNAL_FUNC(reshape_gl), NULL);
177    gtk_signal_connect(GTK_OBJECT(glarea), "realize",
178                       GTK_SIGNAL_FUNC(init), NULL);
179
180    // FIXME: detect when the map viewer is killed
181    mv = new MapViewer("maps/testmap.tmx");
182    new DebugFps();
183
184    /* We tick from the idle function instead of a timeout to avoid
185     * stealing time from the GTK loop when the callback time exceeds
186     * the timeout value. */
187    gtk_widget_show_all(window);
188    gtk_idle_add(tick, glarea);
189    gtk_main();
190
191    return EXIT_SUCCESS;
192}
193
Note: See TracBrowser for help on using the repository browser.