рдорд╛рдЙрд╕ рдЪрд╛рд▓рд┐рдд рд╡рд┐рдЧреЗрдЯреНрд╕ред рдЦрд┐рдбрд╝рдХреА рдХреЗ рднреАрддрд░ рдЦреАрдВрдЪреЗрдВ рдФрд░ рдЫреЛрдбрд╝реЗрдВ

рдбреНрд░реИрдЧ рдПрдВрдб рдбреНрд░реЙрдк (рдбреА рдПрдВрдб рдбреА) рдХреА рд╕рд╛рдорд╛рдиреНрдп рд╕рдордЭ рдпрд╣ рдорд╛рдирддреА рд╣реИ рдХрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд▓рд┐рдВрдХ рдПрдХ рд╡рд┐рдЬреЗрдЯ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдорд╛рдЙрд╕ рдХреЗ рд╕рд╛рде рджреВрд╕рд░реА рд╡рд┐рдВрдбреЛ рдпрд╛ рд╡рд┐рдЬреЗрдЯ рдореЗрдВ рд▓реЗ рдЬрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдЧрд▓рд╛, рд╣рдо рдбреА рдПрдВрдб рдбреА рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЦрд┐рдбрд╝рдХреА рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рднреАрддрд░ рд╡рд┐рдЬреЗрдЯ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред рдХреЛрдб рдареЛрд╕ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╣реИ, рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╕реА рд╢реИрд▓реА рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред рд╕рдВрдкрд╛рджрдХ рдХреЛрдбрдмреНрд▓реЙрдХ 17.12 рд╣реИ, рдЬреЛ 16 рд╡реЗрдВ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЙрдмрдВрдЯреВ x64 рдкрд░ рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рдЧрдпрд╛ред

рдЫрд╡рд┐

рдПрдХ рд╡рд┐рдЬреЗрдЯ рдХрдВрдЯреЗрдирд░ GtkFixed рд╣реИ, рдЬреЛ рдХреБрдЫ рд╡рд┐рдЬреЗрдЯреНрд╕ рдХреЛ рдХреБрдЫ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдкрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, GTK рдкрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХреА рдХреНрд▓рд╛рд╕рд┐рдХ рдЕрд╡рдзрд╛рд░рдгрд╛ рдореЗрдВ рд╡рд┐рдВрдбреЛ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдлреИрд▓рд╛рдиреЗ рдФрд░ рд╕реНрдерд╛рди рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдЬреЗрдЯ рдХрдВрдЯреЗрдирд░ GtkBox (рдФрд░ рдЕрдиреНрдп) рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИред рдХрдВрдЯреЗрдирд░ рдпрд╛ рддреЛ рдЦрд┐рдбрд╝рдХреА рдХреЗ рдЖрдХрд╛рд░ рддрдХ рдлреИрд▓рд╛ рд╣реБрдЖ рд╣реИ (рдФрд░ рдЕрдиреНрдп рд╡рд┐рдЬреЗрдЯ рдХреА рд╕реАрдорд╛рдУрдВ рддрдХ), рдпрд╛ рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ рдмрдЪреНрдЪреЗ рдХреЗ рд╡рд┐рдЬреЗрдЯ рдХреЗ рдЖрдХрд╛рд░ рддрдХ рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдХреЛрдб main.cpp, main.hpp, movable_widgets.hpp рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИред рдореИрдВрдиреЗ рдЕрд▓рдЧ рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЪрдпрди рдирд╣реАрдВ рдХрд┐рдпрд╛ред Main.cpp рдХреА рд╕рд╛рдордЧреНрд░реА рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ:

