⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkpanel.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
字号:
/* * gtkpanel.c - implementation of the `Panels' GTK layout container. */#include "gtkpanel.h"static void panels_init(Panels *panels);static void panels_class_init(PanelsClass *klass);static void panels_map(GtkWidget *widget);static void panels_unmap(GtkWidget *widget);static void panels_draw(GtkWidget *widget, GdkRectangle *area);static gint panels_expose(GtkWidget *widget, GdkEventExpose *event);static void panels_base_add(GtkContainer *container, GtkWidget *widget);static void panels_remove(GtkContainer *container, GtkWidget *widget);static void panels_forall(GtkContainer *container, gboolean include_internals,                           GtkCallback callback, gpointer callback_data);static GtkType panels_child_type(GtkContainer *container);static void panels_size_request(GtkWidget *widget, GtkRequisition *req);static void panels_size_allocate(GtkWidget *widget, GtkAllocation *alloc);static GtkContainerClass *parent_class = NULL;GtkType panels_get_type(void){    static GtkType panels_type = 0;    if (!panels_type) {        static const GtkTypeInfo panels_info = {            "Panels",            sizeof(Panels),            sizeof(PanelsClass),            (GtkClassInitFunc) panels_class_init,            (GtkObjectInitFunc) panels_init,            /* reserved_1 */ NULL,            /* reserved_2 */ NULL,            (GtkClassInitFunc) NULL,        };        panels_type = gtk_type_unique(GTK_TYPE_CONTAINER, &panels_info);    }    return panels_type;}static void panels_class_init(PanelsClass *klass){    GtkObjectClass *object_class;    GtkWidgetClass *widget_class;    GtkContainerClass *container_class;    object_class = (GtkObjectClass *)klass;    widget_class = (GtkWidgetClass *)klass;    container_class = (GtkContainerClass *)klass;    parent_class = gtk_type_class(GTK_TYPE_CONTAINER);    /*     * FIXME: do we have to do all this faffing with set_arg,     * get_arg and child_arg_type? Ick.     */    widget_class->map = panels_map;    widget_class->unmap = panels_unmap;    widget_class->draw = panels_draw;    widget_class->expose_event = panels_expose;    widget_class->size_request = panels_size_request;    widget_class->size_allocate = panels_size_allocate;    container_class->add = panels_base_add;    container_class->remove = panels_remove;    container_class->forall = panels_forall;    container_class->child_type = panels_child_type;}static void panels_init(Panels *panels){    GTK_WIDGET_SET_FLAGS(panels, GTK_NO_WINDOW);    panels->children = NULL;}/* * These appear to be thoroughly tedious functions; the only reason * we have to reimplement them at all is because we defined our own * format for our GList of children... */static void panels_map(GtkWidget *widget){    Panels *panels;    GtkWidget *child;    GList *children;    g_return_if_fail(widget != NULL);    g_return_if_fail(IS_PANELS(widget));    panels = PANELS(widget);    GTK_WIDGET_SET_FLAGS(panels, GTK_MAPPED);    for (children = panels->children;         children && (child = children->data);         children = children->next) {        if (child &&	    GTK_WIDGET_VISIBLE(child) &&            !GTK_WIDGET_MAPPED(child))            gtk_widget_map(child);    }}static void panels_unmap(GtkWidget *widget){    Panels *panels;    GtkWidget *child;    GList *children;    g_return_if_fail(widget != NULL);    g_return_if_fail(IS_PANELS(widget));    panels = PANELS(widget);    GTK_WIDGET_UNSET_FLAGS(panels, GTK_MAPPED);    for (children = panels->children;         children && (child = children->data);         children = children->next) {        if (child &&	    GTK_WIDGET_VISIBLE(child) &&            GTK_WIDGET_MAPPED(child))            gtk_widget_unmap(child);    }}static void panels_draw(GtkWidget *widget, GdkRectangle *area){    Panels *panels;    GtkWidget *child;    GList *children;    GdkRectangle child_area;    g_return_if_fail(widget != NULL);    g_return_if_fail(IS_PANELS(widget));    if (GTK_WIDGET_DRAWABLE(widget)) {        panels = PANELS(widget);        for (children = panels->children;             children && (child = children->data);             children = children->next) {            if (child &&		GTK_WIDGET_DRAWABLE(child) &&                gtk_widget_intersect(child, area, &child_area))                gtk_widget_draw(child, &child_area);        }    }}static gint panels_expose(GtkWidget *widget, GdkEventExpose *event){    Panels *panels;    GtkWidget *child;    GList *children;    GdkEventExpose child_event;    g_return_val_if_fail(widget != NULL, FALSE);    g_return_val_if_fail(IS_PANELS(widget), FALSE);    g_return_val_if_fail(event != NULL, FALSE);    if (GTK_WIDGET_DRAWABLE(widget)) {        panels = PANELS(widget);        child_event = *event;        for (children = panels->children;             children && (child = children->data);             children = children->next) {            if (child &&		GTK_WIDGET_DRAWABLE(child) &&                GTK_WIDGET_NO_WINDOW(child) &&                gtk_widget_intersect(child, &event->area,                                     &child_event.area))                gtk_widget_event(child, (GdkEvent *)&child_event);        }    }    return FALSE;}static void panels_base_add(GtkContainer *container, GtkWidget *widget){    Panels *panels;    g_return_if_fail(container != NULL);    g_return_if_fail(IS_PANELS(container));    g_return_if_fail(widget != NULL);    panels = PANELS(container);    panels_add(panels, widget);}static void panels_remove(GtkContainer *container, GtkWidget *widget){    Panels *panels;    GtkWidget *child;    GList *children;    gboolean was_visible;    g_return_if_fail(container != NULL);    g_return_if_fail(IS_PANELS(container));    g_return_if_fail(widget != NULL);    panels = PANELS(container);    for (children = panels->children;         children && (child = children->data);         children = children->next) {        if (child != widget)            continue;        was_visible = GTK_WIDGET_VISIBLE(widget);        gtk_widget_unparent(widget);        panels->children = g_list_remove_link(panels->children, children);        g_list_free(children);        if (was_visible)            gtk_widget_queue_resize(GTK_WIDGET(container));        break;    }}static void panels_forall(GtkContainer *container, gboolean include_internals,                           GtkCallback callback, gpointer callback_data){    Panels *panels;    GtkWidget *child;    GList *children, *next;    g_return_if_fail(container != NULL);    g_return_if_fail(IS_PANELS(container));    g_return_if_fail(callback != NULL);    panels = PANELS(container);    for (children = panels->children;         children && (child = children->data);         children = next) {        /*         * We can't wait until after the callback to assign         * `children = children->next', because the callback might         * be gtk_widget_destroy, which would remove the link         * `children' from the list! So instead we must get our         * hands on the value of the `next' pointer _before_ the         * callback.         */        next = children->next;	if (child)	    callback(child, callback_data);    }}static GtkType panels_child_type(GtkContainer *container){    return GTK_TYPE_WIDGET;}GtkWidget *panels_new(void){    Panels *panels;    panels = gtk_type_new(panels_get_type());    return GTK_WIDGET(panels);}void panels_add(Panels *panels, GtkWidget *child){    g_return_if_fail(panels != NULL);    g_return_if_fail(IS_PANELS(panels));    g_return_if_fail(child != NULL);    g_return_if_fail(child->parent == NULL);    panels->children = g_list_append(panels->children, child);    gtk_widget_set_parent(child, GTK_WIDGET(panels));    if (GTK_WIDGET_REALIZED(panels))        gtk_widget_realize(child);    if (GTK_WIDGET_VISIBLE(panels)) {        if (GTK_WIDGET_MAPPED(panels))            gtk_widget_map(child);        gtk_widget_queue_resize(child);    }}void panels_switch_to(Panels *panels, GtkWidget *target){    GtkWidget *child = NULL;    GList *children;    gboolean changed = FALSE;    g_return_if_fail(panels != NULL);    g_return_if_fail(IS_PANELS(panels));    g_return_if_fail(target != NULL);    g_return_if_fail(target->parent == GTK_WIDGET(panels));    for (children = panels->children;         children && (child = children->data);         children = children->next) {	if (!child)            continue;        if (child == target) {            if (!GTK_WIDGET_VISIBLE(child)) {                gtk_widget_show(child);                changed = TRUE;            }        } else {            if (GTK_WIDGET_VISIBLE(child)) {                gtk_widget_hide(child);                changed = TRUE;            }        }    }    if (changed)        gtk_widget_queue_resize(child);}/* * Now here comes the interesting bit. The actual layout part is * done in the following two functions: *  * panels_size_request() examines the list of widgets held in the * Panels, and returns a requisition stating the absolute minimum * size it can bear to be. *  * panels_size_allocate() is given an allocation telling it what * size the whole container is going to be, and it calls * gtk_widget_size_allocate() on all of its (visible) children to * set their size and position relative to the top left of the * container. */static void panels_size_request(GtkWidget *widget, GtkRequisition *req){    Panels *panels;    GtkWidget *child;    GList *children;    g_return_if_fail(widget != NULL);    g_return_if_fail(IS_PANELS(widget));    g_return_if_fail(req != NULL);    panels = PANELS(widget);    req->width = 0;    req->height = 0;    for (children = panels->children;         children && (child = children->data);         children = children->next) {        GtkRequisition creq;        gtk_widget_size_request(child, &creq);        if (req->width < creq.width)            req->width = creq.width;        if (req->height < creq.height)            req->height = creq.height;    }    req->width += 2*GTK_CONTAINER(panels)->border_width;    req->height += 2*GTK_CONTAINER(panels)->border_width;}static void panels_size_allocate(GtkWidget *widget, GtkAllocation *alloc){    Panels *panels;    GtkWidget *child;    GList *children;    gint border;    g_return_if_fail(widget != NULL);    g_return_if_fail(IS_PANELS(widget));    g_return_if_fail(alloc != NULL);    panels = PANELS(widget);    widget->allocation = *alloc;    border = GTK_CONTAINER(panels)->border_width;    for (children = panels->children;         children && (child = children->data);         children = children->next) {        GtkAllocation call;        call.x = alloc->x + border;        call.width = alloc->width - 2*border;        call.y = alloc->y + border;        call.height = alloc->height - 2*border;        gtk_widget_size_allocate(child, &call);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -