gem-graph-client/libide/gui/ide-run-button.c

233 lines
7.1 KiB
C

/* ide-run-button.c
*
* Copyright 2016-2019 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#define G_LOG_DOMAIN "ide-run-button"
#include "config.h"
#include <dazzle.h>
#include <glib/gi18n.h>
#include <libide-foundry.h>
#include "ide-gui-global.h"
#include "ide-run-button.h"
#include "ide-run-manager-private.h"
struct _IdeRunButton
{
GtkBox parent_instance;
GtkButton *button;
GtkImage *button_image;
DzlMenuButton *menu_button;
GtkShortcutsShortcut *run_shortcut;
GtkLabel *run_tooltip_message;
DzlShortcutTooltip *tooltip;
char *run_handler_icon_name;
};
G_DEFINE_FINAL_TYPE (IdeRunButton, ide_run_button, GTK_TYPE_BOX)
static void
ide_run_button_handler_set (IdeRunButton *self,
GParamSpec *pspec,
IdeRunManager *run_manager)
{
const GList *list;
const GList *iter;
const gchar *handler;
g_assert (IDE_IS_RUN_BUTTON (self));
g_assert (IDE_IS_RUN_MANAGER (run_manager));
handler = ide_run_manager_get_handler (run_manager);
list = _ide_run_manager_get_handlers (run_manager);
for (iter = list; iter; iter = iter->next)
{
const IdeRunHandlerInfo *info = iter->data;
if (g_strcmp0 (info->id, handler) == 0)
{
self->run_handler_icon_name = g_strdup (info->icon_name);
g_object_set (self->button_image, "icon-name", info->icon_name, NULL);
break;
}
}
}
static void
on_run_busy_state_changed_cb (IdeRunButton *self,
GParamSpec *pspec,
IdeRunManager *run_manager)
{
const char *icon_name;
const char *action_name;
g_assert (IDE_IS_RUN_BUTTON (self));
g_assert (IDE_IS_RUN_MANAGER (run_manager));
if (!ide_run_manager_get_busy (run_manager))
{
icon_name = self->run_handler_icon_name;
action_name = "run-manager.run";
}
else
{
icon_name = "builder-run-stop-symbolic";
action_name = "run-manager.stop";
}
g_object_set (self->button_image, "icon-name", icon_name, NULL);
gtk_actionable_set_action_name (GTK_ACTIONABLE (self->button), action_name);
}
static void
ide_run_button_load (IdeRunButton *self,
IdeContext *context)
{
IdeRunManager *run_manager;
g_assert (IDE_IS_RUN_BUTTON (self));
g_assert (IDE_IS_CONTEXT (context));
run_manager = ide_run_manager_from_context (context);
g_signal_connect_object (run_manager,
"notify::busy",
G_CALLBACK (on_run_busy_state_changed_cb),
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (run_manager,
"notify::handler",
G_CALLBACK (ide_run_button_handler_set),
self,
G_CONNECT_SWAPPED);
ide_run_button_handler_set (self, NULL, run_manager);
}
static void
ide_run_button_context_set (GtkWidget *widget,
IdeContext *context)
{
IdeRunButton *self = (IdeRunButton *)widget;
g_assert (IDE_IS_RUN_BUTTON (self));
g_assert (!context || IDE_IS_CONTEXT (context));
if (context != NULL)
ide_run_button_load (self, context);
}
static gboolean
ide_run_button_query_tooltip (IdeRunButton *self,
gint x,
gint y,
gboolean keyboard_tooltip,
GtkTooltip *tooltip,
GtkButton *button)
{
IdeRunManager *run_manager;
const GList *list;
const GList *iter;
const gchar *handler;
IdeContext *context;
g_assert (IDE_IS_RUN_BUTTON (self));
g_assert (GTK_IS_TOOLTIP (tooltip));
g_assert (GTK_IS_BUTTON (button));
context = ide_widget_get_context (GTK_WIDGET (self));
run_manager = ide_run_manager_from_context (context);
handler = ide_run_manager_get_handler (run_manager);
list = _ide_run_manager_get_handlers (run_manager);
if (ide_run_manager_get_busy (run_manager))
{
gtk_tooltip_set_text (tooltip, _("Stop running"));
return TRUE;
}
for (iter = list; iter; iter = iter->next)
{
const IdeRunHandlerInfo *info = iter->data;
if (g_strcmp0 (info->id, handler) == 0)
{
gboolean enabled;
/* Figure out if the run action is enabled. If it
* is not, then we should inform the user that
* the project cannot be run yet because the
* build pipeline is not yet configured. */
g_action_group_query_action (G_ACTION_GROUP (run_manager),
"run",
&enabled,
NULL,
NULL,
NULL,
NULL);
if (!enabled)
{
gtk_tooltip_set_custom (tooltip, GTK_WIDGET (self->run_tooltip_message));
return TRUE;
}
/* The shortcut tooltip will set this up after us */
dzl_shortcut_tooltip_set_accel (self->tooltip, info->accel);
dzl_shortcut_tooltip_set_title (self->tooltip, info->title);
}
}
return FALSE;
}
static void
ide_run_button_class_init (IdeRunButtonClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libide-gui/ui/ide-run-button.ui");
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, button);
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, button_image);
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, menu_button);
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, run_shortcut);
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, run_tooltip_message);
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, tooltip);
}
static void
ide_run_button_init (IdeRunButton *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
g_signal_connect_object (self->button,
"query-tooltip",
G_CALLBACK (ide_run_button_query_tooltip),
self,
G_CONNECT_SWAPPED);
ide_widget_set_context_handler (self, ide_run_button_context_set);
}