{"id":1323,"date":"2020-10-25T17:56:14","date_gmt":"2020-10-25T09:56:14","guid":{"rendered":"http:\/\/euhat.com\/wp\/?p=1323"},"modified":"2020-10-25T17:56:14","modified_gmt":"2020-10-25T09:56:14","slug":"gtk-user-control%e8%87%aa%e7%bb%98%e6%8e%a7%e4%bb%b6","status":"publish","type":"post","link":"http:\/\/euhat.com\/wp\/2020\/10\/25\/gtk-user-control%e8%87%aa%e7%bb%98%e6%8e%a7%e4%bb%b6\/","title":{"rendered":"gtk user control\u81ea\u7ed8\u63a7\u4ef6"},"content":{"rendered":"<p>ubuntu\u4e0bgtk\u5e93\u662f\u9ed8\u8ba4\u5df2\u5b89\u88c5\u7684\uff0c\u5f00\u53d1\u90e8\u7f72\u5f88\u65b9\u4fbf\uff0c\u4ee5\u4e0b\u662f\u6211\u5199\u7684\u81ea\u7ed8\u63a7\u4ef6\u4f8b\u5b50\uff1a<\/p>\n<p>EuhatChildWnd.h<\/p>\n<pre lang=\"cpp\" line=\"1\">\n#pragma once\n\nstruct _cairo_surface;\nstruct _GtkWidget;\n\nclass EuhatChildWnd\n{\npublic:\n\tEuhatChildWnd(int width, int height);\n\t~EuhatChildWnd();\n\n\tvoid clear();\n\tvoid drawBrush(struct _GtkWidget *widget, double x, double y);\n\t\n\tstruct _GtkWidget *drawingArea_;\n\tstruct _cairo_surface *surface_;\n\n\tdouble xFrom_;\n\tdouble yFrom_;\n};\n<\/pre>\n<p><!--more--><br \/>\nEuhatChildWnd.cpp<\/p>\n<pre lang=\"cpp\" line=\"1\">\n#include \"EuhatChildWnd.h\"\n#include <gtk\/gtk.h>\n\nstatic gboolean configureEventCb(GtkWidget *widget, GdkEventConfigure *event, gpointer data)\n{\n\tEuhatChildWnd *pThis = (EuhatChildWnd *)data;\n\n\tif (NULL != pThis->surface_)\n\t\tcairo_surface_destroy(pThis->surface_);\n\n\tpThis->surface_ = gdk_window_create_similar_surface(gtk_widget_get_window(widget), CAIRO_CONTENT_COLOR, gtk_widget_get_allocated_width(widget), gtk_widget_get_allocated_height(widget));\n\n\tpThis->clear();\n\n\treturn TRUE;\n}\n\nstatic gboolean drawCb(GtkWidget *widget, cairo_t *cr, gpointer data)\n{\n\tEuhatChildWnd *pThis = (EuhatChildWnd *)data;\n\n\tcairo_set_source_surface(cr, pThis->surface_, 0, 0);\n\tcairo_paint(cr);\n\n\treturn FALSE;\n}\n\nstatic gboolean buttonPressEventCb(GtkWidget *widget, GdkEventButton *event, gpointer data)\n{\n\tEuhatChildWnd *pThis = (EuhatChildWnd *)data;\n\tif (NULL == pThis->surface_)\n\t\treturn FALSE;\n\n\tif (event->button == GDK_BUTTON_PRIMARY)\n\t{\n\t\tpThis->xFrom_ = event->x;\n\t\tpThis->yFrom_ = event->y;\n\t\tpThis->drawBrush(widget, event->x, event->y);\n\t}\n\telse if (event->button == GDK_BUTTON_SECONDARY)\n\t{\n\t\tpThis->clear();\n\t\tgtk_widget_queue_draw(widget);\n\t}\n\n\treturn TRUE;\n}\n\nstatic gboolean motionNotifyEventCb(GtkWidget *widget, GdkEventMotion *event, gpointer data)\n{\n\tEuhatChildWnd *pThis = (EuhatChildWnd *)data;\n\tif (NULL == pThis->surface_)\n\t\treturn FALSE;\n\n\tif (event->state & GDK_BUTTON1_MASK)\n\t\tpThis->drawBrush(widget, event->x, event->y);\n\n\treturn TRUE;\n}\n\nEuhatChildWnd::EuhatChildWnd(int width, int height)\n{\n\tsurface_ = NULL;\n\txFrom_ = 0;\n\tyFrom_ = 0;\n\n\tdrawingArea_ = gtk_drawing_area_new();\n\n\tgtk_widget_set_size_request(drawingArea_, width, height);\n\n\tg_signal_connect(drawingArea_, \"configure-event\", G_CALLBACK(configureEventCb), this);\n\tg_signal_connect(drawingArea_, \"draw\", G_CALLBACK(drawCb), this);\n\n\tg_signal_connect(drawingArea_, \"button-press-event\", G_CALLBACK(buttonPressEventCb), this);\n\tg_signal_connect(drawingArea_, \"motion-notify-event\", G_CALLBACK(motionNotifyEventCb), this);\n\n\tgtk_widget_set_events(drawingArea_, gtk_widget_get_events(drawingArea_) | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);\n}\n\nEuhatChildWnd::~EuhatChildWnd()\n{\n\tif (NULL != surface_)\n\t\tcairo_surface_destroy(surface_);\n}\n\nvoid EuhatChildWnd::clear()\n{\n\tcairo_t *cr;\n\n\tcr = cairo_create(surface_);\n\n\tcairo_set_source_rgb(cr, 1, 1, 1);\n\tcairo_paint(cr);\n\n\tcairo_destroy(cr);\n}\n\nvoid EuhatChildWnd::drawBrush(GtkWidget *widget, gdouble x, gdouble y)\n{\n\tcairo_t *cr;\n\n\tcr = cairo_create(surface_);\n\n\/\/\tcairo_rectangle(cr, x - 3, y - 3, 6, 6);\n\/\/\tcairo_fill(cr);\n\/\/\tcairo_draw_line(cr, xFrom_, yFrom_, x, y);\n\tcairo_set_source_rgb(cr, 1, 1, 1);\n\tcairo_paint(cr);\n\n\tcairo_set_source_rgb(cr, 0, 0, 0);\n\tcairo_set_line_width(cr, 1);\n\tcairo_move_to(cr, xFrom_, yFrom_);\n\tcairo_line_to(cr, x, yFrom_);\n\tcairo_line_to(cr, x, y);\n\tcairo_line_to(cr, xFrom_, y);\n\tcairo_line_to(cr, xFrom_, yFrom_);\n\tcairo_stroke(cr);\n\n\tcairo_destroy(cr);\n\n\/\/\tgtk_widget_queue_draw_area(widget, x - 3, y - 3, 6, 6);\n\tgtk_widget_queue_draw(widget);\n}\n<\/pre>\n<p>EuhatWindow.h<\/p>\n<pre lang=\"cpp\" line=\"1\">\n#pragma once\n\nstruct _GtkWidget;\n\nclass EuhatApp;\nclass EuhatChildWnd;\n\nclass EuhatWindow\n{\npublic:\n\tEuhatWindow(EuhatApp *app);\n\t~EuhatWindow();\n\n\tvoid setTitle(const char *title);\n\tvoid addChildWnd(EuhatChildWnd *childWnd);\n\tvoid showAll();\n\n\tstruct _GtkWidget *window_;\n\/\/\tstruct _GtkWidget *frame_;\n\tstruct _GtkWidget *box_;\n};\n<\/pre>\n<p>EuhatWindow.cpp<\/p>\n<pre lang=\"cpp\" line=\"1\">\n#include \"EuhatWindow.h\"\n#include \"EuhatApp.h\"\n#include \"EuhatChildWnd.h\"\n#include <gtk\/gtk.h>\n\nstatic void closeWindow(gpointer data)\n{\n}\n\nEuhatWindow::EuhatWindow(EuhatApp *app)\n{\n\twindow_ = gtk_application_window_new(app->app_);\n\n\tg_signal_connect(window_, \"destroy\", G_CALLBACK(closeWindow), this);\n\n\tgtk_container_set_border_width(GTK_CONTAINER(window_), 8);\n\n\/*\tframe_ = gtk_frame_new(NULL);\n\tgtk_frame_set_shadow_type(GTK_FRAME(frame_), GTK_SHADOW_IN);\n\tgtk_container_add(GTK_CONTAINER(window_), frame_);\n*\/\n\tbox_ = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);\n\tgtk_container_add(GTK_CONTAINER(window_), box_);\n}\n\nEuhatWindow::~EuhatWindow()\n{\n}\n\nvoid EuhatWindow::setTitle(const char *title)\n{\n\tgtk_window_set_title(GTK_WINDOW(window_), title);\n}\n\nvoid EuhatWindow::addChildWnd(EuhatChildWnd *childWnd)\n{\n\/\/\tgtk_container_add(GTK_CONTAINER(frame_), childWnd->drawingArea_);\n\tgtk_container_add(GTK_CONTAINER(box_), childWnd->drawingArea_);\n}\n\nvoid EuhatWindow::showAll()\n{\n\tgtk_widget_show_all(window_);\n}\n<\/pre>\n<p>EuhatApp.h<\/p>\n<pre lang=\"cpp\" line=\"1\">\n#pragma once\n\nstruct _GtkApplication;\n\nclass EuhatApp\n{\npublic:\n\tEuhatApp();\n\t~EuhatApp();\n\n\tvirtual void onActivate();\n\tint run(int argc, char **argv);\n\n\tstruct _GtkApplication *app_;\n};\n<\/pre>\n<p>EuhatApp.cpp<\/p>\n<pre lang=\"cpp\" line=\"1\">\n#include \"EuhatApp.h\"\n#include <gtk\/gtk.h>\n\nstatic void activate(GtkApplication *app, gpointer data)\n{\n\tEuhatApp *pThis = (EuhatApp *)data;\n\n\tpThis->onActivate();\n}\n\nEuhatApp::EuhatApp()\n{\n\tapp_ = gtk_application_new(\"com.euhat.expert\", G_APPLICATION_FLAGS_NONE);\n\tg_signal_connect(app_, \"activate\", G_CALLBACK(activate), this);\n}\n\nEuhatApp::~EuhatApp()\n{\n\tg_object_unref(app_);\n}\n\nvoid EuhatApp::onActivate()\n{\n}\n\nint EuhatApp::run(int argc, char **argv)\n{\n\tint status;\n\tstatus = g_application_run(G_APPLICATION(app_), argc, argv);\n\treturn 1;\n}\n<\/pre>\n<p>main.cpp<\/p>\n<pre lang=\"cpp\" line=\"1\">\n#include <EuhatApp.h>\n#include <EuhatWindow.h>\n#include <EuhatChildWnd.h>\n#include <list>\n#include <vector>\n#include <string>\n#include <memory>\n\nusing namespace std;\n\nclass TstApp : public EuhatApp\n{\npublic:\n\tvoid onActivate();\n\n\tunique_ptr<EuhatWindow> mainWin_;\n\tunique_ptr<EuhatChildWnd> childWnd_;\n\tunique_ptr<EuhatChildWnd> childWnd2_;\n};\n\nvoid TstApp::onActivate()\n{\n\tmainWin_.reset(new EuhatWindow(this));\n\tchildWnd_.reset(new EuhatChildWnd(400, 400));\n\tchildWnd2_.reset(new EuhatChildWnd(400, 400));\n\tmainWin_->addChildWnd(childWnd_.get());\n\tmainWin_->addChildWnd(childWnd2_.get());\n\tmainWin_->showAll();\n}\n\nint main(int argc, char **argv)\n{\n\tTstApp app;\n\treturn app.run(argc, argv);\n}\n<\/pre>\n<p>Makefile<\/p>\n<pre lang=\"make\" line=\"1\">\nCPLUSPLUS=g++\nCFLAGS=-g -I. -Wl,-Map=test.map -no-pie -rdynamic `pkg-config --cflags gtk+-3.0`\nLDFLAGS=`pkg-config --libs gtk+-3.0`\n\nSOURCES=$(wildcard *.cpp)\n\nOBJS=$(SOURCES:%.cpp=release\/%.o)\n\nTARGET=release\/test\n\nall: before $(TARGET)\n\nbefore:\n\t@test -d release || mkdir -p release\n\n$(OBJS): release\/%.o: %.cpp\n\t$(CPLUSPLUS) -c $(CFLAGS) $< -o $@\n\n$(TARGET): $(OBJS)\n\t$(CPLUSPLUS) -o $@ $^ $(LDFLAGS)\n\nclean:\n\trm -Rf release\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>ubuntu\u4e0bgtk\u5e93\u662f\u9ed8\u8ba4\u5df2\u5b89\u88c5\u7684\uff0c\u5f00\u53d1\u90e8\u7f72\u5f88\u65b9\u4fbf\uff0c\u4ee5\u4e0b\u662f\u6211\u5199\u7684\u81ea\u7ed8\u63a7\u4ef6\u4f8b\u5b50\uff1a EuhatChildWnd.h #pragma once struct _cairo_surface; struct _GtkWidget; class EuhatChildWnd { public: EuhatChildWnd(int width, int height); ~EuhatChildWnd(); void clear(); void drawBrush(struct _GtkWidget *widget, double x, double y); struct _GtkWidget *drawingArea_; struct _cairo_surface *surface_; double xFrom_; double yFrom_; };<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[115,273,420,499],"_links":{"self":[{"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/posts\/1323"}],"collection":[{"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/comments?post=1323"}],"version-history":[{"count":0,"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/posts\/1323\/revisions"}],"wp:attachment":[{"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/media?parent=1323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/categories?post=1323"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/euhat.com\/wp\/wp-json\/wp\/v2\/tags?post=1323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}