//
// gtkhelpers.h
// TikZiT
//
// Copyright 2010 Alex Merry. All rights reserved.
//
// Some code from Glade:
// Copyright 2001 Ximian, Inc.
//
// This file is part of TikZiT.
//
// TikZiT 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.
//
// TikZiT 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 TikZiT. If not, see .
//
#import "gtkhelpers.h"
#import
void gtk_table_adjust_attach (GtkTable *table,
GtkWidget *widget,
gint left_adjust,
gint right_adjust,
gint top_adjust,
gint bottom_adjust) {
guint top_attach;
guint bottom_attach;
guint left_attach;
guint right_attach;
GtkAttachOptions xoptions;
GtkAttachOptions yoptions;
guint xpadding;
guint ypadding;
gtk_container_child_get (GTK_CONTAINER (table), widget,
"top-attach", &top_attach,
"bottom-attach", &bottom_attach,
"left-attach", &left_attach,
"right-attach", &right_attach,
"x-options", &xoptions,
"y-options", &yoptions,
"x-padding", &xpadding,
"y-padding", &ypadding,
NULL);
g_object_ref (G_OBJECT (widget));
gtk_container_remove (GTK_CONTAINER (table), widget);
gtk_table_attach (table, widget,
left_attach + left_adjust,
right_attach + right_adjust,
top_attach + top_adjust,
bottom_attach + bottom_adjust,
xoptions,
yoptions,
xpadding,
ypadding);
g_object_unref (G_OBJECT (widget));
}
/*
* Delete multiple table rows
*/
void gtk_table_delete_rows (GtkTable *table, guint firstRow, guint count) {
if (count == 0) {
return;
}
GtkContainer *tableC = GTK_CONTAINER (table);
guint n_columns;
guint n_rows;
g_object_get (G_OBJECT (table),
"n-columns", &n_columns,
"n-rows", &n_rows,
NULL);
guint topBound = firstRow;
guint bottomBound = firstRow + count;
if (bottomBound > n_rows) {
bottomBound = n_rows;
count = bottomBound - topBound;
}
GList *toBeDeleted = NULL;
GList *toBeShrunk = NULL;
/* indexed by top-attach */
GPtrArray *toBeMoved = g_ptr_array_sized_new (n_rows - topBound);
g_ptr_array_set_size (toBeMoved, n_rows - topBound);
GList *childIt = gtk_container_get_children (tableC);
while (childIt) {
GtkWidget *widget = GTK_WIDGET (childIt->data);
guint top_attach;
guint bottom_attach;
gtk_container_child_get (tableC, widget,
"top-attach", &top_attach,
"bottom-attach", &bottom_attach,
NULL);
if (top_attach >= topBound && bottom_attach <= bottomBound) {
toBeDeleted = g_list_prepend (toBeDeleted, widget);
} else if (top_attach <= topBound && bottom_attach > topBound) {
toBeShrunk = g_list_prepend (toBeShrunk, widget);
} else if (top_attach > topBound) {
GList *rowList = (GList*)g_ptr_array_index (toBeMoved, top_attach - topBound);
rowList = g_list_prepend (rowList, widget);
g_ptr_array_index (toBeMoved, top_attach - topBound) = rowList;
}
childIt = childIt->next;
}
g_list_free (childIt);
/* remove anything that is completely within the segment being deleted */
while (toBeDeleted) {
gtk_container_remove (tableC, GTK_WIDGET (toBeDeleted->data));
toBeDeleted = toBeDeleted->next;
}
g_list_free (toBeDeleted);
/* shrink anything that spans the segment */
while (toBeShrunk) {
GtkWidget *widget = GTK_WIDGET (toBeShrunk->data);
gtk_table_adjust_attach (table, widget, 0, 0, 0, -count);
toBeShrunk = toBeShrunk->next;
}
g_list_free (toBeShrunk);
/* move everything below the segment being deleted up, in order */
/* note that "n-rows" is not a valid "top-attach" */
for (int offset = 0; offset < (n_rows - 1) - topBound; ++offset) {
GList *rowList = (GList *)g_ptr_array_index (toBeMoved, offset);
guint top_attach = offset + topBound;
guint overlap = bottomBound - top_attach;
while (rowList) {
GtkWidget *widget = GTK_WIDGET (rowList->data);
gtk_table_adjust_attach (table, widget, 0, 0, -offset, -(offset + overlap));
rowList = rowList->next;
}
g_list_free (rowList);
g_ptr_array_index (toBeMoved, offset) = NULL;
}
gtk_table_resize (table, n_rows - 1, n_columns);
}
/*
* Delete a table row
*/
void gtk_table_delete_row (GtkTable *table, guint row) {
gtk_table_delete_rows (table, row, 1);
}
NSString * gtk_editable_get_string (GtkEditable *editable, gint start, gint end)
{
gchar *text = gtk_editable_get_chars (editable, start, end);
NSString *string = [NSString stringWithUTF8String:text];
g_free (text);
return string;
}
void gtk_entry_set_string (GtkEntry *entry, NSString *string)
{
gtk_entry_set_text (entry, string == nil ? "" : [string UTF8String]);
}
NSString * gtk_entry_get_string (GtkEntry *entry)
{
return [NSString stringWithUTF8String:gtk_entry_get_text (entry)];
}
GdkRectangle gdk_rectangle_from_ns_rect (NSRect box) {
GdkRectangle rect;
rect.x = box.origin.x;
rect.y = box.origin.y;
rect.width = box.size.width;
rect.height = box.size.height;
return rect;
}
NSRect gdk_rectangle_to_ns_rect (GdkRectangle rect) {
NSRect result;
result.origin.x = rect.x;
result.origin.y = rect.y;
result.size.width = rect.width;
result.size.height = rect.height;
return result;
}
void gtk_action_set_detailed_label (GtkAction *action, const gchar *baseLabel, const gchar *actionName) {
if (actionName == NULL || *actionName == '\0') {
gtk_action_set_label (action, baseLabel);
} else {
GString *label = g_string_sized_new (30);
g_string_printf(label, "%s: %s", baseLabel, actionName);
gtk_action_set_label (action, label->str);
g_string_free (label, TRUE);
}
}
/**
* tz_hijack_key_press:
* @win: a #GtkWindow
* event: the GdkEventKey
* user_data: unused
*
* This function is meant to be attached to key-press-event of a toplevel,
* it simply allows the window contents to treat key events /before/
* accelerator keys come into play (this way widgets dont get deleted
* when cutting text in an entry etc.).
* Creates a liststore suitable for comboboxes and such to
* chose from a variety of types.
*
* Returns: whether the event was handled
*/
gint
tz_hijack_key_press (GtkWindow *win,
GdkEventKey *event,
gpointer user_data)
{
GtkWidget *focus_widget;
focus_widget = gtk_window_get_focus (win);
if (focus_widget &&
(event->keyval == GDK_Delete || /* Filter Delete from accelerator keys */
((event->state & GDK_CONTROL_MASK) && /* CTRL keys... */
((event->keyval == GDK_c || event->keyval == GDK_C) || /* CTRL-C (copy) */
(event->keyval == GDK_x || event->keyval == GDK_X) || /* CTRL-X (cut) */
(event->keyval == GDK_v || event->keyval == GDK_V) || /* CTRL-V (paste) */
(event->keyval == GDK_a || event->keyval == GDK_A) || /* CTRL-A (select-all) */
(event->keyval == GDK_n || event->keyval == GDK_N))))) /* CTRL-N (new document) ?? */
{
return gtk_widget_event (focus_widget,
(GdkEvent *)event);
}
return FALSE;
}
// vim:ft=objc:ts=8:et:sts=4:sw=4