WIP: obtained a window
This commit is contained in:
parent
4b6383bf0c
commit
4766fbc9bb
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Gem-graph OpenGL experiments
|
||||||
|
*
|
||||||
|
* Desc: User interface header
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||||
|
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||||
|
*
|
||||||
|
* This file is part of Gem-graph.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GEM_GRAPH_CLIENT_TYPE_APPLICATION (gem_graph_client_application_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GemGraphClientApplication,
|
||||||
|
gem_graph_client_application,
|
||||||
|
GEM_GRAPH_CLIENT,
|
||||||
|
APPLICATION,
|
||||||
|
GtkApplication)
|
||||||
|
|
||||||
|
GemGraphClientApplication *gem_graph_client_application_new(const char *application_id,
|
||||||
|
GApplicationFlags flags);
|
||||||
|
|
||||||
|
G_END_DECLS
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Gem-graph OpenGL experiments
|
||||||
|
*
|
||||||
|
* Desc: User interface header
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||||
|
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||||
|
*
|
||||||
|
* This file is part of Gem-graph.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <gtk-4.0/gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "../include/base.h"
|
||||||
|
|
||||||
|
extern float rotation_angles[N_AXIS];
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GEM_GRAPH_CLIENT_TYPE_WINDOW (gem_graph_client_window_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GemGraphClientWindow,
|
||||||
|
gem_graph_client_window,
|
||||||
|
GEM_GRAPH_CLIENT,
|
||||||
|
WINDOW,
|
||||||
|
GtkApplicationWindow)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
//void on_activate(GtkApplication *app, gpointer user_data);
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Gem-graph OpenGL experiments
|
||||||
|
*
|
||||||
|
* Desc: User interface functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||||
|
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||||
|
*
|
||||||
|
* This file is part of Gem-graph.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../include/application.h"
|
||||||
|
#include "../include/window.h"
|
||||||
|
|
||||||
|
struct _GemGraphClientApplication
|
||||||
|
{
|
||||||
|
GtkApplication parent_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GemGraphClientApplication,
|
||||||
|
gem_graph_client_application,
|
||||||
|
GTK_TYPE_APPLICATION)
|
||||||
|
|
||||||
|
GemGraphClientApplication *gem_graph_client_application_new(
|
||||||
|
const char *application_id,
|
||||||
|
GApplicationFlags flags)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(application_id != NULL, NULL);
|
||||||
|
|
||||||
|
return g_object_new(GEM_GRAPH_CLIENT_TYPE_APPLICATION,
|
||||||
|
"application-id", application_id,
|
||||||
|
"flags", flags,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gem_graph_client_application_activate(GApplication *app)
|
||||||
|
{
|
||||||
|
GtkWindow *window;
|
||||||
|
|
||||||
|
g_assert (GEM_GRAPH_CLIENT_IS_APPLICATION (app));
|
||||||
|
|
||||||
|
window = gtk_application_get_active_window(GTK_APPLICATION (app));
|
||||||
|
if (window == NULL)
|
||||||
|
window = g_object_new(GEM_GRAPH_CLIENT_TYPE_WINDOW,
|
||||||
|
"application", app,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_window_present (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gem_graph_client_application_class_init(
|
||||||
|
GemGraphClientApplicationClass *klass)
|
||||||
|
{
|
||||||
|
GApplicationClass *app_class = G_APPLICATION_CLASS(klass);
|
||||||
|
|
||||||
|
app_class->activate = gem_graph_client_application_activate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gem_graph_client_application_about_action (GSimpleAction *action,
|
||||||
|
GVariant *parameter,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
static const char *authors[] = {"neox", NULL};
|
||||||
|
GemGraphClientApplication *self = user_data;
|
||||||
|
GtkWindow *window = NULL;
|
||||||
|
|
||||||
|
g_assert (GEM_GRAPH_CLIENT_IS_APPLICATION(self));
|
||||||
|
|
||||||
|
window = gtk_application_get_active_window(GTK_APPLICATION (self));
|
||||||
|
|
||||||
|
gtk_show_about_dialog(window,
|
||||||
|
"program-name", "gem-graph-client",
|
||||||
|
"logo-icon-name", "org.alec.gemgraph",
|
||||||
|
"authors", authors,
|
||||||
|
"version", "0.1.0",
|
||||||
|
"copyright", "© 2023 neox",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gem_graph_client_application_quit_action (GSimpleAction *action,
|
||||||
|
GVariant *parameter,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GemGraphClientApplication *self = user_data;
|
||||||
|
|
||||||
|
g_assert(GEM_GRAPH_CLIENT_IS_APPLICATION(self));
|
||||||
|
|
||||||
|
g_application_quit(G_APPLICATION(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GActionEntry app_actions[] = {
|
||||||
|
{ "quit", gem_graph_client_application_quit_action },
|
||||||
|
{ "about", gem_graph_client_application_about_action },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gem_graph_client_application_init(GemGraphClientApplication *self)
|
||||||
|
{
|
||||||
|
g_action_map_add_action_entries(G_ACTION_MAP(self),
|
||||||
|
app_actions,
|
||||||
|
G_N_ELEMENTS(app_actions),
|
||||||
|
self);
|
||||||
|
gtk_application_set_accels_for_action(GTK_APPLICATION (self),
|
||||||
|
"app.quit",
|
||||||
|
(const char *[]) { "<primary>q", NULL });
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
/*
|
||||||
|
* Gem-graph OpenGL experiments
|
||||||
|
*
|
||||||
|
* Desc: User interface functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||||
|
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||||
|
*
|
||||||
|
* This file is part of Gem-graph.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <gtk-4.0/gtk/gtk.h>
|
||||||
|
#include <glib-2.0/glib.h>
|
||||||
|
|
||||||
|
#include "../include/base.h"
|
||||||
|
#include "../include/graphics.h"
|
||||||
|
#include "../include/window.h"
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
float rotation_angles[N_AXIS] = { 0.0 }; // Rotation angles on each axis
|
||||||
|
|
||||||
|
static GtkWidget *gl_area = NULL;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void on_axis_value_change(GtkAdjustment *adjustment, gpointer data);
|
||||||
|
|
||||||
|
static inline GtkWidget *create_axis_slider(int axis)
|
||||||
|
{
|
||||||
|
GtkWidget *box, *label, *slider;
|
||||||
|
GtkAdjustment *adj;
|
||||||
|
const char *text;
|
||||||
|
|
||||||
|
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
|
||||||
|
switch (axis) {
|
||||||
|
case X_AXIS:
|
||||||
|
text = "X";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Y_AXIS:
|
||||||
|
text = "Y";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Z_AXIS:
|
||||||
|
text = "Z";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
label = gtk_label_new(text);
|
||||||
|
gtk_box_append(GTK_BOX(box), label);
|
||||||
|
gtk_widget_show(label);
|
||||||
|
|
||||||
|
adj = gtk_adjustment_new(0.0, 0.0, 360.0, 1.0, 12.0, 0.0);
|
||||||
|
g_signal_connect(adj, "value-changed",
|
||||||
|
G_CALLBACK(on_axis_value_change),
|
||||||
|
GINT_TO_POINTER(axis));
|
||||||
|
slider = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adj);
|
||||||
|
gtk_box_append(GTK_BOX(box), slider);
|
||||||
|
gtk_widget_set_hexpand(slider, TRUE);
|
||||||
|
gtk_widget_show(slider);
|
||||||
|
|
||||||
|
gtk_widget_show(box);
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void on_axis_value_change(GtkAdjustment *adjustment, gpointer data)
|
||||||
|
{
|
||||||
|
int axis = GPOINTER_TO_INT(data);
|
||||||
|
|
||||||
|
g_assert(axis >= 0 && axis < N_AXIS);
|
||||||
|
|
||||||
|
/* Update the rotation angle */
|
||||||
|
rotation_angles[axis] = gtk_adjustment_get_value(adjustment);
|
||||||
|
|
||||||
|
/* Update the contents of the GL drawing area */
|
||||||
|
gtk_widget_queue_draw(gl_area);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_render(GtkGLArea * area, GdkGLContext * context)
|
||||||
|
{
|
||||||
|
if(gtk_gl_area_get_error(area) != NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
graphicsDraw();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* We need to set up our state when we realize the GtkGLArea widget */
|
||||||
|
static void on_realize(GtkWidget *widget)
|
||||||
|
{
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(widget));
|
||||||
|
|
||||||
|
if(gtk_gl_area_get_error(GTK_GL_AREA(widget)) != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
graphicsInitGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should tear down the state when unrealizing */
|
||||||
|
static void on_unrealize(GtkWidget *widget)
|
||||||
|
{
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(widget));
|
||||||
|
|
||||||
|
if(gtk_gl_area_get_error(GTK_GL_AREA(widget)) != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
graphicsShutdownGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_close_window(GtkWidget *widget)
|
||||||
|
{
|
||||||
|
/* Reset the state */
|
||||||
|
gl_area = NULL;
|
||||||
|
|
||||||
|
rotation_angles[X_AXIS] = 0.0;
|
||||||
|
rotation_angles[Y_AXIS] = 0.0;
|
||||||
|
rotation_angles[Z_AXIS] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_activate(GtkApplication *app, gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkWidget *window, *box, *button, *controls;
|
||||||
|
int i, minor=4, major=0;
|
||||||
|
|
||||||
|
window = gtk_application_window_new(app);
|
||||||
|
gtk_window_set_default_size(GTK_WINDOW(window), 400, 600);
|
||||||
|
gtk_window_set_title(GTK_WINDOW(window), "GemGL (essais pour Gem-graph en OpenGL)");
|
||||||
|
g_signal_connect(window, "destroy", G_CALLBACK(on_close_window), NULL);
|
||||||
|
|
||||||
|
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, FALSE);
|
||||||
|
gtk_widget_set_margin_start(box, 12);
|
||||||
|
gtk_widget_set_margin_end(box, 12);
|
||||||
|
gtk_widget_set_margin_top(box, 12);
|
||||||
|
gtk_widget_set_margin_bottom(box, 12);
|
||||||
|
gtk_box_set_spacing(GTK_BOX(box), 6);
|
||||||
|
gtk_window_set_child(GTK_WINDOW(window), box);
|
||||||
|
|
||||||
|
gl_area = gtk_gl_area_new();
|
||||||
|
gtk_gl_area_set_required_version( GTK_GL_AREA(gl_area), minor, major);
|
||||||
|
gtk_gl_area_get_required_version( GTK_GL_AREA(gl_area), &minor, &major);
|
||||||
|
gtk_widget_set_hexpand(gl_area, TRUE);
|
||||||
|
gtk_widget_set_vexpand(gl_area, TRUE);
|
||||||
|
gtk_widget_set_size_request(gl_area, 100, 200);
|
||||||
|
gtk_box_append(GTK_BOX(box), gl_area);
|
||||||
|
|
||||||
|
// We need to initialize and free GL resources, so we use
|
||||||
|
// the realize and unrealize signals on the widget
|
||||||
|
//
|
||||||
|
g_signal_connect(gl_area, "realize", G_CALLBACK(on_realize), NULL);
|
||||||
|
g_signal_connect(gl_area, "unrealize", G_CALLBACK(on_unrealize), NULL);
|
||||||
|
|
||||||
|
// The main "draw" call for GtkGLArea
|
||||||
|
g_signal_connect(gl_area, "render", G_CALLBACK(on_render), NULL);
|
||||||
|
|
||||||
|
controls = gtk_box_new(GTK_ORIENTATION_VERTICAL, FALSE);
|
||||||
|
gtk_box_append(GTK_BOX(box), controls);
|
||||||
|
gtk_widget_set_hexpand(controls, TRUE);
|
||||||
|
|
||||||
|
for(i = 0; i < N_AXIS; i++)
|
||||||
|
gtk_box_append(GTK_BOX(controls), create_axis_slider(i));
|
||||||
|
|
||||||
|
button = gtk_button_new_with_label("Fermer");
|
||||||
|
gtk_widget_set_hexpand(button, TRUE);
|
||||||
|
gtk_box_append(GTK_BOX(box), button);
|
||||||
|
g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_window_destroy), window);
|
||||||
|
|
||||||
|
gtk_widget_show(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
struct _GemGraphClientWindow
|
||||||
|
{
|
||||||
|
GtkApplicationWindow parent_instance;
|
||||||
|
|
||||||
|
/* Template widgets */
|
||||||
|
GtkHeaderBar *header_bar;
|
||||||
|
GtkLabel *label;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_FINAL_TYPE (GemGraphClientWindow,
|
||||||
|
gem_graph_client_window,
|
||||||
|
GTK_TYPE_APPLICATION_WINDOW)
|
||||||
|
|
||||||
|
static void gem_graph_client_window_class_init(GemGraphClientWindowClass *klass)
|
||||||
|
{
|
||||||
|
gchar *contents;
|
||||||
|
gsize len;
|
||||||
|
GError *err;
|
||||||
|
GBytes *bytes;
|
||||||
|
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
|
||||||
|
|
||||||
|
if (g_file_get_contents("ui/gemgraph.ui", &contents, &len, &err) == FALSE)
|
||||||
|
g_error("error reading ui/gemgraph.ui: %s", err->message);
|
||||||
|
|
||||||
|
bytes = g_bytes_new_take(contents, len);
|
||||||
|
gtk_widget_class_set_template(GTK_WIDGET_CLASS(klass), bytes);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child(widget_class,
|
||||||
|
GemGraphClientWindow,
|
||||||
|
header_bar);
|
||||||
|
gtk_widget_class_bind_template_child(widget_class,
|
||||||
|
GemGraphClientWindow,
|
||||||
|
label);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gem_graph_client_window_init(GemGraphClientWindow *self)
|
||||||
|
{
|
||||||
|
gtk_widget_init_template(GTK_WIDGET (self));
|
||||||
|
}
|
Loading…
Reference in New Issue