예제 #1
0
static gboolean
which_tooltip_cb (GtkWidget  *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
{
    gchar *text = "";

    GncCombott *combott = GNC_COMBOTT (user_data);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    if(priv->active != 0)
    {
        gtk_tree_model_get( priv->model, &priv->active_iter, priv->tip_col, &text, -1 );
        if(g_strcmp0(text, "") && (text != NULL))
        {
            gchar *label = "";
            gtk_tooltip_set_text (tooltip, text);
            g_free(text);
            return TRUE;
        }
        else
        {
            g_free(text);
            return FALSE;
        }
    }
    return FALSE;
}
예제 #2
0
static gboolean
button_press_cb (GtkWidget *widget, GdkEvent *event, gpointer *user_data )
{
    GncCombott *combott = GNC_COMBOTT (user_data);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    if(priv->model != NULL)
    {
        if (event->type == GDK_BUTTON_PRESS)
        {
            GdkEventButton *bevent = (GdkEventButton *) event;

            gtk_menu_popup (GTK_MENU (priv->menu),
                            NULL, NULL,
                            gctt_combott_menu_position, combott,
                            bevent->button, bevent->time);

            /* Tell calling code that we have handled this event; the buck
             * stops here. */
            return TRUE;
        }
    }
    /* Tell calling code that we have not handled this event; pass it on. */
    return FALSE;
}
예제 #3
0
/* Note that g_value_set_object() refs the object, as does
 * g_object_get(). But g_object_get() only unrefs once when it disgorges
 * the object, leaving an unbalanced ref, which leaks. So instead of
 * using g_value_set_object(), use g_value_take_object() which doesn't
 * ref the object when used in get_property().
 */
static void
gctt_get_property (GObject    *object,
                   guint       param_id,
                   GValue     *value,
                   GParamSpec *pspec)
{
    GncCombott *combott = GNC_COMBOTT (object);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    switch (param_id)
    {
    case PROP_MODEL:
        g_value_take_object (value, priv->model);
        break;

    case PROP_ACTIVE:
        g_value_set_int (value, gnc_combott_get_active (combott));
        break;

    case PROP_TEXT_COL:
        g_value_set_int (value, priv->text_col);
        break;

    case PROP_TIP_COL:
        g_value_set_int (value, priv->tip_col);
        break;

    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
        break;
    }
}
예제 #4
0
void
gnc_combott_set_active (GncCombott *combott, gint index)
{
    GncCombottPrivate *priv;
    GtkTreeIter iter;
    gboolean valid = TRUE;
    gint active = 1;

    g_return_if_fail (GNC_IS_COMBOTT (combott));
    g_return_if_fail (index >= -1);

    priv = GNC_COMBOTT_GET_PRIVATE (combott);

    /* Do we have a valid model */
    if (priv->model != NULL)
    {
        /* Is index the same as current option */
        if(index + 1 != priv->active)
        {
            /* Set button label to blank for no selection */
            if(index == -1)
            {
                priv->active = 0;
                gtk_label_set_text(GTK_LABEL(priv->label), "");
                g_signal_emit (combott, combott_signals[CHANGED], 0);
            }
            else
            {
                /* Get the corresponding entry in the list store */
                valid = gtk_tree_model_get_iter_first (priv->model, &iter);
                while (valid)
                {
                    /* Walk through the list, reading each row */
                    gchar *str_data;
                    gchar *tip_data;
                    /* Make sure you terminate calls to gtk_tree_model_get()
                     * with a '-1' value */
                    gtk_tree_model_get (priv->model, &iter,
                                        priv->text_col, &str_data,
                                        priv->tip_col, &tip_data,
                                        -1);

                    if(index + 1 == active)
                    {
                        priv->active = index + 1;
                        priv->active_iter = iter;
                        gtk_label_set_text(GTK_LABEL(priv->label), str_data);
                        gnc_label_set_alignment (priv->label, 0, 0.5);
                        g_signal_emit (combott, combott_signals[CHANGED], 0);
                    }

                    g_free (str_data);
                    g_free (tip_data);
                    active ++;
                    valid = gtk_tree_model_iter_next (priv->model, &iter);
                }
            }
        }
    }
}
예제 #5
0
static void
menu_getsize_cb (GtkWidget *widget, GtkAllocation *allocation, gpointer *user_data)
{
    GncCombott *combott = GNC_COMBOTT (user_data);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    /* Set the menu width */
    gtk_widget_set_size_request (widget, priv->width - 6, allocation->height);
}
예제 #6
0
static void
button_getsize_cb (GtkWidget *widget, GtkAllocation *allocation, gpointer *user_data)
{
    GncCombott *combott = GNC_COMBOTT (user_data);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    priv->width = allocation->width;
    priv->height = allocation->height;
    priv->x = allocation->x;
    priv->y = allocation->y;
}
예제 #7
0
static void
gctt_refresh_menu (GncCombott *combott, GtkTreeModel *model)
{
    GncCombottPrivate *priv;

    g_return_if_fail (GNC_IS_COMBOTT (combott));
    g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));

    priv = GNC_COMBOTT_GET_PRIVATE (combott);

    gctt_rebuild_menu(combott, model);
}
예제 #8
0
static void
gctt_combott_menu_position (GtkMenu  *menu,
                            gint     *x,
                            gint     *y,
                            gint     *push_in,
                            gpointer  user_data)
{
    GncCombott *combott = GNC_COMBOTT (user_data);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);
    gint sx, sy;
    GtkWidget *child;
    GtkRequisition req;
    GtkAllocation alloc;
    GtkBorder padding;
    GtkStyleContext *sc = gtk_widget_get_style_context (GTK_WIDGET (priv->button));
    GtkStateFlags state_flags = gtk_style_context_get_state (sc);

    child = gtk_bin_get_child (GTK_BIN (priv->button));

    sx = sy = 0;

    if (!gtk_widget_get_has_window (child))
    {
        gtk_widget_get_allocation (child, &alloc);
        sx += alloc.x;
        sy += alloc.y;
    }

    gdk_window_get_root_coords (gtk_widget_get_window (child), sx, sy, &sx, &sy);

    gtk_style_context_get_padding (sc, state_flags, &padding);

    sx -= padding.left;

    gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);

    if (gtk_widget_get_direction (GTK_WIDGET (priv->button)) == GTK_TEXT_DIR_LTR)
        *x = sx;
    else
    {
        gtk_widget_get_allocation (child, &alloc);
        *x = sx + alloc.width - req.width;
    }

    if(priv->active == -1 || priv->active == 0)
        *y = sy;
    else
        *y = sy - ((req.height / priv->num_items) * (priv->active - 1));

    *push_in = FALSE;
}
예제 #9
0
gint
gnc_combott_get_active (GncCombott *combott)
{
    GncCombottPrivate *priv;
    gint result;

    g_return_val_if_fail (GNC_IS_COMBOTT (combott), 0);

    priv = GNC_COMBOTT_GET_PRIVATE (combott);

    result = priv->active - 1;

    return result;
}
예제 #10
0
static void
menuitem_response_cb (GtkMenuItem *item, gpointer *user_data )
{
    const gchar *label_text;
    GtkTreeIter iter, iter_now = {0, NULL, NULL, NULL};
    gboolean valid;
    gint active = 1;
    gint active_now = 1;

    GncCombott *combott = GNC_COMBOTT (user_data);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    label_text = gtk_menu_item_get_label (item);

    /* Set the button Label */
    gtk_label_set_text(GTK_LABEL(priv->label), label_text);
    gtk_misc_set_alignment (GTK_MISC(priv->label), 0, 0.5);

    /* Get the corresponding entry in the list store */
    valid = gtk_tree_model_get_iter_first (priv->model, &iter);
    while (valid)
    {
        /* Walk through the list, reading each row */
        gchar *str_data;
        gchar *tip_data;
        gtk_tree_model_get (priv->model, &iter,
                            priv->text_col, &str_data,
                            priv->tip_col, &tip_data,
                            -1);
        if(!g_strcmp0(str_data, label_text))
        {
            active_now = active;
            iter_now = iter;
        }

        g_free (str_data);
        g_free (tip_data);
        active ++;
        valid = gtk_tree_model_iter_next (priv->model, &iter);
    }

    /* Emit Changed signal if we have selected a new entry */
    if(priv->active != active_now)
    {
        priv->active = active_now;
        priv->active_iter = iter_now;

        g_signal_emit (combott, combott_signals[CHANGED], 0);
    }
}
예제 #11
0
static void
gctt_combott_menu_position (GtkMenu  *menu,
                            gint     *x,
                            gint     *y,
                            gint     *push_in,
                            gpointer  user_data)
{
    GncCombott *combott = GNC_COMBOTT (user_data);
    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);
    gint sx, sy;
    GtkWidget *child;
    GtkRequisition req;
    GtkAllocation alloc;

    child = gtk_bin_get_child (GTK_BIN (priv->button));

    sx = sy = 0;

    if (!gtk_widget_get_has_window (child))
    {
        gtk_widget_get_allocation (child, &alloc);
        sx += alloc.x;
        sy += alloc.y;
    }

    gdk_window_get_root_coords (gtk_widget_get_window (child), sx, sy, &sx, &sy);

    sx -= gtk_widget_get_style (GTK_WIDGET (priv->button))->xthickness;

    gtk_widget_size_request (GTK_WIDGET (menu), &req);

    if (gtk_widget_get_direction (GTK_WIDGET (priv->button)) == GTK_TEXT_DIR_LTR)
        *x = sx;
    else
    {
        gtk_widget_get_allocation (child, &alloc);
        *x = sx + alloc.width - req.width;
    }

    if(priv->active == -1 || priv->active == 0)
        *y = sy;
    else
        *y = sy - ((req.height / priv->num_items) * (priv->active - 1));

    *push_in = FALSE;
}
예제 #12
0
static void
gctt_init (GncCombott *combott)
{
    GtkWidget *hbox;
    GtkWidget *label;
    GtkWidget *arrow;
    GtkWidget *button;
    GtkWidget *sep;

    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    priv->active = 0;
    priv->text_col = 0;
    priv->tip_col = 1;

    hbox = gtk_hbox_new(FALSE, 0);

    arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
    gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);

    sep = gtk_vseparator_new();
    gtk_box_pack_end (GTK_BOX (hbox), sep, FALSE, FALSE, 0);

    label = gtk_label_new(NULL);
    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
    priv->label = label;

    button = gtk_button_new();
    gtk_container_add(GTK_CONTAINER(button), GTK_WIDGET(hbox));
    priv->button = button;

    gtk_container_add(GTK_CONTAINER(combott), GTK_WIDGET(button));

    g_signal_connect (button, "event",
                      G_CALLBACK (button_press_cb), combott);

    gtk_widget_set_has_tooltip (GTK_WIDGET(combott), TRUE);

    g_signal_connect(G_OBJECT(combott), "query-tooltip",
                     G_CALLBACK(which_tooltip_cb), combott);

    g_signal_connect(G_OBJECT(combott), "size-allocate",
                     G_CALLBACK(button_getsize_cb), combott);

    gtk_widget_show(GTK_WIDGET(priv->button));
}
예제 #13
0
static void
gctt_finalize (GObject *object)
{
    GncCombott *combott;
    GncCombottPrivate *priv;

    g_return_if_fail (object != NULL);
    g_return_if_fail (GNC_IS_COMBOTT (object));

    combott = GNC_COMBOTT (object);
    priv = GNC_COMBOTT_GET_PRIVATE (combott);

    if (priv->model)
    {
        priv->model = NULL;
    }

    if (priv->menu)
    {
        priv->menu = NULL;
    }

    G_OBJECT_CLASS (parent_class)->finalize (object);
}
예제 #14
0
static void
gctt_rebuild_menu (GncCombott *combott, GtkTreeModel *model)
{
    GncCombottPrivate *priv;
    GtkTreeIter iter;
    GtkWidget *menu_items;
    gboolean valid;
    gint num = 1;
    gint items = 0;

    g_return_if_fail (GNC_IS_COMBOTT (combott));
    g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));

    priv = GNC_COMBOTT_GET_PRIVATE (combott);

    priv->menu = NULL;

    priv->menu = gtk_menu_new();

    valid = gtk_tree_model_get_iter_first (model, &iter);
    while (valid)
    {
        GtkWidget *label;

        /* Walk through the list, reading each row */
        gchar *str_data;
        gchar *tip_data;
        gtk_tree_model_get (model, &iter,
                            priv->text_col, &str_data,
                            priv->tip_col, &tip_data,
                            -1);

        /* Create a new menu-item with a name... */
        menu_items = gtk_menu_item_new_with_label (str_data);

        /* Get widget width to max number of characters in list */
        if(strlen(str_data) > num)
            num = strlen(str_data);

        /* Add the tooltip to the child label */
        label = gtk_bin_get_child(GTK_BIN(menu_items));
        gtk_widget_set_tooltip_text (label, tip_data);
        gtk_misc_set_alignment (GTK_MISC(label), 0, 0.5);

        /* ...and add it to the menu. */
        gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_items);
        g_signal_connect (menu_items, "activate",
                          G_CALLBACK (menuitem_response_cb),
                          combott);

        /* Show the widget */
        gtk_widget_show (menu_items);

        g_free (str_data);
        g_free (tip_data);
        items++;
        valid = gtk_tree_model_iter_next (model, &iter);
    }

    g_signal_connect(G_OBJECT(priv->menu), "size-allocate", G_CALLBACK(menu_getsize_cb), combott);

    /* Set widget width to max number of characters in list */
    priv->max_number_char = num;
    gtk_label_set_width_chars(GTK_LABEL(priv->label), priv->max_number_char);

    priv->num_items = items;
}
예제 #15
0
static void
gctt_init (GncCombott *combott)
{
    GtkWidget *hbox;
    GtkWidget *label;
    GtkWidget *arrow;
    GtkWidget *button;
    GtkWidget *sep;

    GncCombottPrivate *priv = GNC_COMBOTT_GET_PRIVATE (combott);

    gtk_orientable_set_orientation (GTK_ORIENTABLE(combott), GTK_ORIENTATION_HORIZONTAL);

    // Set the style context for this widget so it can be easily manipulated with css
    gnc_widget_set_style_context (GTK_WIDGET(combott), "GncCombott");

    priv->active = 0;
    priv->text_col = 0;
    priv->tip_col = 1;

    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_box_set_homogeneous (GTK_BOX(hbox), FALSE);

    arrow = gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_BUTTON);

    g_signal_connect (G_OBJECT (arrow), "draw",
                      G_CALLBACK (gnc_draw_arrow_cb), GINT_TO_POINTER(1));

#if GTK_CHECK_VERSION(3,12,0)
    gtk_widget_set_margin_start (GTK_WIDGET(arrow), 5);
#else
    gtk_widget_set_margin_left (GTK_WIDGET(arrow), 5);
#endif
    gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);

    sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
    gtk_box_pack_end (GTK_BOX (hbox), sep, FALSE, FALSE, 0);

    label = gtk_label_new(NULL);
    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
    priv->label = label;

    button = gtk_button_new();
    gtk_container_add(GTK_CONTAINER(button), GTK_WIDGET(hbox));
    priv->button = button;

    gtk_container_add(GTK_CONTAINER(combott), GTK_WIDGET(button));

    g_signal_connect (button, "event",
                      G_CALLBACK (button_press_cb), combott);

    gtk_widget_set_has_tooltip (GTK_WIDGET(combott), TRUE);

    g_signal_connect(G_OBJECT(combott), "query-tooltip",
                     G_CALLBACK(which_tooltip_cb), combott);

    g_signal_connect(G_OBJECT(combott), "size-allocate",
                     G_CALLBACK(button_getsize_cb), combott);

    gtk_widget_show(GTK_WIDGET(priv->button));
}