
09/12/2002, 15:07
|
 | | | Fecha de Ingreso: octubre-2001
Mensajes: 1.621
Antigüedad: 23 años, 6 meses Puntos: 5 | |
Código:
/*
* Archivo: GtkGraph.c
* Autor: IvanRodriguez
*
* Widget de grafica gtk sencillo
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include "gtkgraph.h"
static GtkWidgetClass *parent_class = NULL;
/*
* Declaraciones anticipadas
*/
static void gtk_graph_class_init (GtkGraphClass *class);
static void gtk_graph_init (GtkGraph *graph);
static void gtk_graph_realize (GtkWidget *widget);
static void gtk_graph_draw (GtkWidget *widget, GdkRectangle *area);
static void gtk_graph_size_request (GtkWidget *widget, GtkRequisition *req);
static gint gtk_graph_expose (GtkWidget *widget, GdkEventExpose *event);
static void gtk_graph_destroy (GtkObject *object);
/*
* gtk_grapth_get_type
*
* Clase interna. Utilizada para definir la clase GtkGraph ante GTK+
*/
guint gtk_graph_get_type (void)
{
static guint graph_type = 0;
/* Si no esta creada todavia */
if(!graph_type)
{
/* Crear un objeto graph_info */
GtkTypeInfo graph_info =
{
"GtkGraph",
sizeof (GtkGraph),
sizeof (GtkGraphClass),
(GtkClassInitFunc) gtk_graph_class_init,
(GtkObjectInitFunc) gtk_graph_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL,
};
/* Informar a GTK+ de su existencia · Obtener identificador univoco */
graph_type = gtk_type_unique (gtk_widget_get_type(), &graph_info);
}
return graph_type;
}
/*
* gtk_graph_class_init
*
* Sustituir todos los metodos de la clase que sea necesario
* para que la clase de la grafica se comporte adecuadamene.
* Aqui se sustituyen las funciones que hacen que se realize
* el dibujo.
*
* class - Clase de definicion del objeto
*/
static void gtk_graph_class_init (GtkGraphClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
/* Obtener la clase del widget */
object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
parent_class = gtk_type_class (gtk_widget_get_type());
/* Sustituir destruccion del objeto */
object_class->destroy = gtk_graph_destroy;
/* sustituir destruccion del objeto */
widget_class->realize = gtk_graph_realize;
widget_class->draw = gtk_graph_draw;
widget_class->size_request = gtk_graph_size_request;
widget_class->expose_event = gtk_graph_expose;
}
/*
* gtk_graph_init
*
* se invoca cada vez que se crea un nuevo elemento de grafica.
* Inicializa los campos de nuestra estructura.
*/
static void gtk_graph_init (GtkGraph *graph)
{
GtkWidget *widget;
widget = (GtkWidget *) graph;
/* Valores iniciales */
graph->values = NULL;
graph->num_values = 0;
}
/*
* gtk_graph_new
*
* Crea un nuevo elemento GtkGraph
*/
GtkWidget* gtk_graph_new (void)
{
return gtk_type_new (gtk_graph_get_type());
}
/*
* gtk_graph_realize
*
* Asociar el widget con una ventana X Window.
*
*/
static void gtk_graph_realize (GtkWidget *widget)
{
GtkGraph *darea;
GdkWindowAttr attributes;
gint attributes_mask;
/* Comprobar errores */
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_GRAPH (widget));
darea = GTK_GRAPH (widget);
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
/* Atributos para crear la ventana */
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = widget->allocation.x;
attributes.y = widget->allocation.y;
attributes.width = widget->allocation.width;
attributes.height = widget->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
attributes.colormap = gtk_widget_get_colormap (widget);
attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
/* Estamos pasando valores x, y, visual y colormap */
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
/* Crear la ventana */
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
gdk_window_set_user_data (widget->window, darea);
widget->style = gtk_style_attach (widget->style, widget->window);
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
}
/*
* gtk_graph_size
*
* Metodo personalizado para establecer el tamañano de la grafica
*/
void gtk_graph_size (GtkGraph *graph, int size)
{
g_return_if_fail (graph != NULL);
g_return_if_fail (GTK_IS_GRAPH (graph));
graph->num_values = size;
graph->values = g_realloc (graph->values, sizeof (gint) *size);
}
/*
* gtk_graph_set_value
*
* Metodo personalizado para establecer el tamaño
*/
void gtk_graph_set_value (GtkGraph *graph, int index, int value)
{
g_return_if_fail (graph != NULL);
g_return_if_fail (GTK_IS_GRAPH (graph));
g_return_if_fail (index < graph->num_values && index >=0);
graph->values[index] = value;
}
/*
* gtk_graph_draw
*
* Dibujar el widget, basandose en el numero de valores graficos del grafico de barras
*/
static void gtk_graph_draw (GtkWidget *widget, GdkRectangle *area)
{
GtkGraph *graph;
int width;
int height;
int column_width;
int max = 0;
int i;
int bar_height;
/* Comprobar existencia de problemas obvios */
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_GRAPH (widget));
/* Asegurarse de que es un widget dibujable */
if (GTK_WIDGET_DRAWABLE (widget))
{
graph = GTK_GRAPH (widget);
if (graph->num_values == 0)
{
return;
}
/* Obtener altura y anchura */
width = widget->allocation.width -1;
height = widget->allocation.height -1;
/* Calcular anchura de las columnas */
column_width = width / graph->num_values;
/* Encontrar valor maximo */
for (i = 0; i < graph->num_values; i++)
{
if (max < graph->values[i])
{
max = graph->values[i];
}
}
for (i = 0; i < graph->num_values; i++)
{
bar_height = (graph->values[i] * height) / max;
gdk_draw_rectangle (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], TRUE, (i * column_width), height - bar_height, (column_width-2), bar_height);
}
}
}
/*
* gtk_graph_size_request
*
* ¿de que tamaño debe ser el widget?
* Puede modificarse
*/
static void gtk_graph_size_request (GtkWidget *widget, GtkRequisition *req)
{
req->width = 100;
req->height = 100;
}
/*
* gtk_graph_expose
*
* El widget de grafica ha quedado expuesto y debe redibujarse
*/
static gint gtk_graph_expose (GtkWidget *widget, GdkEventExpose *event)
{
GtkGraph *graph;
/* Realizar comprobacion de errores */
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_GRAPH (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
if (event->count > 0)
{
return (FALSE);
}
/* Obtener el widget de grafica */
graph = GTK_GRAPH (widget);
/* Borrar la ventana */
gdk_window_clear_area (widget->window, 0, 0, widget->allocation.width, widget->allocation.height);
/* Dibujar la grafica */
gtk_graph_draw (widget, NULL);
return(FALSE);
}
/*
* gtk_graph_destroy
*
* Destruir el widget y liberar la memoria asiganada.
* Despues, invocar funcion de destruccion del padre,
* para asegurarse de que libera la memoria asignada
* por este.
*/
static void gtk_graph_destroy (GtkObject *object)
{
GtkGraph *graph;
/* Comprobar tipo */
g_return_if_fail (object != NULL);
g_return_if_fail (GTK_IS_GRAPH (object));
/* Convertir en objeto de grafica */
graph = GTK_GRAPH (object);
/* Liberar memoria */
g_free (graph->values);
/* Invocar destruccion del padre */
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
__________________ Usuario registrado de Linux #288725 |