2022-04-21 16:53:28 +02:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "utf-8" / >
< meta name = "generator" content = "pandoc" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1" / >
2023-12-10 09:39:32 +01:00
< link href = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel = "stylesheet" integrity = "sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin = "anonymous" >
2022-11-21 14:48:20 +01:00
< title > GTK 4 tutorial< / title >
2022-04-21 16:53:28 +02:00
< style >
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre{overflow: visible;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
2022-04-17 13:54:42 +02:00
}
2022-04-21 16:53:28 +02:00
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::after
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}
td {padding: 2px 6px; border: 1px solid;}
img {display: block; margin-left: auto; margin-right: auto;}
figcaption {text-align: center;}
< / style >
< / head >
< body style = "padding-top: 70px;" >
< div class = "container" >
< nav class = "navbar fixed-top navbar-expand-lg navbar-dark bg-primary" >
< div class = "container-fluid" >
< span class = "navbar-brand" > Gtk4 tutorial< / span >
< button class = "navbar-toggler" type = "button" data-bs-toggle = "collapse" data-bs-target = "#navbarSupportedContent" aria-controls = "navbarSupportedContent" aria-expanded = "false" aria-label = "Toggle navigation" >
< span class = "navbar-toggler-icon" > < / span >
< / button >
< div class = "collapse navbar-collapse" id = "navbarSupportedContent" >
< ul class = "navbar-nav me-auto mb-2 mb-lg-0" >
< li class = "nav-item" >
< a class = "nav-link" href = "index.html" > Home< / a >
< / li >
< li class = "nav-item" >
< a class = "nav-link" href = "sec25.html" > Prev: section25< / a >
< / li >
< li class = "nav-item" >
< a class = "nav-link" href = "sec27.html" > Next: section27< / a >
< / li >
< / ul >
< / div >
< / div >
< / nav >
2023-12-10 09:39:32 +01:00
< div class = "row justify-content-center" >
< div class = "col-xl-10 col-xxl-9" >
2023-07-23 04:49:22 +02:00
< h1 id = "custom-drawing" > Custom drawing< / h1 >
< p > Custom drawing is to draw shapes dynamically. This section shows an
example of custom drawing. You can draw rectangles by dragging the
mouse.< / p >
< p > Down the button.< / p >
2022-04-17 13:54:42 +02:00
< figure >
2023-07-23 04:49:22 +02:00
< img src = "image/cd0.png" alt = "down the button" / >
< figcaption aria-hidden = "true" > down the button< / figcaption >
2022-04-17 13:54:42 +02:00
< / figure >
2023-07-23 04:49:22 +02:00
< p > Move the mouse< / p >
< figure >
< img src = "image/cd1.png" alt = "Move the mouse" / >
< figcaption aria-hidden = "true" > Move the mouse< / figcaption >
< / figure >
< p > Up the button.< / p >
< figure >
< img src = "image/cd2.png" alt = "Up the button" / >
< figcaption aria-hidden = "true" > Up the button< / figcaption >
< / figure >
< p > The programs are at < code > src/custom_drawing< / code > directory.
Download the < a
href="https://github.com/ToshioCP/Gtk4-tutorial">repository< / a > and see
the directory. There are four files.< / p >
2022-04-17 13:54:42 +02:00
< ul >
2023-07-23 04:49:22 +02:00
< li > meson.build< / li >
< li > rect.c< / li >
< li > rect.gresource.xml< / li >
< li > rect.ui< / li >
2022-04-17 13:54:42 +02:00
< / ul >
2023-07-23 04:49:22 +02:00
< h2 id = "rect.gresource.xml" > rect.gresource.xml< / h2 >
< p > This file describes a ui file to compile. The compiler
glib-compile-resources uses it.< / p >
2023-07-15 10:27:53 +02:00
< div class = "sourceCode" id = "cb1" > < pre
class="sourceCode numberSource xml numberLines">< code class = "sourceCode xml" > < span id = "cb1-1" > < a href = "#cb1-1" > < / a > < span class = "fu" > < ?xml< / span > < span class = "ot" > version=< / span > < span class = "st" > " 1.0" < / span > < span class = "ot" > encoding=< / span > < span class = "st" > " UTF-8" < / span > < span class = "fu" > ?> < / span > < / span >
2023-07-23 04:49:22 +02:00
< span id = "cb1-2" > < a href = "#cb1-2" > < / a > < < span class = "kw" > gresources< / span > > < / span >
< span id = "cb1-3" > < a href = "#cb1-3" > < / a > < < span class = "kw" > gresource< / span > < span class = "ot" > prefix=< / span > < span class = "st" > " /com/github/ToshioCP/rect" < / span > > < / span >
< span id = "cb1-4" > < a href = "#cb1-4" > < / a > < < span class = "kw" > file< / span > > rect.ui< /< span class = "kw" > file< / span > > < / span >
< span id = "cb1-5" > < a href = "#cb1-5" > < / a > < /< span class = "kw" > gresource< / span > > < / span >
< span id = "cb1-6" > < a href = "#cb1-6" > < / a > < /< span class = "kw" > gresources< / span > > < / span > < / code > < / pre > < / div >
< p > The prefix is < code > /com/github/ToshioCP/rect< / code > and the file is
< code > rect.ui< / code > . Therefore, GtkBuilder reads the resource from
< code > /com/github/ToshioCP/rect/rect.ui< / code > .< / p >
< h2 id = "rect.ui" > rect.ui< / h2 >
< p > The following is the ui file that defines the widgets. There are two
widgets which are GtkApplicationWindow and GtkDrawingArea. The ids are
< code > win< / code > and < code > da< / code > respectively.< / p >
2022-11-21 14:48:20 +01:00
< div class = "sourceCode" id = "cb2" > < pre
2023-07-15 10:27:53 +02:00
class="sourceCode numberSource xml numberLines">< code class = "sourceCode xml" > < span id = "cb2-1" > < a href = "#cb2-1" > < / a > < span class = "fu" > < ?xml< / span > < span class = "ot" > version=< / span > < span class = "st" > " 1.0" < / span > < span class = "ot" > encoding=< / span > < span class = "st" > " UTF-8" < / span > < span class = "fu" > ?> < / span > < / span >
2023-07-23 04:49:22 +02:00
< span id = "cb2-2" > < a href = "#cb2-2" > < / a > < < span class = "kw" > interface< / span > > < / span >
< span id = "cb2-3" > < a href = "#cb2-3" > < / a > < < span class = "kw" > object< / span > < span class = "ot" > class=< / span > < span class = "st" > " GtkApplicationWindow" < / span > < span class = "ot" > id=< / span > < span class = "st" > " win" < / span > > < / span >
< span id = "cb2-4" > < a href = "#cb2-4" > < / a > < < span class = "kw" > property< / span > < span class = "ot" > name=< / span > < span class = "st" > " default-width" < / span > > 800< /< span class = "kw" > property< / span > > < / span >
< span id = "cb2-5" > < a href = "#cb2-5" > < / a > < < span class = "kw" > property< / span > < span class = "ot" > name=< / span > < span class = "st" > " default-height" < / span > > 600< /< span class = "kw" > property< / span > > < / span >
< span id = "cb2-6" > < a href = "#cb2-6" > < / a > < < span class = "kw" > property< / span > < span class = "ot" > name=< / span > < span class = "st" > " resizable" < / span > > FALSE< /< span class = "kw" > property< / span > > < / span >
< span id = "cb2-7" > < a href = "#cb2-7" > < / a > < < span class = "kw" > property< / span > < span class = "ot" > name=< / span > < span class = "st" > " title" < / span > > Custom drawing< /< span class = "kw" > property< / span > > < / span >
< span id = "cb2-8" > < a href = "#cb2-8" > < / a > < < span class = "kw" > child< / span > > < / span >
< span id = "cb2-9" > < a href = "#cb2-9" > < / a > < < span class = "kw" > object< / span > < span class = "ot" > class=< / span > < span class = "st" > " GtkDrawingArea" < / span > < span class = "ot" > id=< / span > < span class = "st" > " da" < / span > > < / span >
< span id = "cb2-10" > < a href = "#cb2-10" > < / a > < < span class = "kw" > property< / span > < span class = "ot" > name=< / span > < span class = "st" > " hexpand" < / span > > TRUE< /< span class = "kw" > property< / span > > < / span >
< span id = "cb2-11" > < a href = "#cb2-11" > < / a > < < span class = "kw" > property< / span > < span class = "ot" > name=< / span > < span class = "st" > " vexpand" < / span > > TRUE< /< span class = "kw" > property< / span > > < / span >
< span id = "cb2-12" > < a href = "#cb2-12" > < / a > < /< span class = "kw" > object< / span > > < / span >
< span id = "cb2-13" > < a href = "#cb2-13" > < / a > < /< span class = "kw" > child< / span > > < / span >
< span id = "cb2-14" > < a href = "#cb2-14" > < / a > < /< span class = "kw" > object< / span > > < / span >
< span id = "cb2-15" > < a href = "#cb2-15" > < / a > < /< span class = "kw" > interface< / span > > < / span > < / code > < / pre > < / div >
< h2 id = "rect.c" > rect.c< / h2 >
< h3 id = "gtkapplication" > GtkApplication< / h3 >
< p > This program uses GtkApplication. The application ID is
< code > com.github.ToshioCP.rect< / code > .< / p >
< div class = "sourceCode" id = "cb3" > < pre class = "sourceCode c" > < code class = "sourceCode c" > < span id = "cb3-1" > < a href = "#cb3-1" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "pp" > #define APPLICATION_ID " com.github.ToshioCP.rect" < / span > < / span > < / code > < / pre > < / div >
< p > See < a
href="https://developer.gnome.org/documentation/tutorials/application-id.html">GNOME
Developer Documentation< / a > for further information.< / p >
< p > The function < code > main< / code > is called at the beginning of the
application.< / p >
< div class = "sourceCode" id = "cb4" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb4-1" > < a href = "#cb4-1" > < / a > < span class = "dt" > int< / span > < / span >
< span id = "cb4-2" > < a href = "#cb4-2" > < / a > main < span class = "op" > (< / span > < span class = "dt" > int< / span > argc< span class = "op" > ,< / span > < span class = "dt" > char< / span > < span class = "op" > **< / span > argv< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb4-3" > < a href = "#cb4-3" > < / a > GtkApplication < span class = "op" > *< / span > app< span class = "op" > ;< / span > < / span >
< span id = "cb4-4" > < a href = "#cb4-4" > < / a > < span class = "dt" > int< / span > stat< span class = "op" > ;< / span > < / span >
< span id = "cb4-5" > < a href = "#cb4-5" > < / a > < / span >
< span id = "cb4-6" > < a href = "#cb4-6" > < / a > app < span class = "op" > =< / span > gtk_application_new < span class = "op" > (< / span > APPLICATION_ID< span class = "op" > ,< / span > G_APPLICATION_HANDLES_OPEN< span class = "op" > );< / span > < / span >
< span id = "cb4-7" > < a href = "#cb4-7" > < / a > g_signal_connect < span class = "op" > (< / span > app< span class = "op" > ,< / span > < span class = "st" > " startup" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > app_startup< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb4-8" > < a href = "#cb4-8" > < / a > g_signal_connect < span class = "op" > (< / span > app< span class = "op" > ,< / span > < span class = "st" > " activate" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > app_activate< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb4-9" > < a href = "#cb4-9" > < / a > g_signal_connect < span class = "op" > (< / span > app< span class = "op" > ,< / span > < span class = "st" > " shutdown" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > app_shutdown< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb4-10" > < a href = "#cb4-10" > < / a > stat < span class = "op" > =< / span > g_application_run < span class = "op" > (< / span > G_APPLICATION < span class = "op" > (< / span > app< span class = "op" > ),< / span > argc< span class = "op" > ,< / span > argv< span class = "op" > );< / span > < / span >
< span id = "cb4-11" > < a href = "#cb4-11" > < / a > g_object_unref < span class = "op" > (< / span > app< span class = "op" > );< / span > < / span >
< span id = "cb4-12" > < a href = "#cb4-12" > < / a > < span class = "cf" > return< / span > stat< span class = "op" > ;< / span > < / span >
< span id = "cb4-13" > < a href = "#cb4-13" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< p > It connects three signals and handlers.< / p >
< ul >
< li > startup: It is emitted after the application is registered to the
system.< / li >
< li > activate: It is emitted when the application is activated.< / li >
< li > shutdown: It is emitted just before the application quits.< / li >
< / ul >
2022-11-21 14:48:20 +01:00
< div class = "sourceCode" id = "cb5" > < pre
2023-07-15 10:27:53 +02:00
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb5-1" > < a href = "#cb5-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
2023-07-23 04:49:22 +02:00
< span id = "cb5-2" > < a href = "#cb5-2" > < / a > app_startup < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > application< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-3" > < a href = "#cb5-3" > < / a > GtkApplication < span class = "op" > *< / span > app < span class = "op" > =< / span > GTK_APPLICATION < span class = "op" > (< / span > application< span class = "op" > );< / span > < / span >
< span id = "cb5-4" > < a href = "#cb5-4" > < / a > GtkBuilder < span class = "op" > *< / span > build< span class = "op" > ;< / span > < / span >
< span id = "cb5-5" > < a href = "#cb5-5" > < / a > GtkWindow < span class = "op" > *< / span > win< span class = "op" > ;< / span > < / span >
< span id = "cb5-6" > < a href = "#cb5-6" > < / a > GtkDrawingArea < span class = "op" > *< / span > da< span class = "op" > ;< / span > < / span >
< span id = "cb5-7" > < a href = "#cb5-7" > < / a > GtkGesture < span class = "op" > *< / span > drag< span class = "op" > ;< / span > < / span >
2023-07-15 10:27:53 +02:00
< span id = "cb5-8" > < a href = "#cb5-8" > < / a > < / span >
2023-07-23 04:49:22 +02:00
< span id = "cb5-9" > < a href = "#cb5-9" > < / a > build < span class = "op" > =< / span > gtk_builder_new_from_resource < span class = "op" > (< / span > < span class = "st" > " /com/github/ToshioCP/rect/rect.ui" < / span > < span class = "op" > );< / span > < / span >
< span id = "cb5-10" > < a href = "#cb5-10" > < / a > win < span class = "op" > =< / span > GTK_WINDOW < span class = "op" > (< / span > gtk_builder_get_object < span class = "op" > (< / span > build< span class = "op" > ,< / span > < span class = "st" > " win" < / span > < span class = "op" > ));< / span > < / span >
< span id = "cb5-11" > < a href = "#cb5-11" > < / a > da < span class = "op" > =< / span > GTK_DRAWING_AREA < span class = "op" > (< / span > gtk_builder_get_object < span class = "op" > (< / span > build< span class = "op" > ,< / span > < span class = "st" > " da" < / span > < span class = "op" > ));< / span > < / span >
< span id = "cb5-12" > < a href = "#cb5-12" > < / a > gtk_window_set_application < span class = "op" > (< / span > win< span class = "op" > ,< / span > app< span class = "op" > );< / span > < / span >
< span id = "cb5-13" > < a href = "#cb5-13" > < / a > g_object_unref < span class = "op" > (< / span > build< span class = "op" > );< / span > < / span >
< span id = "cb5-14" > < a href = "#cb5-14" > < / a > < / span >
< span id = "cb5-15" > < a href = "#cb5-15" > < / a > gtk_drawing_area_set_draw_func < span class = "op" > (< / span > da< span class = "op" > ,< / span > draw_cb< span class = "op" > ,< / span > NULL< span class = "op" > ,< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb5-16" > < a href = "#cb5-16" > < / a > g_signal_connect_after < span class = "op" > (< / span > da< span class = "op" > ,< / span > < span class = "st" > " resize" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > resize_cb< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb5-17" > < a href = "#cb5-17" > < / a > < / span >
< span id = "cb5-18" > < a href = "#cb5-18" > < / a > drag < span class = "op" > =< / span > gtk_gesture_drag_new < span class = "op" > ();< / span > < / span >
< span id = "cb5-19" > < a href = "#cb5-19" > < / a > gtk_gesture_single_set_button < span class = "op" > (< / span > GTK_GESTURE_SINGLE < span class = "op" > (< / span > drag< span class = "op" > ),< / span > GDK_BUTTON_PRIMARY< span class = "op" > );< / span > < / span >
< span id = "cb5-20" > < a href = "#cb5-20" > < / a > gtk_widget_add_controller < span class = "op" > (< / span > GTK_WIDGET < span class = "op" > (< / span > da< span class = "op" > ),< / span > GTK_EVENT_CONTROLLER < span class = "op" > (< / span > drag< span class = "op" > ));< / span > < / span >
< span id = "cb5-21" > < a href = "#cb5-21" > < / a > g_signal_connect < span class = "op" > (< / span > drag< span class = "op" > ,< / span > < span class = "st" > " drag-begin" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > drag_begin< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb5-22" > < a href = "#cb5-22" > < / a > g_signal_connect < span class = "op" > (< / span > drag< span class = "op" > ,< / span > < span class = "st" > " drag-update" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > drag_update< span class = "op" > ),< / span > da< span class = "op" > );< / span > < / span >
< span id = "cb5-23" > < a href = "#cb5-23" > < / a > g_signal_connect < span class = "op" > (< / span > drag< span class = "op" > ,< / span > < span class = "st" > " drag-end" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > drag_end< span class = "op" > ),< / span > da< span class = "op" > );< / span > < / span >
< span id = "cb5-24" > < a href = "#cb5-24" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< p > The startup handler does three things.< / p >
2023-07-15 10:27:53 +02:00
< ul >
2023-07-23 04:49:22 +02:00
< li > Builds the widgets.< / li >
< li > Initializes the GtkDrawingArea instance.
2022-04-17 13:54:42 +02:00
< ul >
2023-07-23 04:49:22 +02:00
< li > Sets the drawing function< / li >
< li > Connects the “resize” signal and the handler.< / li >
< / ul > < / li >
< li > Creates the GtkGestureDrag instance and initializes it. Gesture will
be explained in this section later.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
2023-07-23 04:49:22 +02:00
< div class = "sourceCode" id = "cb6" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb6-1" > < a href = "#cb6-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb6-2" > < a href = "#cb6-2" > < / a > app_activate < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > application< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb6-3" > < a href = "#cb6-3" > < / a > GtkApplication < span class = "op" > *< / span > app < span class = "op" > =< / span > GTK_APPLICATION < span class = "op" > (< / span > application< span class = "op" > );< / span > < / span >
< span id = "cb6-4" > < a href = "#cb6-4" > < / a > GtkWindow < span class = "op" > *< / span > win< span class = "op" > ;< / span > < / span >
< span id = "cb6-5" > < a href = "#cb6-5" > < / a > < / span >
< span id = "cb6-6" > < a href = "#cb6-6" > < / a > win < span class = "op" > =< / span > gtk_application_get_active_window < span class = "op" > (< / span > app< span class = "op" > );< / span > < / span >
< span id = "cb6-7" > < a href = "#cb6-7" > < / a > gtk_window_present < span class = "op" > (< / span > win< span class = "op" > );< / span > < / span >
< span id = "cb6-8" > < a href = "#cb6-8" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< p > The activate handler just shows the window.< / p >
< h3 id = "gtkdrawingarea" > GtkDrawingArea< / h3 >
< p > The program has two cairo surfaces and they are pointed by the global
variables.< / p >
< div class = "sourceCode" id = "cb7" > < pre class = "sourceCode C" > < code class = "sourceCode c" > < span id = "cb7-1" > < a href = "#cb7-1" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "dt" > static< / span > cairo_surface_t < span class = "op" > *< / span > surface < span class = "op" > =< / span > NULL< span class = "op" > ;< / span > < / span >
< span id = "cb7-2" > < a href = "#cb7-2" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "dt" > static< / span > cairo_surface_t < span class = "op" > *< / span > surface_save < span class = "op" > =< / span > NULL< span class = "op" > ;< / span > < / span > < / code > < / pre > < / div >
< p > The drawing process is as follows.< / p >
2022-04-17 13:54:42 +02:00
< ul >
2023-07-23 04:49:22 +02:00
< li > Creates an image on < code > surface< / code > .< / li >
< li > Copies < code > surface< / code > to the cairo surface of the
GtkDrawingArea.< / li >
< li > Calls < code > gtk_widget_queue_draw (da)< / code > to draw it if
necessary.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
2023-07-23 04:49:22 +02:00
< p > They are created in the “resize” signal handler.< / p >
2023-07-15 10:27:53 +02:00
< div class = "sourceCode" id = "cb8" > < pre
2023-07-23 04:49:22 +02:00
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb8-1" > < a href = "#cb8-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb8-2" > < a href = "#cb8-2" > < / a > resize_cb < span class = "op" > (< / span > GtkWidget < span class = "op" > *< / span > widget< span class = "op" > ,< / span > < span class = "dt" > int< / span > width< span class = "op" > ,< / span > < span class = "dt" > int< / span > height< span class = "op" > ,< / span > gpointer user_data< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-3" > < a href = "#cb8-3" > < / a > cairo_t < span class = "op" > *< / span > cr< span class = "op" > ;< / span > < / span >
< span id = "cb8-4" > < a href = "#cb8-4" > < / a > < / span >
< span id = "cb8-5" > < a href = "#cb8-5" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > surface< span class = "op" > )< / span > < / span >
< span id = "cb8-6" > < a href = "#cb8-6" > < / a > cairo_surface_destroy < span class = "op" > (< / span > surface< span class = "op" > );< / span > < / span >
< span id = "cb8-7" > < a href = "#cb8-7" > < / a > surface < span class = "op" > =< / span > cairo_image_surface_create < span class = "op" > (< / span > CAIRO_FORMAT_RGB24< span class = "op" > ,< / span > width< span class = "op" > ,< / span > height< span class = "op" > );< / span > < / span >
< span id = "cb8-8" > < a href = "#cb8-8" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > surface_save< span class = "op" > )< / span > < / span >
< span id = "cb8-9" > < a href = "#cb8-9" > < / a > cairo_surface_destroy < span class = "op" > (< / span > surface_save< span class = "op" > );< / span > < / span >
< span id = "cb8-10" > < a href = "#cb8-10" > < / a > surface_save < span class = "op" > =< / span > cairo_image_surface_create < span class = "op" > (< / span > CAIRO_FORMAT_RGB24< span class = "op" > ,< / span > width< span class = "op" > ,< / span > height< span class = "op" > );< / span > < / span >
< span id = "cb8-11" > < a href = "#cb8-11" > < / a > < span class = "co" > /* Paint the surface white. It is the background color. */< / span > < / span >
< span id = "cb8-12" > < a href = "#cb8-12" > < / a > cr < span class = "op" > =< / span > cairo_create < span class = "op" > (< / span > surface< span class = "op" > );< / span > < / span >
< span id = "cb8-13" > < a href = "#cb8-13" > < / a > cairo_set_source_rgb < span class = "op" > (< / span > cr< span class = "op" > ,< / span > < span class = "fl" > 1.0< / span > < span class = "op" > ,< / span > < span class = "fl" > 1.0< / span > < span class = "op" > ,< / span > < span class = "fl" > 1.0< / span > < span class = "op" > );< / span > < / span >
< span id = "cb8-14" > < a href = "#cb8-14" > < / a > cairo_paint < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb8-15" > < a href = "#cb8-15" > < / a > cairo_destroy < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb8-16" > < a href = "#cb8-16" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< p > This callback is called when the GtkDrawingArea is shown. It is the
only call because the window is not resizable.< / p >
< p > It creates image surfaces for < code > surface< / code > and
< code > surface_save< / code > . The < code > surface< / code > surface is painted
white, which is the background color.< / p >
< p > The drawing function copies < code > surface< / code > to the
GtkDrawingArea surface.< / p >
< div class = "sourceCode" id = "cb9" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb9-1" > < a href = "#cb9-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb9-2" > < a href = "#cb9-2" > < / a > draw_cb < span class = "op" > (< / span > GtkDrawingArea < span class = "op" > *< / span > da< span class = "op" > ,< / span > cairo_t < span class = "op" > *< / span > cr< span class = "op" > ,< / span > < span class = "dt" > int< / span > width< span class = "op" > ,< / span > < span class = "dt" > int< / span > height< span class = "op" > ,< / span > gpointer user_data< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb9-3" > < a href = "#cb9-3" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > surface< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb9-4" > < a href = "#cb9-4" > < / a > cairo_set_source_surface < span class = "op" > (< / span > cr< span class = "op" > ,< / span > surface< span class = "op" > ,< / span > < span class = "fl" > 0.0< / span > < span class = "op" > ,< / span > < span class = "fl" > 0.0< / span > < span class = "op" > );< / span > < / span >
< span id = "cb9-5" > < a href = "#cb9-5" > < / a > cairo_paint < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb9-6" > < a href = "#cb9-6" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb9-7" > < a href = "#cb9-7" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< p > This function is called by the system when it needs to redraw the
drawing area.< / p >
< p > Two surfaces < code > surface< / code > and < code > surface_save< / code > are
destroyed before the application quits.< / p >
< div class = "sourceCode" id = "cb10" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb10-1" > < a href = "#cb10-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb10-2" > < a href = "#cb10-2" > < / a > app_shutdown < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > application< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb10-3" > < a href = "#cb10-3" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > surface< span class = "op" > )< / span > < / span >
< span id = "cb10-4" > < a href = "#cb10-4" > < / a > cairo_surface_destroy < span class = "op" > (< / span > surface< span class = "op" > );< / span > < / span >
< span id = "cb10-5" > < a href = "#cb10-5" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > surface_save< span class = "op" > )< / span > < / span >
< span id = "cb10-6" > < a href = "#cb10-6" > < / a > cairo_surface_destroy < span class = "op" > (< / span > surface_save< span class = "op" > );< / span > < / span >
< span id = "cb10-7" > < a href = "#cb10-7" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< h3 id = "gtkgesturedrag" > GtkGestureDrag< / h3 >
< p > Gesture class is used to recognize human gestures such as click,
drag, pan, swipe and so on. It is a subclass of GtkEventController.
GtkGesture class is abstract and there are several implementations.< / p >
2023-07-15 10:27:53 +02:00
< ul >
2023-07-23 04:49:22 +02:00
< li > GtkGestureClick< / li >
< li > GtkGestureDrag< / li >
< li > GtkGesturePan< / li >
< li > GtkGestureSwipe< / li >
< li > other implementations< / li >
2023-07-15 10:27:53 +02:00
< / ul >
2023-07-23 04:49:22 +02:00
< p > The program < code > rect.c< / code > uses GtkGestureDrag. It is the
implementation for drags. The parent-child relationship is as
follows.< / p >
< pre > < code > GObject -- GtkEventController -- GtkGesture -- GtkGestureSingle -- GtkGestureDrag< / code > < / pre >
< p > GtkGestureSingle is a subclass of GtkGesture and optimized for
singe-touch and mouse gestures.< / p >
< p > A GtkGestureDrag instance is created and initialized in the startup
signal handler in < code > rect.c< / code > . See line 18 to 23 in the
following.< / p >
< div class = "sourceCode" id = "cb12" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb12-1" > < a href = "#cb12-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb12-2" > < a href = "#cb12-2" > < / a > app_startup < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > application< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb12-3" > < a href = "#cb12-3" > < / a > GtkApplication < span class = "op" > *< / span > app < span class = "op" > =< / span > GTK_APPLICATION < span class = "op" > (< / span > application< span class = "op" > );< / span > < / span >
< span id = "cb12-4" > < a href = "#cb12-4" > < / a > GtkBuilder < span class = "op" > *< / span > build< span class = "op" > ;< / span > < / span >
< span id = "cb12-5" > < a href = "#cb12-5" > < / a > GtkWindow < span class = "op" > *< / span > win< span class = "op" > ;< / span > < / span >
< span id = "cb12-6" > < a href = "#cb12-6" > < / a > GtkDrawingArea < span class = "op" > *< / span > da< span class = "op" > ;< / span > < / span >
< span id = "cb12-7" > < a href = "#cb12-7" > < / a > GtkGesture < span class = "op" > *< / span > drag< span class = "op" > ;< / span > < / span >
< span id = "cb12-8" > < a href = "#cb12-8" > < / a > < / span >
< span id = "cb12-9" > < a href = "#cb12-9" > < / a > build < span class = "op" > =< / span > gtk_builder_new_from_resource < span class = "op" > (< / span > < span class = "st" > " /com/github/ToshioCP/rect/rect.ui" < / span > < span class = "op" > );< / span > < / span >
< span id = "cb12-10" > < a href = "#cb12-10" > < / a > win < span class = "op" > =< / span > GTK_WINDOW < span class = "op" > (< / span > gtk_builder_get_object < span class = "op" > (< / span > build< span class = "op" > ,< / span > < span class = "st" > " win" < / span > < span class = "op" > ));< / span > < / span >
< span id = "cb12-11" > < a href = "#cb12-11" > < / a > da < span class = "op" > =< / span > GTK_DRAWING_AREA < span class = "op" > (< / span > gtk_builder_get_object < span class = "op" > (< / span > build< span class = "op" > ,< / span > < span class = "st" > " da" < / span > < span class = "op" > ));< / span > < / span >
< span id = "cb12-12" > < a href = "#cb12-12" > < / a > gtk_window_set_application < span class = "op" > (< / span > win< span class = "op" > ,< / span > app< span class = "op" > );< / span > < / span >
< span id = "cb12-13" > < a href = "#cb12-13" > < / a > g_object_unref < span class = "op" > (< / span > build< span class = "op" > );< / span > < / span >
< span id = "cb12-14" > < a href = "#cb12-14" > < / a > < / span >
< span id = "cb12-15" > < a href = "#cb12-15" > < / a > gtk_drawing_area_set_draw_func < span class = "op" > (< / span > da< span class = "op" > ,< / span > draw_cb< span class = "op" > ,< / span > NULL< span class = "op" > ,< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb12-16" > < a href = "#cb12-16" > < / a > g_signal_connect_after < span class = "op" > (< / span > da< span class = "op" > ,< / span > < span class = "st" > " resize" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > resize_cb< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb12-17" > < a href = "#cb12-17" > < / a > < / span >
< span id = "cb12-18" > < a href = "#cb12-18" > < / a > drag < span class = "op" > =< / span > gtk_gesture_drag_new < span class = "op" > ();< / span > < / span >
< span id = "cb12-19" > < a href = "#cb12-19" > < / a > gtk_gesture_single_set_button < span class = "op" > (< / span > GTK_GESTURE_SINGLE < span class = "op" > (< / span > drag< span class = "op" > ),< / span > GDK_BUTTON_PRIMARY< span class = "op" > );< / span > < / span >
< span id = "cb12-20" > < a href = "#cb12-20" > < / a > gtk_widget_add_controller < span class = "op" > (< / span > GTK_WIDGET < span class = "op" > (< / span > da< span class = "op" > ),< / span > GTK_EVENT_CONTROLLER < span class = "op" > (< / span > drag< span class = "op" > ));< / span > < / span >
< span id = "cb12-21" > < a href = "#cb12-21" > < / a > g_signal_connect < span class = "op" > (< / span > drag< span class = "op" > ,< / span > < span class = "st" > " drag-begin" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > drag_begin< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb12-22" > < a href = "#cb12-22" > < / a > g_signal_connect < span class = "op" > (< / span > drag< span class = "op" > ,< / span > < span class = "st" > " drag-update" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > drag_update< span class = "op" > ),< / span > da< span class = "op" > );< / span > < / span >
< span id = "cb12-23" > < a href = "#cb12-23" > < / a > g_signal_connect < span class = "op" > (< / span > drag< span class = "op" > ,< / span > < span class = "st" > " drag-end" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > drag_end< span class = "op" > ),< / span > da< span class = "op" > );< / span > < / span >
< span id = "cb12-24" > < a href = "#cb12-24" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< ul >
< li > The function < code > gtk_gesture_drag_new< / code > creates a new
GtkGestureDrag instance.< / li >
< li > The function < code > gtk_gesture_single_set_button< / code > sets the
button number to listen to. The constant < code > GDK_BUTTON_PRIMARY< / code >
is the left button of a mouse.< / li >
< li > The function < code > gtk_widget_add_controller< / code > adds an event
controller, gestures are descendants of the event controller, to a
widget.< / li >
< li > Three signals and handlers are connected.
< ul >
< li > drag-begin: Emitted when dragging starts.< / li >
< li > drag-update: Emitted when the dragging point moves.< / li >
< li > drag-end: Emitted when the dragging ends.< / li >
< / ul > < / li >
< / ul >
< p > The process during the drag is as follows.< / p >
< ul >
< li > start: save the surface and start points< / li >
< li > update: restore the surface and draw a thin rectangle between the
start point and the current point of the mouse< / li >
< li > end: restore the surface and draw a thick rectangle between the
start and end points.< / li >
< / ul >
< p > We need two global variables for the start point.< / p >
< div class = "sourceCode" id = "cb13" > < pre class = "sourceCode C" > < code class = "sourceCode c" > < span id = "cb13-1" > < a href = "#cb13-1" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > double< / span > start_x< span class = "op" > ;< / span > < / span >
< span id = "cb13-2" > < a href = "#cb13-2" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > double< / span > start_y< span class = "op" > ;< / span > < / span > < / code > < / pre > < / div >
< p > The following is the handler for the “drag-begin” signal.< / p >
< div class = "sourceCode" id = "cb14" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb14-1" > < a href = "#cb14-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb14-2" > < a href = "#cb14-2" > < / a > copy_surface < span class = "op" > (< / span > cairo_surface_t < span class = "op" > *< / span > src< span class = "op" > ,< / span > cairo_surface_t < span class = "op" > *< / span > dst< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb14-3" > < a href = "#cb14-3" > < / a > < span class = "cf" > if< / span > < span class = "op" > (!< / span > src < span class = "op" > ||< / span > < span class = "op" > !< / span > dst< span class = "op" > )< / span > < / span >
< span id = "cb14-4" > < a href = "#cb14-4" > < / a > < span class = "cf" > return< / span > < span class = "op" > ;< / span > < / span >
< span id = "cb14-5" > < a href = "#cb14-5" > < / a > cairo_t < span class = "op" > *< / span > cr < span class = "op" > =< / span > cairo_create < span class = "op" > (< / span > dst< span class = "op" > );< / span > < / span >
< span id = "cb14-6" > < a href = "#cb14-6" > < / a > cairo_set_source_surface < span class = "op" > (< / span > cr< span class = "op" > ,< / span > src< span class = "op" > ,< / span > < span class = "fl" > 0.0< / span > < span class = "op" > ,< / span > < span class = "fl" > 0.0< / span > < span class = "op" > );< / span > < / span >
< span id = "cb14-7" > < a href = "#cb14-7" > < / a > cairo_paint < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb14-8" > < a href = "#cb14-8" > < / a > cairo_destroy < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb14-9" > < a href = "#cb14-9" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb14-10" > < a href = "#cb14-10" > < / a > < / span >
< span id = "cb14-11" > < a href = "#cb14-11" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb14-12" > < a href = "#cb14-12" > < / a > drag_begin < span class = "op" > (< / span > GtkGestureDrag < span class = "op" > *< / span > gesture< span class = "op" > ,< / span > < span class = "dt" > double< / span > x< span class = "op" > ,< / span > < span class = "dt" > double< / span > y< span class = "op" > ,< / span > gpointer user_data< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb14-13" > < a href = "#cb14-13" > < / a > < span class = "co" > // save the surface and record (x, y)< / span > < / span >
< span id = "cb14-14" > < a href = "#cb14-14" > < / a > copy_surface < span class = "op" > (< / span > surface< span class = "op" > ,< / span > surface_save< span class = "op" > );< / span > < / span >
< span id = "cb14-15" > < a href = "#cb14-15" > < / a > start_x < span class = "op" > =< / span > x< span class = "op" > ;< / span > < / span >
< span id = "cb14-16" > < a href = "#cb14-16" > < / a > start_y < span class = "op" > =< / span > y< span class = "op" > ;< / span > < / span >
< span id = "cb14-17" > < a href = "#cb14-17" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< ul >
< li > Copies < code > surface< / code > to < code > surface_save< / code > , which is
an image just before the dragging.< / li >
< li > Stores the points to < code > start_x< / code > and
< code > start_y< / code > .< / li >
< / ul >
< div class = "sourceCode" id = "cb15" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb15-1" > < a href = "#cb15-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb15-2" > < a href = "#cb15-2" > < / a > drag_update < span class = "op" > (< / span > GtkGestureDrag < span class = "op" > *< / span > gesture< span class = "op" > ,< / span > < span class = "dt" > double< / span > offset_x< span class = "op" > ,< / span > < span class = "dt" > double< / span > offset_y< span class = "op" > ,< / span > gpointer user_data< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb15-3" > < a href = "#cb15-3" > < / a > GtkWidget < span class = "op" > *< / span > da < span class = "op" > =< / span > GTK_WIDGET < span class = "op" > (< / span > user_data< span class = "op" > );< / span > < / span >
< span id = "cb15-4" > < a href = "#cb15-4" > < / a > cairo_t < span class = "op" > *< / span > cr< span class = "op" > ;< / span > < / span >
< span id = "cb15-5" > < a href = "#cb15-5" > < / a > < / span >
< span id = "cb15-6" > < a href = "#cb15-6" > < / a > copy_surface < span class = "op" > (< / span > surface_save< span class = "op" > ,< / span > surface< span class = "op" > );< / span > < / span >
< span id = "cb15-7" > < a href = "#cb15-7" > < / a > cr < span class = "op" > =< / span > cairo_create < span class = "op" > (< / span > surface< span class = "op" > );< / span > < / span >
< span id = "cb15-8" > < a href = "#cb15-8" > < / a > cairo_rectangle < span class = "op" > (< / span > cr< span class = "op" > ,< / span > start_x< span class = "op" > ,< / span > start_y< span class = "op" > ,< / span > offset_x< span class = "op" > ,< / span > offset_y< span class = "op" > );< / span > < / span >
< span id = "cb15-9" > < a href = "#cb15-9" > < / a > cairo_set_line_width < span class = "op" > (< / span > cr< span class = "op" > ,< / span > < span class = "fl" > 1.0< / span > < span class = "op" > );< / span > < / span >
< span id = "cb15-10" > < a href = "#cb15-10" > < / a > cairo_stroke < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb15-11" > < a href = "#cb15-11" > < / a > cairo_destroy < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb15-12" > < a href = "#cb15-12" > < / a > gtk_widget_queue_draw < span class = "op" > (< / span > da< span class = "op" > );< / span > < / span >
< span id = "cb15-13" > < a href = "#cb15-13" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< ul >
< li > Restores < code > surface< / code > from < code > surface_save< / code > .< / li >
< li > Draws a rectangle with thin lines.< / li >
< li > Calls < code > gtk_widget_queue_draw< / code > to add the GtkDrawingArea
to the queue to redraw.< / li >
< / ul >
< div class = "sourceCode" id = "cb16" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb16-1" > < a href = "#cb16-1" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb16-2" > < a href = "#cb16-2" > < / a > drag_end < span class = "op" > (< / span > GtkGestureDrag < span class = "op" > *< / span > gesture< span class = "op" > ,< / span > < span class = "dt" > double< / span > offset_x< span class = "op" > ,< / span > < span class = "dt" > double< / span > offset_y< span class = "op" > ,< / span > gpointer user_data< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb16-3" > < a href = "#cb16-3" > < / a > GtkWidget < span class = "op" > *< / span > da < span class = "op" > =< / span > GTK_WIDGET < span class = "op" > (< / span > user_data< span class = "op" > );< / span > < / span >
< span id = "cb16-4" > < a href = "#cb16-4" > < / a > cairo_t < span class = "op" > *< / span > cr< span class = "op" > ;< / span > < / span >
< span id = "cb16-5" > < a href = "#cb16-5" > < / a > < / span >
< span id = "cb16-6" > < a href = "#cb16-6" > < / a > copy_surface < span class = "op" > (< / span > surface_save< span class = "op" > ,< / span > surface< span class = "op" > );< / span > < / span >
< span id = "cb16-7" > < a href = "#cb16-7" > < / a > cr < span class = "op" > =< / span > cairo_create < span class = "op" > (< / span > surface< span class = "op" > );< / span > < / span >
< span id = "cb16-8" > < a href = "#cb16-8" > < / a > cairo_rectangle < span class = "op" > (< / span > cr< span class = "op" > ,< / span > start_x< span class = "op" > ,< / span > start_y< span class = "op" > ,< / span > offset_x< span class = "op" > ,< / span > offset_y< span class = "op" > );< / span > < / span >
< span id = "cb16-9" > < a href = "#cb16-9" > < / a > cairo_set_line_width < span class = "op" > (< / span > cr< span class = "op" > ,< / span > < span class = "fl" > 6.0< / span > < span class = "op" > );< / span > < / span >
< span id = "cb16-10" > < a href = "#cb16-10" > < / a > cairo_stroke < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb16-11" > < a href = "#cb16-11" > < / a > cairo_destroy < span class = "op" > (< / span > cr< span class = "op" > );< / span > < / span >
< span id = "cb16-12" > < a href = "#cb16-12" > < / a > gtk_widget_queue_draw < span class = "op" > (< / span > da< span class = "op" > );< / span > < / span >
< span id = "cb16-13" > < a href = "#cb16-13" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< ul >
< li > Restores < code > surface< / code > from < code > surface_save< / code > .< / li >
< li > Draws a rectangle with thick lines.< / li >
< li > Calls < code > gtk_widget_queue_draw< / code > to add the GtkDrawingArea
to the queue to redraw.< / li >
< / ul >
< h2 id = "build-and-run" > Build and run< / h2 >
< p > Download the < a
href="https://github.com/ToshioCP/Gtk4-tutorial">repository< / a > . Change
your current directory to < code > src/custom_drawing< / code > . Run meson and
ninja to build the program. Type < code > _build/rect< / code > to run the
program. Try to draw rectangles.< / p >
< pre > < code > $ cd src/custom_drawing
$ meson setup _build
$ ninja -C _build
$ _build/rect< / code > < / pre >
< figure >
< img src = "image/rect.png" alt = "The screen of rect program" / >
< figcaption aria-hidden = "true" > The screen of rect program< / figcaption >
< / figure >
2023-12-10 09:39:32 +01:00
< / div >
< / div >
2022-04-21 16:53:28 +02:00
< / div >
< script src = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity = "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin = "anonymous" > < / script >
< / body >
< / html >