📄 gtk2drawing.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Brian Ryner <bryner@brianryner.com> (Original Author) * Pierre Chanial <p_ch@verizon.net> * Michael Ventnor <m.ventnor@gmail.com> * Alp Toker <alp@nuanti.com> * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * This file contains painting functions for each of the gtk2 widgets. * Adapted from the gtkdrawing.c, and gtk+2.0 source. */#include <gtk/gtk.h>#include <gdk/gdkprivate.h>#include <string.h>#include "gtkdrawing.h"#include <math.h>#define XTHICKNESS(style) (style->xthickness)#define YTHICKNESS(style) (style->ythickness)#define WINDOW_IS_MAPPED(window) ((window) && GDK_IS_WINDOW(window) && gdk_window_is_visible(window))static GtkWidget* gProtoWindow;static GtkWidget* gButtonWidget;static GtkWidget* gToggleButtonWidget;static GtkWidget* gButtonArrowWidget;static GtkWidget* gCheckboxWidget;static GtkWidget* gRadiobuttonWidget;static GtkWidget* gHorizScrollbarWidget;static GtkWidget* gVertScrollbarWidget;static GtkWidget* gSpinWidget;static GtkWidget* gHScaleWidget;static GtkWidget* gVScaleWidget;static GtkWidget* gEntryWidget;static GtkWidget* gComboBoxWidget;static GtkWidget* gComboBoxButtonWidget;static GtkWidget* gComboBoxArrowWidget;static GtkWidget* gComboBoxSeparatorWidget;static GtkWidget* gComboBoxEntryWidget;static GtkWidget* gComboBoxEntryTextareaWidget;static GtkWidget* gComboBoxEntryButtonWidget;static GtkWidget* gComboBoxEntryArrowWidget;static GtkWidget* gHandleBoxWidget;static GtkWidget* gToolbarWidget;static GtkWidget* gFrameWidget;static GtkWidget* gStatusbarWidget;static GtkWidget* gProgressWidget;static GtkWidget* gTabWidget;static GtkWidget* gTooltipWidget;static GtkWidget* gMenuBarWidget;static GtkWidget* gMenuBarItemWidget;static GtkWidget* gMenuPopupWidget;static GtkWidget* gMenuItemWidget;static GtkWidget* gImageMenuItemWidget;static GtkWidget* gCheckMenuItemWidget;static GtkWidget* gTreeViewWidget;static GtkTreeViewColumn* gMiddleTreeViewColumn;static GtkWidget* gTreeHeaderCellWidget;static GtkWidget* gTreeHeaderSortArrowWidget;static GtkWidget* gExpanderWidget;static GtkWidget* gToolbarSeparatorWidget;static GtkWidget* gMenuSeparatorWidget;static GtkWidget* gHPanedWidget;static GtkWidget* gVPanedWidget;static GtkWidget* gScrolledWindowWidget;static style_prop_t style_prop_func;static gboolean have_arrow_scaling;static gboolean have_2_10;static gboolean is_initialized;/* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific things they may want to do. */static voidmoz_gtk_set_widget_name(GtkWidget* widget){ gtk_widget_set_name(widget, "MozillaGtkWidget");}gintmoz_gtk_enable_style_props(style_prop_t styleGetProp){ style_prop_func = styleGetProp; return MOZ_GTK_SUCCESS;}static gintensure_window_widget(){ if (!gProtoWindow) { gProtoWindow = gtk_window_new(GTK_WINDOW_POPUP); gtk_widget_realize(gProtoWindow); moz_gtk_set_widget_name(gProtoWindow); } return MOZ_GTK_SUCCESS;}static gintsetup_widget_prototype(GtkWidget* widget){ static GtkWidget* protoLayout; ensure_window_widget(); if (!protoLayout) { protoLayout = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(gProtoWindow), protoLayout); } gtk_container_add(GTK_CONTAINER(protoLayout), widget); gtk_widget_realize(widget); g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); return MOZ_GTK_SUCCESS;}static gintensure_button_widget(){ if (!gButtonWidget) { gButtonWidget = gtk_button_new_with_label("M"); setup_widget_prototype(gButtonWidget); } return MOZ_GTK_SUCCESS;}static gintensure_hpaned_widget(){ if (!gHPanedWidget) { gHPanedWidget = gtk_hpaned_new(); setup_widget_prototype(gHPanedWidget); } return MOZ_GTK_SUCCESS;}static gintensure_vpaned_widget(){ if (!gVPanedWidget) { gVPanedWidget = gtk_vpaned_new(); setup_widget_prototype(gVPanedWidget); } return MOZ_GTK_SUCCESS;}static gintensure_toggle_button_widget(){ if (!gToggleButtonWidget) { gToggleButtonWidget = gtk_toggle_button_new(); setup_widget_prototype(gToggleButtonWidget); /* toggle button must be set active to get the right style on hover. */ GTK_TOGGLE_BUTTON(gToggleButtonWidget)->active = TRUE; } return MOZ_GTK_SUCCESS;}static gintensure_button_arrow_widget(){ if (!gButtonArrowWidget) { ensure_toggle_button_widget(); gButtonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT); gtk_container_add(GTK_CONTAINER(gToggleButtonWidget), gButtonArrowWidget); gtk_widget_realize(gButtonArrowWidget); } return MOZ_GTK_SUCCESS;}static gintensure_checkbox_widget(){ if (!gCheckboxWidget) { gCheckboxWidget = gtk_check_button_new_with_label("M"); setup_widget_prototype(gCheckboxWidget); } return MOZ_GTK_SUCCESS;}static gintensure_radiobutton_widget(){ if (!gRadiobuttonWidget) { gRadiobuttonWidget = gtk_radio_button_new_with_label(NULL, "M"); setup_widget_prototype(gRadiobuttonWidget); } return MOZ_GTK_SUCCESS;}static gintensure_scrollbar_widget(){ if (!gVertScrollbarWidget) { gVertScrollbarWidget = gtk_vscrollbar_new(NULL); setup_widget_prototype(gVertScrollbarWidget); } if (!gHorizScrollbarWidget) { gHorizScrollbarWidget = gtk_hscrollbar_new(NULL); setup_widget_prototype(gHorizScrollbarWidget); } return MOZ_GTK_SUCCESS;}static gintensure_spin_widget(){ if (!gSpinWidget) { gSpinWidget = gtk_spin_button_new(NULL, 1, 0); setup_widget_prototype(gSpinWidget); } return MOZ_GTK_SUCCESS;}static gintensure_scale_widget(){ if (!gHScaleWidget) { gHScaleWidget = gtk_hscale_new(NULL); setup_widget_prototype(gHScaleWidget); } if (!gVScaleWidget) { gVScaleWidget = gtk_vscale_new(NULL); setup_widget_prototype(gVScaleWidget); } return MOZ_GTK_SUCCESS;}static gintensure_entry_widget(){ if (!gEntryWidget) { gEntryWidget = gtk_entry_new(); setup_widget_prototype(gEntryWidget); } return MOZ_GTK_SUCCESS;}/* We need to have pointers to the inner widgets (button, separator, arrow) * of the ComboBox to get the correct rendering from theme engines which * special cases their look. Since the inner layout can change, we ask GTK * to NULL our pointers when they are about to become invalid because the * corresponding widgets don't exist anymore. It's the role of * g_object_add_weak_pointer(). * Note that if we don't find the inner widgets (which shouldn't happen), we * fallback to use generic "non-inner" widgets, and they don't need that kind * of weak pointer since they are explicit children of gProtoWindow and as * such GTK holds a strong reference to them. */static voidmoz_gtk_get_combo_box_inner_button(GtkWidget *widget, gpointer client_data){ if (GTK_IS_TOGGLE_BUTTON(widget)) { gComboBoxButtonWidget = widget; g_object_add_weak_pointer(G_OBJECT(widget), (gpointer) &gComboBoxButtonWidget); gtk_widget_realize(widget); g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); }}static voidmoz_gtk_get_combo_box_button_inner_widgets(GtkWidget *widget, gpointer client_data){ if (GTK_IS_SEPARATOR(widget)) { gComboBoxSeparatorWidget = widget; g_object_add_weak_pointer(G_OBJECT(widget), (gpointer) &gComboBoxSeparatorWidget); } else if (GTK_IS_ARROW(widget)) { gComboBoxArrowWidget = widget; g_object_add_weak_pointer(G_OBJECT(widget), (gpointer) &gComboBoxArrowWidget); } else return; gtk_widget_realize(widget); g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));}static gintensure_combo_box_widgets(){ GtkWidget* buttonChild; if (gComboBoxButtonWidget && gComboBoxArrowWidget) return MOZ_GTK_SUCCESS; /* Create a ComboBox if needed */ if (!gComboBoxWidget) { gComboBoxWidget = gtk_combo_box_new(); setup_widget_prototype(gComboBoxWidget); } /* Get its inner Button */ gtk_container_forall(GTK_CONTAINER(gComboBoxWidget), moz_gtk_get_combo_box_inner_button, NULL); if (gComboBoxButtonWidget) { /* Get the widgets inside the Button */ buttonChild = GTK_BIN(gComboBoxButtonWidget)->child; if (GTK_IS_HBOX(buttonChild)) { /* appears-as-list = FALSE, cell-view = TRUE; the button * contains an hbox. This hbox is there because the ComboBox * needs to place a cell renderer, a separator, and an arrow in * the button when appears-as-list is FALSE. */ gtk_container_forall(GTK_CONTAINER(buttonChild), moz_gtk_get_combo_box_button_inner_widgets, NULL); } else if(GTK_IS_ARROW(buttonChild)) { /* appears-as-list = TRUE, or cell-view = FALSE; * the button only contains an arrow */ gComboBoxArrowWidget = buttonChild; g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer) &gComboBoxArrowWidget); gtk_widget_realize(gComboBoxArrowWidget); g_object_set_data(G_OBJECT(gComboBoxArrowWidget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); } } else { /* Shouldn't be reached with current internal gtk implementation; we * use a generic toggle button as last resort fallback to avoid * crashing. */ ensure_toggle_button_widget(); gComboBoxButtonWidget = gToggleButtonWidget; } if (!gComboBoxArrowWidget) { /* Shouldn't be reached with current internal gtk implementation; * we gButtonArrowWidget as last resort fallback to avoid * crashing. */ ensure_button_arrow_widget(); gComboBoxArrowWidget = gButtonArrowWidget; } /* We don't test the validity of gComboBoxSeparatorWidget since there * is none when "appears-as-list" = TRUE or "cell-view" = FALSE; if it * is invalid we just won't paint it. */ return MOZ_GTK_SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -