该控件共有三个文件myipaddress.c、myipaddress.h、test.c文件
********************** myipaddress.h ******************************
#ifndef __MY_IP_ADDRESS_H__
#define __MY_IP_ADDRESS_H__
#include
#include
#include
G_BEGIN_DECLS
#define MY_IP_ADDRESS_TYPE (my_ip_address_get_type ())
#define MY_IP_ADDRESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
MY_IP_ADDRESS_TYPE, MyIPAddress))
#define MY_IP_ADDRESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
MY_IP_ADDRESS_TYPE, MyIPAddressClass))
#define IS_MY_IP_ADDRESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
MY_IP_ADDRESS_TYPE))
#define IS_MY_IP_ADDRESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
MY_IP_ADDRESS_TYPE))
typedef struct _MyIPAddress MyIPAddress;
typedef struct _MyIPAddressClass MyIPAddressClass;
struct _MyIPAddress
{
GtkEntry entry;
};
struct _MyIPAddressClass
{
GtkEntryClass parent_class;
void (* ip_changed) (MyIPAddress *ipaddress);
};
GType my_ip_address_get_type(void);
static void my_ip_address_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *pspec);
static void my_ip_address_class_init (MyIPAddressClass *klass);
static void my_ip_address_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *pspec);
static void my_ip_address_init (MyIPAddress *ipaddress);
static void my_ip_address_render(MyIPAddress *ipaddress);
static void my_ip_address_move_cursor(GObject *entry,GParamSpec *spec);
static gboolean my_ip_address_key_pressed(GtkEntry *entry,GdkEventKey *event);
GtkWidget *my_ip_address_new();
gchar *my_ip_address_get_address(MyIPAddress *ipaddress);
void my_ip_address_set_address(MyIPAddress *ipaddress,gint address[4]);
G_END_DECLS
#endif
********************** myipaddress.c ******************************
#include
#include
#include
#include
#include "myipaddress.h"
#define MY_IP_ADDRESS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),MY_IP_ADDRESS_TYPE,MyIPAddressPrivate))
typedef struct _MyIPAddressPrivate
{
guint address[4];
};
enum
{
CHANGED_SIGNAL,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_IP1,
PROP_IP2,
PROP_IP3,
PROP_IP4
};
typedef struct _MyIPAddressPrivate MyIPAddressPrivate;
static guint my_ip_address_signals[LAST_SIGNAL] = {0};
GType my_ip_address_get_type(void)
{
static GType entry_type = 0;
if (!entry_type)
{
static const GTypeInfo entry_info =
{
sizeof (MyIPAddressClass),
NULL,
NULL,
(GClassInitFunc)my_ip_address_class_init,
NULL,
NULL,
sizeof(MyIPAddress),
0,
(GInstanceInitFunc)my_ip_address_init,
};
entry_type = g_type_register_static(GTK_TYPE_ENTRY, "MyIPAddress",&entry_info, 0);
}
return entry_type;
}
static void my_ip_address_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *pspec)
{
MyIPAddress *ipaddress = MY_IP_ADDRESS(object);
gint address[4] = {-1, -1, -1, -1};
switch(prop_id)
{
case PROP_IP1:
address[0] = g_value_get_int(value);
my_ip_address_set_address(ipaddress,address);
break;
case PROP_IP2:
address[1] = g_value_get_int(value);
my_ip_address_set_address(ipaddress,address);
break;
case PROP_IP3:
address[2] = g_value_get_int(value);
my_ip_address_set_address(ipaddress,address);
break;
case PROP_IP4:
address[3] = g_value_get_int(value);
my_ip_address_set_address(ipaddress,address);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object,prop_id,pspec);
break;
}
}
static void my_ip_address_class_init (MyIPAddressClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = my_ip_address_set_property;
gobject_class->get_property = my_ip_address_get_property;
g_type_class_add_private (klass, sizeof (MyIPAddressPrivate));
my_ip_address_signals[CHANGED_SIGNAL] =
g_signal_new ("ip-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (MyIPAddressClass, ip_changed),
NULL, NULL,g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
g_object_class_install_property (gobject_class, PROP_IP1,
g_param_spec_int ("ip-number-1",
"IP Address Number 1",
"The first IP address number",
0, 255, 0,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_IP2,
g_param_spec_int ("ip-number-2",
"IP Address Number 2",
"The second IP address number",
0, 255, 0,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_IP3,
g_param_spec_int ("ip-number-3",
"IP Address Number 3",
"The third IP address number",
0, 255, 0,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_IP4,
g_param_spec_int ("ip-number-4",
"IP Address Number 1",
"The fourth IP address number",
0, 255, 0,
G_PARAM_READWRITE));
}
#define G_SIGNAL_OFFSET(struct_type,member) ((glong)((guint8*) &((struct_type*)0)->member))
void (*callback)(gpointer instance,gpointer data);
void (*callback)(gpointer instance,gboolean arg,gpointer data);
static void my_ip_address_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *pspec)
{
MyIPAddress *ipaddress = MY_IP_ADDRESS(object);
MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);
switch(prop_id)
{
case PROP_IP1:
g_value_set_int(value,priv->address[0]);
break;
case PROP_IP2:
g_value_set_int(value,priv->address[1]);
break;
case PROP_IP3:
g_value_set_int(value,priv->address[2]);
break;
case PROP_IP4:
g_value_set_int(value,priv->address[3]);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object,prop_id,pspec);
break;
}
}
static void my_ip_address_init (MyIPAddress *ipaddress)
{
MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE (ipaddress);
PangoFontDescription *fd;
guint i;
for (i = 0; i < 4; i++)
priv->address[i] = 0;
fd = pango_font_description_from_string ("Monospace");
gtk_widget_modify_font (GTK_WIDGET (ipaddress), fd);
my_ip_address_render (ipaddress);
pango_font_description_free (fd);
g_signal_connect (G_OBJECT (ipaddress), "key-press-event",G_CALLBACK (my_ip_address_key_pressed), NULL);
g_signal_connect (G_OBJECT (ipaddress), "notify::cursor-position",G_CALLBACK (my_ip_address_move_cursor), NULL);
}
static void my_ip_address_render(MyIPAddress *ipaddress)
{
MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);
GString *text;
gint i;
text = g_string_new(NULL);
for(i=0; i<4; i++)
{
gchar *temp = g_strdup_printf("%3i.",priv->address[i]);
text = g_string_append(text,temp);
g_free(temp);
}
text = g_string_truncate(text,15);
gtk_entry_set_text(GTK_ENTRY(ipaddress),text->str);
g_string_free(text,TRUE);
}
static void my_ip_address_move_cursor(GObject *entry,GParamSpec *spec)
{
gint cursor = gtk_editable_get_position(GTK_EDITABLE(entry));
if(cursor <= 3)
{
gtk_editable_set_position(GTK_EDITABLE(entry),3);
}
else if(cursor <= 7)
{
gtk_editable_set_position(GTK_EDITABLE(entry),7);
}
else if(cursor <= 11)
{
gtk_editable_set_position(GTK_EDITABLE(entry),11);
}
else
gtk_editable_set_position(GTK_EDITABLE(entry),15);
}
static gboolean my_ip_address_key_pressed(GtkEntry *entry,GdkEventKey *event)
{
MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(entry);
guint k = event->keyval;
gint cursor,value;
if((k >= GDK_0 && k <= GDK_9) || (k >= GDK_KP_0 && k <= GDK_KP_9))
{
cursor = floor(gtk_editable_get_position(GTK_EDITABLE(entry))/4);
value = g_ascii_digit_value(event->string[0]);
if((priv->address[cursor] == 25) && (value > 5))
return TRUE;
if(priv->address[cursor] < 26)
{
priv->address[cursor] *= 10;
priv->address[cursor] += value;
my_ip_address_render(MY_IP_ADDRESS(entry));
gtk_editable_set_position(GTK_EDITABLE(entry),(4 * cursor) + 3);
g_signal_emit_by_name((gpointer)entry,"ip-changed");
}
}
else if(k == GDK_Tab)
{
cursor = (gint)(floor(gtk_editable_get_position(GTK_EDITABLE(entry))/4)+1);
gtk_editable_set_position(GTK_EDITABLE(entry),(4 * (cursor%4)) + 3);
}
else if(k == GDK_BackSpace)
{
cursor = (gint)floor(gtk_editable_get_position(GTK_EDITABLE(entry))/4);
priv->address[cursor] /= 10;
my_ip_address_render(MY_IP_ADDRESS(entry));
gtk_editable_set_position(GTK_EDITABLE(entry),(4*cursor)+3);
g_signal_emit_by_name((gpointer)entry,"ip-changed");
}
else if((k == GDK_Return) || (k == GDK_KP_Enter))
gtk_widget_activate(GTK_WIDGET(entry));
return TRUE;
}
GtkWidget *my_ip_address_new()
{
return GTK_WIDGET(g_object_new(my_ip_address_get_type(),NULL));
}
char *my_ip_address_get_address(MyIPAddress *ipaddress)
{
MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);
return g_strdup_printf("%d.%d.%d.%d",priv->address[0],priv->address[1],
priv->address[2],priv->address[3]);
}
void my_ip_address_set_address(MyIPAddress *ipaddress,gint address[4])
{
MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);
guint i;
for(i=0; i<4; i++)
{
if(address[i] >= 0 && address[i] <= 255)
{
priv->address[i] = address[i];
}
}
my_ip_address_render(ipaddress);
g_signal_emit_by_name((gpointer)ipaddress,"ip-changed");
}
********************** test.c ******************************
#include
#include "myipaddress.h"
static void ip_address_changed(MyIPAddress* ipaddress);
int main(int argc,char *argv[])
{
GtkWidget *window,*ipaddress;
gtk_init(&argc,&argv);
gint address[4] = {0,0,0,0};
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"MyIPAddress");
ipaddress = my_ip_address_new();
my_ip_address_set_address(MY_IP_ADDRESS(ipaddress),address);
g_signal_connect(G_OBJECT(ipaddress),"ip-changed",G_CALLBACK(ip_address_changed),NULL);
gtk_container_add(GTK_CONTAINER(window),ipaddress);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
static void ip_address_changed(MyIPAddress* ipaddress)
{
gchar *address = my_ip_address_get_address(ipaddress);
g_print("%s\n",address);
g_free(address);
}
网友评论