unit ButtonWidget;
interface
uses glib2, gdk2pixbuf, gdk2, gtk2, Cairo, ButtonWidgetHeader in
'/home/yarik/Desktop/ButtonWidgetUnit(Incorrectly)/' +
'ButtonWidgetHeader.pp',
Header in
'/home/yarik/Desktop/Zhuzhculator/Prog/Units/Header/Header.pp';
function gtk_button_widget_new(pathnorm, pathhover,
pathpress, pathmask : PathArr;
width, height : integer) : PGtkWidget;
implementation
procedure gtk_button_widget_class_init(class : PGtkButtonWidgetClass);
cdecl; forward;
procedure gtk_button_widget_init(button_widget : PGtkButtonWidget);
cdecl; forward;
procedure move_cursor(widget : PGtkWidget; event : PGdkEventCrossing;
user_data : gpointer);cdecl; forward;
procedure press_cursor(widget : PGtkWidget; event : PGdkEventButton;
user_data : gpointer);cdecl; forward;
procedure gtk_button_widget_unrealize(widget : PGtkWidget); cdecl; forward;
procedure gtk_button_widget_update(button_widget : PGtkButtonWidget);
forward;
procedure button_context_create(button_widget : PGtkButtonWidget;
width, height : integer); forward;
procedure button_images_init(); forward;
type
button_signals = (PRESS_BUTTON_SIGNAL, RELEASE_BUTTON_SIGNAL);
button_images = (image_button_normal, image_button_hovered,
image_button_pressed, image_button_mask);
button_pathes = (path_button_normal, path_button_hovered,
path_button_pressed, path_button_mask);
var
date_type : GType = 0;
button_widget_signals : array [button_signals] of guint = (0, 0);
button_widget_images : array [button_images] of Pcairo_surface_t;
button_widget_pathes : array [button_pathes] of PathArr;
parent_class : PGtkWidgetClass = nil;
function gtk_button_get_type() : GType;
const
date_info : TGTypeInfo =
(class_size : SizeOf(TGtkButtonWidgetClass);
base_init : nil;
base_finalize : nil;
class_init : TGClassInitFunc (@gtk_button_widget_class_init);
class_finalize : nil;
class_data : nil;
instance_size : SizeOf(TGtkButtonWidget);
n_preallocs : 0;
instance_init : TGInstanceInitFunc (@gtk_button_widget_init););
begin
if (date_type = 0) then
date_type := g_type_register_static(
GTK_TYPE_EVENT_BOX, 'GtkButtonWidget', @date_info, 0
);
gtk_button_get_type := date_type;
end;
procedure gtk_button_widget_class_init(class : PGtkButtonWidgetClass);cdecl;
var
widget_class : PGtkWidgetClass;
begin
widget_class := GTK_WIDGET_CLASS(class);
widget_class^.unrealize := @gtk_button_widget_unrealize;
button_widget_signals[PRESS_BUTTON_SIGNAL] :=
g_signal_new(
'press_button',
G_OBJECT_CLASS_TYPE(G_OBJECT_CLASS(class)),
G_SIGNAL_RUN_FIRST,
@class^.press_button - pointer(class),
nil,
nil,
@g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
button_widget_signals[RELEASE_BUTTON_SIGNAL] :=
g_signal_new(
'release_button',
G_OBJECT_CLASS_TYPE(G_OBJECT_CLASS(class)),
G_SIGNAL_RUN_FIRST,
@class^.release_button - pointer(class),
nil,
nil,
@g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
end;
procedure gtk_button_widget_init(button_widget : PGtkButtonWidget);cdecl;
begin
button_widget^.state := state_button_normal;
button_widget^.drawing_box := gtk_drawing_area_new();
gtk_widget_realize(GTK_WIDGET(button_widget));
button_widget^.drawing_box^.window :=
gdk_window_new(GTK_WIDGET(button_widget)^.window, nil, 0);
gtk_widget_realize(button_widget^.drawing_box);
gtk_widget_show(button_widget^.drawing_box);
gtk_container_add(GTK_CONTAINER(button_widget),
button_widget^.drawing_box);
gtk_widget_set_events (GTK_WIDGET(button_widget), GDK_ENTER_NOTIFY_MASK
or GDK_LEAVE_NOTIFY_MASK);
g_signal_connect (G_OBJECT(button_widget),
'button-press-event',
G_CALLBACK(@press_cursor), nil);
g_signal_connect (G_OBJECT(button_widget),
'button-release-event',
G_CALLBACK(@press_cursor), nil);
g_signal_connect (G_OBJECT(button_widget),
'enter-notify-event',
G_CALLBACK(@move_cursor), nil);
g_signal_connect (G_OBJECT(button_widget),
'leave-notify-event',
G_CALLBACK(@move_cursor), nil);
end;
procedure move_cursor(widget : PGtkWidget; event : PGdkEventCrossing;
user_data : gpointer);cdecl;
//const
// hand_cursor : PGdkCursor = nil;
begin
if (event^._type = GDK_ENTER_NOTIFY) then
begin
// if (hand_cursor = nil) then
// begin
// hand_cursor := gdk_cursor_new(GDK_HAND2);
// gdk_window_set_cursor(widget^.window, hand_cursor)
// end;
GTK_BUTTON_WIDGET(widget)^.state := state_button_hovered;
gtk_widget_queue_draw(GTK_BUTTON_WIDGET(widget)^.drawing_box);
end;
if (event^._type = GDK_LEAVE_NOTIFY) then
begin
GTK_BUTTON_WIDGET(widget)^.state := state_button_normal;
gtk_widget_queue_draw(GTK_BUTTON_WIDGET(widget)^.drawing_box);
end;
gtk_button_widget_update(GTK_BUTTON_WIDGET(widget));
end;
procedure press_cursor(widget : PGtkWidget; event : PGdkEventButton;
user_data : gpointer);cdecl;
begin
if (event^._type = GDK_BUTTON_PRESS) then
begin
g_signal_emit(GTK_BUTTON_WIDGET(widget),
button_widget_signals[PRESS_BUTTON_SIGNAL], 0);
GTK_BUTTON_WIDGET(widget)^.state := state_button_pressed;
gtk_widget_queue_draw(GTK_BUTTON_WIDGET(widget)^.drawing_box);
end;
if (event^._type = GDK_BUTTON_RELEASE) then
begin
g_signal_emit(GTK_BUTTON_WIDGET(widget),
button_widget_signals[RELEASE_BUTTON_SIGNAL], 0);
GTK_BUTTON_WIDGET(widget)^.state := state_button_hovered;
end;
gtk_button_widget_update(GTK_BUTTON_WIDGET(widget));
end;
procedure gtk_button_widget_unrealize(widget : PGtkWidget);cdecl;
var
button_widget : PGtkButtonWidget;
begin
if(widget = nil) then;
exit;
if(GTK_IS_BUTTON_WIDGET(widget) = false) then
exit;
button_widget := GTK_BUTTON_WIDGET(widget);
if(button_widget^.drawing_box <> nil) then
g_free(button_widget^.drawing_box);
if(GTK_OBJECT_CLASS(parent_class)^.destroy <> nil) then
GTK_OBJECT_CLASS(parent_class)^.destroy(GTK_OBJECT(widget))
end;
function gtk_button_widget_new(pathnorm, pathhover,
pathpress, pathmask : PathArr;
width, height : integer) : PGtkWidget;
var
button_widget : PGtkButtonWidget;
begin
button_widget :=
g_object_new(GTK_TYPE_BUTTON_WIDGET, nil);
button_widget_pathes[path_button_normal] := pathnorm;
button_widget_pathes[path_button_hovered] := pathhover;
button_widget_pathes[path_button_pressed] := pathpress;
button_widget_pathes[path_button_mask] := pathmask;
button_images_init();
button_context_create(button_widget, width, height);
gtk_button_widget_update(button_widget);
gtk_button_widget_new := GTK_WIDGET(button_widget);
end;
procedure button_images_init();
begin
button_widget_images[image_button_normal] :=
cairo_image_surface_create_from_png(
@button_widget_pathes[path_button_normal]);
button_widget_images[image_button_hovered] :=
cairo_image_surface_create_from_png(
@button_widget_pathes[path_button_hovered]);
button_widget_images[image_button_pressed] :=
cairo_image_surface_create_from_png(
@button_widget_pathes[path_button_pressed]);
button_widget_images[image_button_mask] :=
cairo_image_surface_create_from_png(
@button_widget_pathes[path_button_mask]);
end;
procedure button_context_create(button_widget : PGtkButtonWidget;
width, height : integer);
var
mask_pixmap : PGdkPixmap;
context : Pcairo_t;
begin
mask_pixmap := gdk_pixmap_new(nil, width, height, 1);
context := gdk_cairo_create(mask_pixmap);
cairo_set_source_surface(context, button_widget_images[image_button_mask],
0, 0);
cairo_paint(context);
cairo_destroy(context);
gtk_widget_shape_combine_mask(button_widget^.drawing_box,
mask_pixmap, 0, 0);
gtk_widget_set_size_request(button_widget^.drawing_box,
width, height);
end;
procedure gtk_button_widget_update(button_widget : PGtkButtonWidget);
var
cr : Pcairo_t;
begin
cr := gdk_cairo_create(button_widget^.drawing_box^.window);
case button_widget^.state of
state_button_normal:
cairo_set_source_surface(cr,
button_widget_images[image_button_normal], 0, 0);
state_button_hovered:
cairo_set_source_surface(cr,
button_widget_images[image_button_hovered], 0, 0);
state_button_pressed:
cairo_set_source_surface(cr,
button_widget_images[image_button_pressed], 0, 0);
end;
cairo_paint(cr);
cairo_destroy(cr);
end;
end.