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

📄 gtklabel.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS * file for a list of people on the GTK+ Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/.  */#include <math.h>#include <string.h>#include "gtklabel.h"#include "gdk/gdkkeysyms.h"#include "gdk/gdki18n.h"enum {  ARG_0,  ARG_LABEL,  ARG_PATTERN,  ARG_JUSTIFY,  ARG_WRAP};typedef struct _GtkLabelULine GtkLabelULine;struct _GtkLabelWord{  GdkWChar *beginning;  gint length;    /* FIXME:   * We need (space,width) only before we've set (x,y), so to save   * memory, these pairs should really be wrapped in a union.   * I haven't yet figured out how to do this without making the code   * look ugly.    */  gint space;  gint width;  gint x;  gint y;  GtkLabelWord *next;  gint uline_y;  GtkLabelULine *uline;};struct _GtkLabelULine{  gint x1;  gint x2;  gint y;  GtkLabelULine *next;};static void gtk_label_class_init   (GtkLabelClass  *klass);static void gtk_label_init	   (GtkLabel	   *label);static void gtk_label_set_arg	   (GtkObject	   *object,				    GtkArg	   *arg,				    guint	    arg_id);static void gtk_label_get_arg	   (GtkObject      *object,				    GtkArg	   *arg,				    guint	    arg_id);static void gtk_label_finalize	   (GtkObject	   *object);static void gtk_label_size_request (GtkWidget	   *widget,				    GtkRequisition *requisition);static void gtk_label_style_set    (GtkWidget      *widget,				    GtkStyle       *previous_style);static gint gtk_label_expose	   (GtkWidget	   *widget,				    GdkEventExpose *event);static GtkLabelWord*  gtk_label_word_alloc          (void);static GtkLabelULine* gtk_label_uline_alloc         (void);static void           gtk_label_free_words          (GtkLabel     *label);static void           gtk_label_free_ulines         (GtkLabelWord *word);static gint           gtk_label_split_text          (GtkLabel     *label);static GtkMiscClass *parent_class = NULL;static GMemChunk *word_chunk = NULL;static GMemChunk *uline_chunk = NULL;GtkTypegtk_label_get_type (void){  static GtkType label_type = 0;    if (!label_type)    {      static const GtkTypeInfo label_info =      {	"GtkLabel",	sizeof (GtkLabel),	sizeof (GtkLabelClass),	(GtkClassInitFunc) gtk_label_class_init,	(GtkObjectInitFunc) gtk_label_init,        /* reserved_1 */ NULL,	/* reserved_2 */ NULL,	(GtkClassInitFunc) NULL,      };            label_type = gtk_type_unique (GTK_TYPE_MISC, &label_info);      gtk_type_set_chunk_alloc (label_type, 32);    }    return label_type;}static voidgtk_label_class_init (GtkLabelClass *class){  GtkObjectClass *object_class;  GtkWidgetClass *widget_class;    object_class = (GtkObjectClass*) class;  widget_class = (GtkWidgetClass*) class;    parent_class = gtk_type_class (GTK_TYPE_MISC);    gtk_object_add_arg_type ("GtkLabel::label", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_LABEL);  gtk_object_add_arg_type ("GtkLabel::pattern", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_PATTERN);  gtk_object_add_arg_type ("GtkLabel::justify", GTK_TYPE_JUSTIFICATION, GTK_ARG_READWRITE, ARG_JUSTIFY);  gtk_object_add_arg_type ("GtkLabel::wrap", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_WRAP);    object_class->set_arg = gtk_label_set_arg;  object_class->get_arg = gtk_label_get_arg;  object_class->finalize = gtk_label_finalize;    widget_class->size_request = gtk_label_size_request;  widget_class->style_set = gtk_label_style_set;  widget_class->expose_event = gtk_label_expose;}static voidgtk_label_set_arg (GtkObject	  *object,		   GtkArg	  *arg,		   guint	   arg_id){  GtkLabel *label;    label = GTK_LABEL (object);    switch (arg_id)    {    case ARG_LABEL:      gtk_label_set_text (label, GTK_VALUE_STRING (*arg));      break;    case ARG_PATTERN:      gtk_label_set_pattern (label, GTK_VALUE_STRING (*arg));      break;    case ARG_JUSTIFY:      gtk_label_set_justify (label, GTK_VALUE_ENUM (*arg));      break;    case ARG_WRAP:      gtk_label_set_line_wrap (label, GTK_VALUE_BOOL (*arg));      break;	      default:      break;    }}static voidgtk_label_get_arg (GtkObject	  *object,		   GtkArg	  *arg,		   guint	   arg_id){  GtkLabel *label;    label = GTK_LABEL (object);    switch (arg_id)    {    case ARG_LABEL:      GTK_VALUE_STRING (*arg) = g_strdup (label->label);      break;    case ARG_PATTERN:      GTK_VALUE_STRING (*arg) = g_strdup (label->pattern);      break;    case ARG_JUSTIFY:      GTK_VALUE_ENUM (*arg) = label->jtype;      break;    case ARG_WRAP:      GTK_VALUE_BOOL (*arg) = label->wrap;      break;    default:      arg->type = GTK_TYPE_INVALID;      break;    }}static voidgtk_label_init (GtkLabel *label){  GTK_WIDGET_SET_FLAGS (label, GTK_NO_WINDOW);    label->label = NULL;  label->label_wc = NULL;  label->pattern = NULL;  label->words = NULL;  label->max_width = 0;  label->jtype = GTK_JUSTIFY_CENTER;  label->wrap = FALSE;    gtk_label_set_text (label, "");}GtkWidget*gtk_label_new (const gchar *str){  GtkLabel *label;    label = gtk_type_new (GTK_TYPE_LABEL);  if (str && *str)    gtk_label_set_text (label, str);    return GTK_WIDGET (label);}static inline voidgtk_label_set_text_internal (GtkLabel *label,			     gchar    *str,			     GdkWChar *str_wc){  gtk_label_free_words (label);        g_free (label->label);  g_free (label->label_wc);    label->label = str;  label->label_wc = str_wc;    gtk_widget_queue_resize (GTK_WIDGET (label));}voidgtk_label_set_text (GtkLabel    *label,		    const gchar *str){  GdkWChar *str_wc;  gint len;  gint wc_len;    g_return_if_fail (GTK_IS_LABEL (label));  if (!str)    str = "";  if (!label->label || strcmp (label->label, str))    {      /* Convert text to wide characters */      len = strlen (str);      str_wc = g_new (GdkWChar, len + 1);      wc_len = gdk_mbstowcs (str_wc, str, len + 1);      if (wc_len >= 0)	{	  str_wc[wc_len] = '\0';	  gtk_label_set_text_internal (label, g_strdup (str), str_wc);	}      else	g_free (str_wc);    }}voidgtk_label_set_pattern (GtkLabel	   *label,		       const gchar *pattern){  g_return_if_fail (GTK_IS_LABEL (label));    gtk_label_free_words (label);    g_free (label->pattern);  label->pattern = g_strdup (pattern);  gtk_widget_queue_resize (GTK_WIDGET (label));}voidgtk_label_set_justify (GtkLabel        *label,		       GtkJustification jtype){  g_return_if_fail (GTK_IS_LABEL (label));  g_return_if_fail (jtype >= GTK_JUSTIFY_LEFT && jtype <= GTK_JUSTIFY_FILL);    if ((GtkJustification) label->jtype != jtype)    {      gtk_label_free_words (label);            label->jtype = jtype;      gtk_widget_queue_resize (GTK_WIDGET (label));    }}voidgtk_label_set_line_wrap (GtkLabel *label,			 gboolean  wrap){  g_return_if_fail (GTK_IS_LABEL (label));    wrap = wrap != FALSE;    if (label->wrap != wrap)    {      gtk_label_free_words (label);      label->wrap = wrap;      gtk_widget_queue_resize (GTK_WIDGET (label));    }}voidgtk_label_get (GtkLabel *label,	       gchar   **str){  g_return_if_fail (label != NULL);  g_return_if_fail (GTK_IS_LABEL (label));  g_return_if_fail (str != NULL);    *str = label->label;}static voidgtk_label_finalize (GtkObject *object){  GtkLabel *label;    g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_LABEL (object));    label = GTK_LABEL (object);    g_free (label->label);  g_free (label->label_wc);  g_free (label->pattern);  gtk_label_free_words (label);  GTK_OBJECT_CLASS (parent_class)->finalize (object);}static GtkLabelULine*gtk_label_uline_alloc (void){  GtkLabelULine *uline;    if (!uline_chunk)    uline_chunk = g_mem_chunk_create (GtkLabelWord, 32, G_ALLOC_AND_FREE);  uline = g_chunk_new0 (GtkLabelULine, uline_chunk);    uline->next = NULL;    return uline;}static voidgtk_label_free_ulines (GtkLabelWord *word){  while (word->uline)    {      GtkLabelULine *uline = word->uline;      word->uline = uline->next;      g_chunk_free (uline, uline_chunk);    }}static GtkLabelWord*gtk_label_word_alloc (void){  GtkLabelWord * word;    if (!word_chunk)    word_chunk = g_mem_chunk_create (GtkLabelWord, 32, G_ALLOC_AND_FREE);    word = g_chunk_new0 (GtkLabelWord, word_chunk);    word->beginning = NULL;  word->next = NULL;  word->uline = NULL;  return word;}static voidgtk_label_free_words (GtkLabel *label){  while (label->words)    {      GtkLabelWord *word = label->words;      label->words = word->next;      gtk_label_free_ulines (word);      g_chunk_free (word, word_chunk);    }}static gintgtk_label_split_text (GtkLabel *label){  GtkLabelWord *word, **tailp;  gint space_width, line_width, max_line_width;  GdkWChar *str, *p;    gtk_label_free_words (label);  if (label->label == NULL)    return 0;    /* Split text at new-lines. */  space_width = gdk_string_width (GTK_WIDGET (label)->style->font, " ");    line_width = 0;  max_line_width = 0;  tailp = &label->words;  str = label->label_wc;    while (*str)    {      word = gtk_label_word_alloc ();            if (str == label->label_wc || str[-1] == '\n')	{	  /* Paragraph break */	  word->space = 0;	  	  max_line_width = MAX (line_width, max_line_width);	  line_width = 0;	}      else if (str[0] == ' ')	{	  while (str[0] == ' ')	    {	      str++;	      word->space += space_width;	    }	}      else	{	  /* Regular inter-word space */	  word->space = space_width;	}            word->beginning = str;            word->length = 0;      p = word->beginning;      while (*p && *p != '\n')	{	  word->length++;	  p++;	}            word->width = gdk_text_width_wc (GTK_WIDGET (label)->style->font, str, word->length);            str += word->length;      if (*str)	str++;            line_width += word->space + word->width;            *tailp = word;      tailp = &word->next;    }    /* Add an empty word to represent an empty line   */  if (str == label->label_wc || str[-1] == '\n')    {      word = gtk_label_word_alloc ();            word->space = 0;      word->beginning = str;      word->length = 0;      word->width = 0;            *tailp = word;      tailp = &word->next;    }    return MAX (line_width, max_line_width);}/* this needs to handle white space better. */static gintgtk_label_split_text_wrapped (GtkLabel *label){

⌨️ 快捷键说明

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