mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
7b14d03a24
Update the distribution package information.
345 lines
25 KiB
HTML
345 lines
25 KiB
HTML
<!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" />
|
||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
|
||
<title>GTK 4 tutorial</title>
|
||
<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; }
|
||
}
|
||
@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="sec23.html">Prev: section23</a>
|
||
</li>
|
||
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="sec25.html">Next: section25</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
<div class="row justify-content-center">
|
||
<div class="col-xl-10 col-xxl-9">
|
||
<h1 id="gtkdrawingarea-and-cairo">GtkDrawingArea and Cairo</h1>
|
||
<p>If you want to draw shapes or paint images dynamically on the screen,
|
||
use the GtkDrawingArea widget.</p>
|
||
<p>GtkDrawingArea provides a cairo drawing context. You can draw images
|
||
with cairo library functions. This section describes:</p>
|
||
<ol type="1">
|
||
<li>Cairo, but briefly</li>
|
||
<li>GtkDrawingArea, with a very simple example.</li>
|
||
</ol>
|
||
<h2 id="cairo">Cairo</h2>
|
||
<p>Cairo is a drawing library for two dimensional graphics. There are a
|
||
lot of documents on <a href="https://www.cairographics.org/">Cairo’s
|
||
website</a>. If you aren’t familiar with Cairo, it is worth reading the
|
||
<a href="https://www.cairographics.org/tutorial/">tutorial</a>.</p>
|
||
<p>The following is an introduction to the Cairo library. First, you
|
||
need to know surfaces, sources, masks, destinations, cairo context and
|
||
transformations.</p>
|
||
<ul>
|
||
<li>A surface represents an image. It is like a canvas. We can draw
|
||
shapes and images with different colors on surfaces.</li>
|
||
<li>The source pattern, or simply source, is like paint, which will be
|
||
transferred to destination surface by cairo functions.</li>
|
||
<li>The mask describes the area to be used in the copy;</li>
|
||
<li>The destination is a target surface;</li>
|
||
<li>The cairo context manages the transfer from source to destination,
|
||
through mask with its functions; For example, <code>cairo_stroke</code>
|
||
is a function to draw a path to the destination by the transfer.</li>
|
||
<li>A transformation can be applied before the transfer completes. The
|
||
transformation which is applied is called affine, which is a
|
||
mathematical term meaning transofrmations that preserve straight lines.
|
||
Scaling, rotating, reflecting, shearing and translating are examples of
|
||
affine transformations. They are mathematically represented by matrix
|
||
multiplication and vector addition. In this section we don’t use it,
|
||
instead we will only use the identity transformation. This means that
|
||
the coordinates in the source and mask are the same as the coordinates
|
||
in destination.</li>
|
||
</ul>
|
||
<figure>
|
||
<img src="image/cairo.png" alt="Stroke a rectangle" />
|
||
<figcaption aria-hidden="true">Stroke a rectangle</figcaption>
|
||
</figure>
|
||
<p>The instruction is as follows:</p>
|
||
<ol type="1">
|
||
<li>Create a surface. This will be the destination.</li>
|
||
<li>Create a cairo context with the surface, the surface will be the
|
||
destination of the context.</li>
|
||
<li>Create a source pattern within the context.</li>
|
||
<li>Create paths, which are lines, rectangles, arcs, texts or more
|
||
complicated shapes in the mask.</li>
|
||
<li>Use a drawing operator such as <code>cairo_stroke</code> to transfer
|
||
the paint in the source to the destination.</li>
|
||
<li>Save the destination surface to a file if necessary.</li>
|
||
</ol>
|
||
<p>Here’s a simple example program that draws a small square and saves
|
||
it as a png file. The path of the file is
|
||
<code>src/misc/cairo.c</code>.</p>
|
||
<div class="sourceCode" id="cb1"><pre
|
||
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1"></a><span class="pp">#include </span><span class="im"><cairo.h></span></span>
|
||
<span id="cb1-2"><a href="#cb1-2"></a></span>
|
||
<span id="cb1-3"><a href="#cb1-3"></a><span class="dt">int</span></span>
|
||
<span id="cb1-4"><a href="#cb1-4"></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>
|
||
<span id="cb1-5"><a href="#cb1-5"></a><span class="op">{</span></span>
|
||
<span id="cb1-6"><a href="#cb1-6"></a> cairo_surface_t <span class="op">*</span>surface<span class="op">;</span></span>
|
||
<span id="cb1-7"><a href="#cb1-7"></a> cairo_t <span class="op">*</span>cr<span class="op">;</span></span>
|
||
<span id="cb1-8"><a href="#cb1-8"></a> <span class="dt">int</span> width <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></span>
|
||
<span id="cb1-9"><a href="#cb1-9"></a> <span class="dt">int</span> height <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></span>
|
||
<span id="cb1-10"><a href="#cb1-10"></a> <span class="dt">int</span> square_size <span class="op">=</span> <span class="fl">40.0</span><span class="op">;</span></span>
|
||
<span id="cb1-11"><a href="#cb1-11"></a></span>
|
||
<span id="cb1-12"><a href="#cb1-12"></a> <span class="co">/* Create surface and cairo */</span></span>
|
||
<span id="cb1-13"><a href="#cb1-13"></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="cb1-14"><a href="#cb1-14"></a> cr <span class="op">=</span> cairo_create <span class="op">(</span>surface<span class="op">);</span></span>
|
||
<span id="cb1-15"><a href="#cb1-15"></a></span>
|
||
<span id="cb1-16"><a href="#cb1-16"></a> <span class="co">/* Drawing starts here. */</span></span>
|
||
<span id="cb1-17"><a href="#cb1-17"></a> <span class="co">/* Paint the background white */</span></span>
|
||
<span id="cb1-18"><a href="#cb1-18"></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="cb1-19"><a href="#cb1-19"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb1-20"><a href="#cb1-20"></a> <span class="co">/* Draw a black rectangle */</span></span>
|
||
<span id="cb1-21"><a href="#cb1-21"></a> cairo_set_source_rgb <span class="op">(</span>cr<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 class="fl">0.0</span><span class="op">);</span></span>
|
||
<span id="cb1-22"><a href="#cb1-22"></a> cairo_set_line_width <span class="op">(</span>cr<span class="op">,</span> <span class="fl">2.0</span><span class="op">);</span></span>
|
||
<span id="cb1-23"><a href="#cb1-23"></a> cairo_rectangle <span class="op">(</span>cr<span class="op">,</span></span>
|
||
<span id="cb1-24"><a href="#cb1-24"></a> width<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
|
||
<span id="cb1-25"><a href="#cb1-25"></a> height<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
|
||
<span id="cb1-26"><a href="#cb1-26"></a> square_size<span class="op">,</span></span>
|
||
<span id="cb1-27"><a href="#cb1-27"></a> square_size<span class="op">);</span></span>
|
||
<span id="cb1-28"><a href="#cb1-28"></a> cairo_stroke <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb1-29"><a href="#cb1-29"></a></span>
|
||
<span id="cb1-30"><a href="#cb1-30"></a> <span class="co">/* Write the surface to a png file and clean up cairo and surface. */</span></span>
|
||
<span id="cb1-31"><a href="#cb1-31"></a> cairo_surface_write_to_png <span class="op">(</span>surface<span class="op">,</span> <span class="st">"rectangle.png"</span><span class="op">);</span></span>
|
||
<span id="cb1-32"><a href="#cb1-32"></a> cairo_destroy <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb1-33"><a href="#cb1-33"></a> cairo_surface_destroy <span class="op">(</span>surface<span class="op">);</span></span>
|
||
<span id="cb1-34"><a href="#cb1-34"></a></span>
|
||
<span id="cb1-35"><a href="#cb1-35"></a> <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
|
||
<span id="cb1-36"><a href="#cb1-36"></a><span class="op">}</span></span></code></pre></div>
|
||
<ul>
|
||
<li>1: Includes the header file of Cairo.</li>
|
||
<li>6: <code>cairo_surface_t</code> is the type of a surface.</li>
|
||
<li>7: <code>cairo_t</code> is the type of a cairo context.</li>
|
||
<li>8-10: <code>width</code> and <code>height</code> are the size of
|
||
<code>surface</code>. <code>square_size</code> is the size of a square
|
||
to be drawn on the surface.</li>
|
||
<li>13: <code>cairo_image_surface_create</code> creates an image
|
||
surface. <code>CAIRO_FORMAT_RGB24</code> is a constant which means that
|
||
each pixel has red, green and blue data, and each data point is an 8
|
||
bits number (for 24 bits in total). Modern displays have this type of
|
||
color depth. Width and height are in pixels and given as integers.</li>
|
||
<li>14: Creates cairo context. The surface given as an argument will be
|
||
the destination of the context.</li>
|
||
<li>18: <code>cairo_set_source_rgb</code> creates a source pattern,
|
||
which is a solid white paint. The second to fourth arguments are red,
|
||
green and blue color values respectively, and they are of type float.
|
||
The values are between zero (0.0) and one (1.0). Black is (0.0,0.0,0.0)
|
||
and white is (1.0,1.0,1.0).</li>
|
||
<li>19: <code>cairo_paint</code> copies everywhere in the source to
|
||
destination. The destination is filled with white pixels with this
|
||
command.</li>
|
||
<li>21: Sets the source color to black.</li>
|
||
<li>22: <code>cairo_set_line_width</code> sets the width of lines. In
|
||
this case, the line width is set to be two pixels and will end up that
|
||
same size. (It is because the transformation is identity. If the
|
||
transformation isn’t identity, for example scaling with the factor
|
||
three, the actual width in destination will be six (2x3=6) pixels.)</li>
|
||
<li>23: Draws a rectangle (square) on the mask. The square is located at
|
||
the center.</li>
|
||
<li>24: <code>cairo_stroke</code> transfers the source to destination
|
||
through the rectangle in the mask.</li>
|
||
<li>31: Outputs the image to a png file <code>rectangle.png</code>.</li>
|
||
<li>32: Destroys the context. At the same time the source is
|
||
destroyed.</li>
|
||
<li>33: Destroys the surface.</li>
|
||
</ul>
|
||
<p>To compile this, change your current directory to
|
||
<code>src/misc</code> and type the following.</p>
|
||
<pre><code>$ gcc `pkg-config --cflags cairo` cairo.c `pkg-config --libs cairo`</code></pre>
|
||
<p>s <img src="image/rectangle.png" alt="rectangle.png" /></p>
|
||
<p>See the <a href="https://www.cairographics.org/">Cairo’s website</a>
|
||
for further information.</p>
|
||
<h2 id="gtkdrawingarea">GtkDrawingArea</h2>
|
||
<p>The following is a very simple example.</p>
|
||
<div class="sourceCode" id="cb3"><pre
|
||
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1"></a><span class="pp">#include </span><span class="im"><gtk/gtk.h></span></span>
|
||
<span id="cb3-2"><a href="#cb3-2"></a></span>
|
||
<span id="cb3-3"><a href="#cb3-3"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb3-4"><a href="#cb3-4"></a>draw_function <span class="op">(</span>GtkDrawingArea <span class="op">*</span>area<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="cb3-5"><a href="#cb3-5"></a> <span class="dt">int</span> square_size <span class="op">=</span> <span class="fl">40.0</span><span class="op">;</span></span>
|
||
<span id="cb3-6"><a href="#cb3-6"></a></span>
|
||
<span id="cb3-7"><a href="#cb3-7"></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 class="co">/* white */</span></span>
|
||
<span id="cb3-8"><a href="#cb3-8"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb3-9"><a href="#cb3-9"></a> cairo_set_line_width <span class="op">(</span>cr<span class="op">,</span> <span class="fl">2.0</span><span class="op">);</span></span>
|
||
<span id="cb3-10"><a href="#cb3-10"></a> cairo_set_source_rgb <span class="op">(</span>cr<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 class="fl">0.0</span><span class="op">);</span> <span class="co">/* black */</span></span>
|
||
<span id="cb3-11"><a href="#cb3-11"></a> cairo_rectangle <span class="op">(</span>cr<span class="op">,</span></span>
|
||
<span id="cb3-12"><a href="#cb3-12"></a> width<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
|
||
<span id="cb3-13"><a href="#cb3-13"></a> height<span class="op">/</span><span class="fl">2.0</span> <span class="op">-</span> square_size<span class="op">/</span><span class="dv">2</span><span class="op">,</span></span>
|
||
<span id="cb3-14"><a href="#cb3-14"></a> square_size<span class="op">,</span></span>
|
||
<span id="cb3-15"><a href="#cb3-15"></a> square_size<span class="op">);</span></span>
|
||
<span id="cb3-16"><a href="#cb3-16"></a> cairo_stroke <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb3-17"><a href="#cb3-17"></a><span class="op">}</span></span>
|
||
<span id="cb3-18"><a href="#cb3-18"></a></span>
|
||
<span id="cb3-19"><a href="#cb3-19"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb3-20"><a href="#cb3-20"></a>app_activate <span class="op">(</span>GApplication <span class="op">*</span>app<span class="op">,</span> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb3-21"><a href="#cb3-21"></a> GtkWidget <span class="op">*</span>win <span class="op">=</span> gtk_application_window_new <span class="op">(</span>GTK_APPLICATION <span class="op">(</span>app<span class="op">));</span></span>
|
||
<span id="cb3-22"><a href="#cb3-22"></a> GtkWidget <span class="op">*</span>area <span class="op">=</span> gtk_drawing_area_new <span class="op">();</span></span>
|
||
<span id="cb3-23"><a href="#cb3-23"></a></span>
|
||
<span id="cb3-24"><a href="#cb3-24"></a> gtk_window_set_title <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">),</span> <span class="st">"da1"</span><span class="op">);</span></span>
|
||
<span id="cb3-25"><a href="#cb3-25"></a> gtk_drawing_area_set_draw_func <span class="op">(</span>GTK_DRAWING_AREA <span class="op">(</span>area<span class="op">),</span> draw_function<span class="op">,</span> NULL<span class="op">,</span> NULL<span class="op">);</span></span>
|
||
<span id="cb3-26"><a href="#cb3-26"></a> gtk_window_set_child <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">),</span> area<span class="op">);</span></span>
|
||
<span id="cb3-27"><a href="#cb3-27"></a></span>
|
||
<span id="cb3-28"><a href="#cb3-28"></a> gtk_window_present <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">));</span></span>
|
||
<span id="cb3-29"><a href="#cb3-29"></a><span class="op">}</span></span>
|
||
<span id="cb3-30"><a href="#cb3-30"></a></span>
|
||
<span id="cb3-31"><a href="#cb3-31"></a><span class="pp">#define APPLICATION_ID "com.github.ToshioCP.da1"</span></span>
|
||
<span id="cb3-32"><a href="#cb3-32"></a></span>
|
||
<span id="cb3-33"><a href="#cb3-33"></a><span class="dt">int</span></span>
|
||
<span id="cb3-34"><a href="#cb3-34"></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="cb3-35"><a href="#cb3-35"></a> GtkApplication <span class="op">*</span>app<span class="op">;</span></span>
|
||
<span id="cb3-36"><a href="#cb3-36"></a> <span class="dt">int</span> stat<span class="op">;</span></span>
|
||
<span id="cb3-37"><a href="#cb3-37"></a></span>
|
||
<span id="cb3-38"><a href="#cb3-38"></a> app <span class="op">=</span> gtk_application_new <span class="op">(</span>APPLICATION_ID<span class="op">,</span> G_APPLICATION_DEFAULT_FLAGS<span class="op">);</span></span>
|
||
<span id="cb3-39"><a href="#cb3-39"></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="cb3-40"><a href="#cb3-40"></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="cb3-41"><a href="#cb3-41"></a> g_object_unref <span class="op">(</span>app<span class="op">);</span></span>
|
||
<span id="cb3-42"><a href="#cb3-42"></a> <span class="cf">return</span> stat<span class="op">;</span></span>
|
||
<span id="cb3-43"><a href="#cb3-43"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>The function <code>main</code> is almost same as before. The two
|
||
functions <code>app_activate</code> and <code>draw_function</code> are
|
||
important in this example.</p>
|
||
<ul>
|
||
<li>22: Creates a GtkDrawingArea instance.</li>
|
||
<li>25: Sets a drawing function of the widget. GtkDrawingArea widget
|
||
uses the function <code>draw_function</code> to draw the contents of
|
||
itself whenever its necessary. For example, when a user drag a mouse
|
||
pointer and resize a top-level window, GtkDrawingArea also changes the
|
||
size. Then, the whole window needs to be redrawn. For the information of
|
||
<code>gtk_drawing_area_set_draw_func</code>, see <a
|
||
href="https://docs.gtk.org/gtk4/method.DrawingArea.set_draw_func.html">Gtk
|
||
API Reference – gtk_drawing_area_set_draw_func</a>.</li>
|
||
</ul>
|
||
<p>The drawing function has five parameters.</p>
|
||
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> drawing_function <span class="op">(</span>GtkDrawingArea <span class="op">*</span>drawing_area<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></span>
|
||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> gpointer user_data<span class="op">);</span></span></code></pre></div>
|
||
<p>The first parameter is the GtkDrawingArea widget. You can’t change
|
||
any properties, for example <code>content-width</code> or
|
||
<code>content-height</code>, in this function. The second parameter is a
|
||
cairo context given by the widget. The destination surface of the
|
||
context is connected to the contents of the widget. What you draw to
|
||
this surface will appear in the widget on the screen. The third and
|
||
fourth parameters are the size of the destination surface. Now, look at
|
||
the program again.</p>
|
||
<ul>
|
||
<li>3-17: The drawing function.</li>
|
||
<li>7-8: Sets the source to be white and paint the destination
|
||
white.</li>
|
||
<li>9: Sets the line width to be 2.</li>
|
||
<li>10: Sets the source to be black.</li>
|
||
<li>11-15: Adds a rectangle to the mask.</li>
|
||
<li>16: Draws the rectangle with black color to the destination.</li>
|
||
</ul>
|
||
<p>The program is src/misc/da1.c. Compile and run it, then a window with
|
||
a black rectangle (square) appears. Try resizing the window. The square
|
||
always appears at the center of the window because the drawing function
|
||
is invoked each time the window is resized.</p>
|
||
<figure>
|
||
<img src="image/da1.png" alt="Square in the window" />
|
||
<figcaption aria-hidden="true">Square in the window</figcaption>
|
||
</figure>
|
||
</div>
|
||
</div>
|
||
</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>
|