/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2013 Red Hat, Inc. */ /** * SECTION:nmt-newt-component * @short_description: Base class for widgets that wrap #newtComponents * * #NmtNewtComponent is the abstract class for #NmtNewtWidgets that * wrap a (single) #newtComponent. */ #include "libnm-client-aux-extern/nm-default-client.h" #include "nmt-newt-component.h" #include "nmt-newt-form.h" #include "nmt-newt-hacks.h" G_DEFINE_ABSTRACT_TYPE(NmtNewtComponent, nmt_newt_component, NMT_TYPE_NEWT_WIDGET) #define NMT_NEWT_COMPONENT_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE((o), NMT_TYPE_NEWT_COMPONENT, NmtNewtComponentPrivate)) typedef struct { newtComponent co; gboolean own_component; gboolean sensitive; } NmtNewtComponentPrivate; enum { PROP_0, PROP_COMPONENT, PROP_SENSITIVE, LAST_PROP }; static void nmt_newt_component_init(NmtNewtComponent *component) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(component); priv->sensitive = TRUE; } static void nmt_newt_component_unrealize(NmtNewtWidget *widget) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(widget); if (!priv->co) return; newtComponentAddCallback(priv->co, NULL, NULL); newtComponentAddDestroyCallback(priv->co, NULL, NULL); if (priv->own_component) newtComponentDestroy(priv->co); priv->co = NULL; } static void component_destroy_callback(newtComponent co, void *component) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(component); priv->own_component = FALSE; nmt_newt_widget_unrealize(component); nmt_newt_widget_needs_rebuild(component); } static void nmt_newt_component_realize(NmtNewtWidget *widget) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(widget); nmt_newt_component_unrealize(widget); priv->co = NMT_NEWT_COMPONENT_GET_CLASS(widget)->build_component(NMT_NEWT_COMPONENT(widget), priv->sensitive); priv->own_component = TRUE; if (!priv->sensitive) newtComponentTakesFocus(priv->co, FALSE); newtComponentAddDestroyCallback(priv->co, component_destroy_callback, widget); } static newtComponent * nmt_newt_component_get_components(NmtNewtWidget *widget) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(widget); newtComponent * cos; priv->own_component = FALSE; cos = g_new0(newtComponent, 2); cos[0] = priv->co; return cos; } static NmtNewtWidget * nmt_newt_component_find_component(NmtNewtWidget *widget, newtComponent co) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(widget); if (co == priv->co) return widget; else return NULL; } static void nmt_newt_component_size_request(NmtNewtWidget *widget, int *width, int *height) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(widget); newtComponentGetSize(priv->co, width, height); } static void nmt_newt_component_size_allocate(NmtNewtWidget *widget, int x, int y, int width, int height) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(widget); newtGrid grid; /* You can't directly place a newtComponent, so we create a newtGrid, * position the component within that, and then place the grid. */ grid = newtCreateGrid(1, 1); newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, priv->co, x, y, 0, 0, NEWT_ANCHOR_LEFT | NEWT_ANCHOR_TOP, 0); newtGridPlace(grid, 0, 0); newtGridFree(grid, FALSE); } static newtComponent nmt_newt_component_get_focus_component(NmtNewtWidget *widget) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(widget); return priv->co; } /** * nmt_newt_component_get_component: * @component: an #NmtNewtComponent * * A simpler version of nmt_newt_widget_get_components() for the * single-component case. Also, unlike * nmt_newt_widget_get_component(), this does not realize the widget * if it isn't already realized. FIXME: why? * * Returns: @component's #newtComponent */ newtComponent nmt_newt_component_get_component(NmtNewtComponent *component) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(component); return priv->co; } /** * nmt_newt_component_get_sensitive: * @component: an #NmtNewtComponent * * Gets @component's #NmtNewtComponent:sensitive property, indicating * whether the widget is available for manipulation. Insensitive * components will be skipped over in the keyboard tab chain, and may * be displayed differently. * * Returns: @component's #NmtNewtComponent:sensitive property */ gboolean nmt_newt_component_get_sensitive(NmtNewtComponent *component) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(component); return priv->sensitive; } /** * nmt_newt_component_set_sensitive: * @component: an #NmtNewtComponent * @sensitive: whether @component should be sensitive * * Sets @component's #NmtNewtComponent:sensitive property. */ void nmt_newt_component_set_sensitive(NmtNewtComponent *component, gboolean sensitive) { NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE(component); sensitive = !!sensitive; if (priv->sensitive == sensitive) return; priv->sensitive = sensitive; g_object_notify(G_OBJECT(component), "sensitive"); nmt_newt_widget_needs_rebuild(NMT_NEWT_WIDGET(component)); } static void nmt_newt_component_set_property(GObject * object, guint prop_id, const GValue *value, GParamSpec * pspec) { NmtNewtComponent *component = NMT_NEWT_COMPONENT(object); switch (prop_id) { case PROP_SENSITIVE: nmt_newt_component_set_sensitive(component, g_value_get_boolean(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void nmt_newt_component_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NmtNewtComponent *component = NMT_NEWT_COMPONENT(object); switch (prop_id) { case PROP_COMPONENT: g_value_set_pointer(value, nmt_newt_component_get_component(component)); break; case PROP_SENSITIVE: g_value_set_boolean(value, nmt_newt_component_get_sensitive(component)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void nmt_newt_component_class_init(NmtNewtComponentClass *component_class) { GObjectClass * object_class = G_OBJECT_CLASS(component_class); NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS(component_class); g_type_class_add_private(component_class, sizeof(NmtNewtComponentPrivate)); /* virtual methods */ object_class->set_property = nmt_newt_component_set_property; object_class->get_property = nmt_newt_component_get_property; widget_class->realize = nmt_newt_component_realize; widget_class->unrealize = nmt_newt_component_unrealize; widget_class->get_components = nmt_newt_component_get_components; widget_class->find_component = nmt_newt_component_find_component; widget_class->size_request = nmt_newt_component_size_request; widget_class->size_allocate = nmt_newt_component_size_allocate; widget_class->get_focus_component = nmt_newt_component_get_focus_component; /* properties */ /** * NmtNewtComponent:component: * * The component's #newtComponent */ g_object_class_install_property( object_class, PROP_COMPONENT, g_param_spec_pointer("component", "", "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); /** * NmtNewtComponent:sensitive: * * Whether the component is sensitive. Insensitive components will * be skipped over in the keyboard tab chain, and may be displayed * differently. */ g_object_class_install_property( object_class, PROP_SENSITIVE, g_param_spec_boolean("sensitive", "", "", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); }