#include "main.hpp" #include "movable_widgets.hpp" void builder_init(gpointer user_data) { appdata *data=(appdata*) user_data; GError *error = NULL; GtkBuilder *builder = gtk_builder_new(); if (!gtk_builder_add_from_file (builder, "window.glade", &error)) { //     g_critical ("   : %s", error->message); g_error_free (error); } data->win=GTK_WIDGET(gtk_builder_get_object(builder, "window1")); data->notebook=GTK_NOTEBOOK(gtk_builder_get_object(builder, "notebook1")); gtk_notebook_remove_page(data->notebook,0); ///    gtk_builder_connect_signals (builder,data); g_clear_object(&builder); } void application_activate(GtkApplication *application, gpointer user_data) { appdata *data=(appdata*) user_data; builder_init(data); gtk_widget_set_size_request(data->win,320,240); gtk_application_add_window(data->app,GTK_WINDOW(data->win)); page_body *page=new page_body(data, G_OBJECT(data->notebook)); const gchar *text ="<span foreground=\"blue\" size=\"x-large\">Blue text</span>" ; GtkWidget *label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (label), text); GtkWidget *image=gtk_image_new_from_file("opennet2.gif"); GtkWidget *image2=gtk_image_new_from_file("n_temp.png"); page->add_widget(label,label_t,10,10); page->add_widget(image,image_t,20,20); page->add_widget(image2,image_t,40,40); gtk_widget_show_all(data->win); } void application_shutdown(const GtkApplication *application, gpointer user_data) {} int main (int argc, char *argv[]) { appdata data; gtk_init (&argc, &argv); gint res; data.app = gtk_application_new("gtk3.org", G_APPLICATION_FLAGS_NONE); g_signal_connect(data.app, "activate", G_CALLBACK(application_activate), &data); g_signal_connect(data.app, "shutdown", G_CALLBACK(application_shutdown), &data); res = g_application_run(G_APPLICATION(data.app), 0, NULL); return 0; } 

рдХреБрдЫ рд╡рд┐рдЧреЗрдЯреНрд╕ рдПрдХ XML рд╡рд┐рд╡рд░рдг (рдлрд╝рдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░_рдЗрдирд┐рдЯ) рд╕реЗ рдмрдирд╛рдП рдЧрдП рд╣реИрдВ, рджреВрд╕рд░рд╛ рднрд╛рдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдореЗрдЯрд┐рдХрд▓реА (рдкреЗрдЬ-> add_widget)ред Gtk_widget_show_all рдлрд╝рдВрдХреНрд╢рди (рдбреЗрдЯрд╛-> рдЬреАрдд); рд╡рд┐рдЧреЗрдЯреНрд╕ рдФрд░ рдЙрдирдХреА рд╕рд╛рдордЧреНрд░реА рдХреЗ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХред рдЬреАрдЯреАрдХреЗ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд╡рд┐рдЧреЗрдЯреНрд╕ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИ рдЬрдм рд╡реЗ рд╣рдЯрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЕрдиреНрдп рдЪрд╛рдЗрд▓реНрдб рд╡рд┐рдЬреЗрдЯ рдореЗрдВред рдЬрдм рддрдХ application_shutdown рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рддрдм рддрдХ рдореБрдЦреНрдп рд╡рд┐рдВрдбреЛ рдФрд░ рд╕рднреА рд╕рд╛рдордЧреНрд░реА рд╡рд┐рдЬреЗрдЯ рдкрд╣рд▓реЗ рд╣реА рд╣рдЯрд╛ рджрд┐рдП рдЧрдП рд╣реИрдВред

 #ifndef MAIN_H #define MAIN_H #include <gtk/gtk.h> #include <stdbool.h> #include <stdlib.h> #define restrict __restrict__ class appdata { public: char *glade_name=(char*)"window.glade"; GtkApplication *restrict app; GtkWidget *restrict win; GtkNotebook *restrict notebook; GArray *restrict pages; }; #endif 

рдкреГрд╖реНрда рдлрд╝реАрд▓реНрдб рдкреГрд╖реНрдареЛрдВ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА рд╣реИ, рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ 1 рдЯреИрдм рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдПрдХ рд╢реМрдХрд┐рдпрд╛ рд╣реИред рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ, рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╡реГрджреНрдзрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЙрдкрдпреЛрдЧ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рд╕рдореНрдорд┐рд▓рд┐рдд рд╡рд┐рдЬреЗрдЯ рдХреЛ GtkEventBox рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред рд╡рд╣ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ
buttonclickред рдмрд╛рдИрдВ рдорд╛рдЙрд╕ рдмрдЯрди рдХреЛ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╕рдордп рдлрд╝реНрд░реЗрдо рдореЗрдВ рд╡рд┐рдЬреЗрдЯ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП GtkFrame рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдХрдВрдЯреЗрдирд░ рднреАред рдХрдВрдЯреЗрдирд░ рдкрд░рд┐рд╡рд░реНрддрди рдСрдкрд░реЗрд╢рди рдХрд╛рдлреА рддреЗрдЬ рд╣реИред рдЯреИрдм рд╣реА, рдЬрд╣рд╛рдБ рд╡рд┐рдЬреЗрдЯреНрд╕ рдбрд╛рд▓реЗ рдЧрдП рд╣реИрдВ, рдореЗрдВ рд╕рдВрд▓рдЧреНрдирдХ рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрджрд╛рдиреБрдХреНрд░рдо рд╣реИ: GtkScrolledWindow-> GtkViewport-> GtkFixedред рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рд╡рд┐рдЬреЗрдЯ рдкреНрд░рдХрд╛рд░ GtkWidget рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рдореИрдХреНрд░реЛрдЬрд╝ рджреНрд╡рд╛рд░рд╛ GtkViewport, GtkFixed рдХреЗ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВ рдЬреЛрд░ рджреВрдВрдЧрд╛
рдореИрдХреНрд░реЛ рд╡реНрдпреВ рдкрд░ рдзреНрдпрд╛рди
InsertedWidgetWithProperty * widget_with_property = & g_array_index (рд╡рд┐рдЬреЗрдЯ, InsertedWidgetWithProperty, i);
рдЪреВрдВрдХрд┐ рдпрд╣рд╛рдВ рдЧрд▓рддреА рдХрд░рдирд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╣реИред рдкреИрд░рд╛рдореАрдЯрд░ x_correction, y_correction - рдорд╛рдЙрд╕ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕рдореНрдорд┐рд▓рд┐рдд рд╡рд┐рдЬреЗрдЯ GtkEvent рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВред Button_not_pressed рдзреНрд╡рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдлрд╝реНрд░реЗрдо рдХрдВрдЯреЗрдирд░ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддрд░реНрдХ рд╕реЗ, рдпрд╣ рд╕рдордЭрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рдорд╛рдЙрд╕ рдмрдЯрди рдореЗрдВ рд╕реЗ рдПрдХ рд╕рдореНрдорд┐рд▓рд┐рдд рд╡рд┐рдЬреЗрдЯ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдПрдХ рдлреНрд░реЗрдо рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╛рдиреА, рдмрдЯрди-рдХреНрд▓рд┐рдХ рдФрд░ рдмрдЯрдирд░реЗрд▓ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рджрд░реНрдЬ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдВрдЯрд░-рдиреЛрдЯрд┐рдлрд╝рд┐рдХреЗрд╢рди-рдЗрд╡реЗрдВрдЯ рдФрд░ рд▓реАрд╡-рдиреЛрдЯрд┐рдлрд╝рд┐рдХреЗрд╢рди-рдЗрд╡реЗрдВрдЯ рдИрд╡реЗрдВрдЯ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬреЛ рдХрд░реНрд╕рд░ рдХреЗ рдЖрдХрд╛рд░ рдореЗрдВ рдмрджрд▓рд╛рд╡ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реЛрддреЗ рд╣реИрдВред рдпрджрд┐ x_correction, рдмрдЯрди_not_pressed рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗрд╡рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН, рдЙрдиреНрд╣реЗрдВ рдирд┐рдЬреА рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдмрд╛рдХреА рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рд╡рд░реНрддрдорд╛рди рд╡рд┐рдЬреЗрдЯ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд┐рдХ_рдСрд░реНрдбрд░ рдзреНрд╡рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

 typedef struct { GtkWidget *restrict widget_ptr; GtkWidget *restrict eventbox; GtkWidget *restrict frame; //   GtkWidget *restrict pmenu; widget_type type; bool button_not_pressed; } InsertedWidgetWithProperty; class page_body { public: GtkWidget *restrict scrolledwindow; GtkWidget *restrict viewport; GtkWidget *restrict fixed; GArray *restrict widgets=g_array_new(FALSE, TRUE, sizeof(InsertedWidgetWithProperty)); GtkAdjustment *restrict h_adj; GtkAdjustment *restrict v_adj; int num_of_current_widget=0; double x_correction=0; double y_correction=0; GtkWidget *restrict window; ///      int widget_count=0; bool click_order=FALSE; //TRUE -  page_body(appdata *data, GObject *container) { window=data->win; h_adj=gtk_adjustment_new(0.0,4.0,900.0,1.0,5.0,10.0); v_adj=gtk_adjustment_new(0.0,4.0,900.0,1.0,5.0,10.0); scrolledwindow=gtk_scrolled_window_new(h_adj, v_adj); viewport=gtk_viewport_new(h_adj, v_adj); fixed=gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(scrolledwindow),GTK_WIDGET(viewport)); gtk_container_add(GTK_CONTAINER(viewport),GTK_WIDGET(fixed)); if(GTK_IS_NOTEBOOK(container)) { gtk_notebook_append_page ((GtkNotebook*)container,scrolledwindow,NULL); } else if(GTK_IS_WIDGET(container)) { gtk_container_add(GTK_CONTAINER(container),scrolledwindow); } g_signal_connect(fixed,"motion-notify-event",G_CALLBACK(fixed_motion_notify), this); g_signal_connect(scrolledwindow,"destroy",G_CALLBACK(scrolled_window_destroy_cb), this); } ~page_body() { int i=widgets->len; if(widget_count>0) { for(i; i>=0; i--) { InsertedWidgetWithProperty *widget_with_property; widget_with_property=&g_array_index(widgets,InsertedWidgetWithProperty,i); } } g_array_free(widgets,TRUE); } void add_widget(GtkWidget *widget, widget_type type, int x, int y) { ++widget_count; InsertedWidgetWithProperty *widget_with_property=(InsertedWidgetWithProperty*) g_malloc0(sizeof(InsertedWidgetWithProperty)); widget_with_property->eventbox=gtk_event_box_new(); widget_with_property->type=type; widget_with_property->widget_ptr=widget; gtk_container_add(GTK_CONTAINER(widget_with_property->eventbox),widget); gtk_fixed_put(GTK_FIXED(fixed),widget_with_property->eventbox,x,y); widget_with_property->pmenu=gtk_menu_new(); GtkWidget *menu_items = gtk_menu_item_new_with_label (""); gtk_widget_show(menu_items); gtk_menu_shell_append (GTK_MENU_SHELL (widget_with_property->pmenu), menu_items); g_signal_connect(widget_with_property->eventbox,"button-press-event",G_CALLBACK(eventbox_press_cb),this); g_signal_connect(widget_with_property->eventbox,"button-release-event",G_CALLBACK(eventbox_release_cb),this); g_signal_connect(menu_items,"activate",G_CALLBACK(menu_delete_activate),this); g_signal_connect(widget_with_property->eventbox,"leave-notify-event",G_CALLBACK(eventbox_leave_cb),this); g_signal_connect(widget_with_property->eventbox,"enter-notify-event",G_CALLBACK(eventbox_enter_cb),this); gtk_widget_set_events(widget_with_property->eventbox,GDK_LEAVE_NOTIFY_MASK|GDK_ENTER_NOTIFY_MASK|GDK_STRUCTURE_MASK); g_array_append_val(widgets, *widget_with_property); } inline void change_cursor(char *cursor_name) { GdkDisplay *display; GdkCursor *cursor; display = gtk_widget_get_display (window); if(cursor_name) cursor = gdk_cursor_new_from_name (display, cursor_name); else cursor = gdk_cursor_new_from_name (display, "default"); GdkWindow *gdkwindow=gtk_widget_get_window (window); gdk_window_set_cursor (gdkwindow, cursor); } inline void delete_widget(int i) { InsertedWidgetWithProperty *widget_with_property= &g_array_index(this->widgets,InsertedWidgetWithProperty,i); GtkWidget *eventbox=widget_with_property->eventbox; g_object_ref(eventbox); gtk_container_remove(GTK_CONTAINER(this->fixed),eventbox); if(widget_with_property->frame!=NULL) { gtk_widget_destroy(widget_with_property->frame); } gtk_widget_destroy(widget_with_property->eventbox); this->widgets=g_array_remove_index_fast(this->widgets,i); --this->widget_count; } }; 

рд╡рд┐рдЬреЗрдЯ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХрд╛ рд╕реВрддреНрд░ рддрд╛рдХрд┐ рдЖрдк рдЙрд╕ рдкрд░ рдорд╛рдЙрд╕ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдкрд░ рдХрд┐рд╕реА рднреА рджрд┐рд╢рд╛ рдореЗрдВ рди рдЪрд▓реЗрдВред рдЗрд╕рдореЗрдВ рд╡рд┐рдЬреЗрдЯ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдХреНрд▓рд┐рдХ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ,
GtkFixed рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╡рд┐рдВрдбреЛ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рдордиреНрд╡рдп рдХрд░рддрд╛ рд╣реИ, рд╡рд┐рдВрдбреЛ рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рдордиреНрд╡рдп рдХрд░рддрд╛ рд╣реИред
рдХрд░реЗрдХреНрд╢рди рдлреИрдХреНрдЯрд░ 5.2 рдореБрдЭреЗ рдХреБрдЫ рд╣рдж рддрдХ рднреНрд░рдорд┐рдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рд▓рд┐рдЦрдирд╛ рдХрд┐рддрдирд╛ рд╕рд░рд▓ рд╣реИред рдореИрдВрдиреЗ Ubuntu 15.10, 16.04, 18.04 рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ рдХрд╛рдо рдХреА рдЬрд╛рдБрдЪ рдХреАред 0 рдФрд░ -1 рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ рддрд╛рдХрд┐ рдбрд╛рд▓рд╛ рдЧрдпрд╛ рд╡рд┐рдЬреЗрдЯ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХреНрд╖реЗрддреНрд░ рд╕реЗ рд╣рдЯрд╛рдпрд╛ рди рдЬрд╛рдПред рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рд╕реНрд╡рдпрдВ GtkScrolledWindow рд╡рд┐рдЬреЗрдЯ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╣реИред

 gboolean fixed_motion_notify (GtkWidget *widget, GdkEvent *event, gpointer user_data) { page_body *page=(page_body*) user_data; int x_win, y_win, x_fixed, y_fixed; gtk_window_get_position(GTK_WINDOW(page->window),&x_win,&y_win); gtk_widget_translate_coordinates(page->window,page->fixed,x_win,y_win,&x_fixed,&y_fixed); double correction_y=(-y_fixed+y_win)*2+25; double correction_x=(-x_fixed+x_win); double x_corr=page->x_correction; double y_corr=page->y_correction; int position_x=event->motion.x_root-x_corr-x_win-correction_x; int position_y=event->motion.y_root-y_corr-y_fixed-correction_y; InsertedWidgetWithProperty *widget_with_property=&g_array_index(page->widgets,InsertedWidgetWithProperty,page->num_of_current_widget); GtkWidget *fixed=page->fixed; GtkWidget *eventbox=widget_with_property->eventbox; if(position_x<-1) position_x=0; if(position_y<-1) position_y=0; gtk_fixed_move(GTK_FIXED(fixed), eventbox, position_x, position_y); return FALSE; } 

рдмрд╛рдХреА рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рдиред рд╕рд╣реА рдорд╛рдЙрд╕ рдмрдЯрди рдХреЗ рд╕рд╛рде рд╕рдВрджрд░реНрдн рдореЗрдиреВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╡рд┐рдЧреЗрдЯреНрд╕ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд┐рдпрд╛ред рдкреЗрдЬ_рдмреЙрдбреА рдХреНрд▓рд╛рд╕ рдХреЛ рд╣рдЯрд╛рдХрд░ GtkScrolledWindow рдбрд┐рд▓реАрдЯ рдЗрд╡реЗрдВрдЯ рд╕реЗ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

 void scrolled_window_destroy_cb (GtkWidget *object, gpointer user_data) { page_body *page=(page_body*) user_data; delete page; } void menu_delete_activate (GtkMenuItem *menuitem, gpointer user_data) { page_body *page=(page_body*) user_data; page->delete_widget(page->num_of_current_widget); } gboolean eventbox_leave_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) { page_body *page=(page_body*) user_data; page->change_cursor(NULL); } gboolean eventbox_enter_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) { page_body *page=(page_body*) user_data; page->change_cursor("pointer"); } gboolean eventbox_press_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) { page_body *page=(page_body*) user_data; page->x_correction=event->button.x; page->y_correction=event->button.y; int i=0; InsertedWidgetWithProperty *widget_compare; for(i; i<=page->widgets->len; i++) { widget_compare=(InsertedWidgetWithProperty*) page->widgets->data+i; if(widget==widget_compare->eventbox) { page->num_of_current_widget=i; break; } } if(widget_compare->button_not_pressed==FALSE) { GtkWidget *eventbox=widget_compare->eventbox; if(page->click_order) { int x, y; gtk_widget_translate_coordinates(page->fixed, eventbox,0,0,&x, &y); gtk_container_remove(GTK_CONTAINER(page->fixed),eventbox); gtk_fixed_put(GTK_FIXED(page->fixed),eventbox,-x,-y); } g_object_ref(widget_compare->widget_ptr); gtk_container_remove(GTK_CONTAINER(eventbox),widget_compare->widget_ptr); if(widget_compare->frame==NULL) widget_compare->frame=gtk_frame_new(NULL); gtk_container_add(GTK_CONTAINER(widget_compare->frame),widget_compare->widget_ptr); gtk_container_add(GTK_CONTAINER(eventbox),widget_compare->frame); gtk_widget_show_all(eventbox); widget_compare->button_not_pressed=TRUE; } ///   const gint RIGHT_CLICK = 3; if (event->type == GDK_BUTTON_PRESS) { GdkEventButton *bevent = (GdkEventButton *) event; if (bevent->button == RIGHT_CLICK) { gtk_menu_popup(GTK_MENU(widget_compare->pmenu), NULL, NULL, NULL, NULL, bevent->button, bevent->time); } } return FALSE; } gboolean eventbox_release_cb (GtkWidget *eventbox, GdkEvent *event, gpointer user_data) { page_body *page=(page_body*) user_data; InsertedWidgetWithProperty *widget_with_property= &g_array_index(page->widgets,InsertedWidgetWithProperty,page->num_of_current_widget); ///      ,    if(widget_with_property->button_not_pressed==TRUE) { widget_with_property->frame=(GtkWidget*) g_object_ref(widget_with_property->frame); widget_with_property->widget_ptr=(GtkWidget*) g_object_ref(widget_with_property->widget_ptr); GtkWidget *frame=widget_with_property->frame; GtkWidget *widget=widget_with_property->widget_ptr; gtk_container_remove(GTK_CONTAINER(eventbox), frame); gtk_container_remove(GTK_CONTAINER(frame), widget); gtk_container_add(GTK_CONTAINER(eventbox), widget); widget_with_property->button_not_pressed=FALSE; } } 

рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

github.com/SanyaZ7/movable_widgets_on_GtkFixed-

Source: https://habr.com/ru/post/hi473716/


All Articles