mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
534 lines
58 KiB
HTML
534 lines
58 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.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" 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>
|
||
<h1 id="combine-gtkdrawingarea-and-tfetextview">Combine GtkDrawingArea
|
||
and TfeTextView</h1>
|
||
<p>Now, we will make a new application which has GtkDrawingArea and
|
||
TfeTextView in it. Its name is “color”. If you write a name of a color
|
||
in TfeTextView and click on the <code>run</code> button, then the color
|
||
of GtkDrawingArea changes to the color given by you.</p>
|
||
<figure>
|
||
<img src="image/color.png" alt="color" />
|
||
<figcaption aria-hidden="true">color</figcaption>
|
||
</figure>
|
||
<p>The following colors are available. (without new line charactor)</p>
|
||
<ul>
|
||
<li>white</li>
|
||
<li>black</li>
|
||
<li>red</li>
|
||
<li>green</li>
|
||
<li>blue</li>
|
||
</ul>
|
||
<p>In addition the following two options are also available.</p>
|
||
<ul>
|
||
<li>light: Make the color of the drawing area lighter.</li>
|
||
<li>dark: Make the color of the drawing area darker.</li>
|
||
</ul>
|
||
<p>This application can only do very simple things. However, it tells us
|
||
that if we add powerful parser to it, we will be able to make it more
|
||
efficient. I want to show it to you in the later section by making a
|
||
turtle graphics language like Logo program language.</p>
|
||
<p>In this section, we focus on how to bind the two objects.</p>
|
||
<h2 id="color.ui-and-color.gresource.xml">Color.ui and
|
||
color.gresource.xml</h2>
|
||
<p>First, We need to make the ui file of the widgets. Title bar, four
|
||
buttons in the tool bar, textview and drawing area. The ui file is as
|
||
follows.</p>
|
||
<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>
|
||
<span id="cb1-2"><a href="#cb1-2"></a><<span class="kw">interface</span>></span>
|
||
<span id="cb1-3"><a href="#cb1-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="cb1-4"><a href="#cb1-4"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"title"</span>>color changer</<span class="kw">property</span>></span>
|
||
<span id="cb1-5"><a href="#cb1-5"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"default-width"</span>>600</<span class="kw">property</span>></span>
|
||
<span id="cb1-6"><a href="#cb1-6"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"default-height"</span>>400</<span class="kw">property</span>></span>
|
||
<span id="cb1-7"><a href="#cb1-7"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-8"><a href="#cb1-8"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkBox"</span><span class="ot"> id=</span><span class="st">"boxv"</span>></span>
|
||
<span id="cb1-9"><a href="#cb1-9"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"orientation"</span>>GTK_ORIENTATION_VERTICAL</<span class="kw">property</span>></span>
|
||
<span id="cb1-10"><a href="#cb1-10"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-11"><a href="#cb1-11"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkBox"</span><span class="ot"> id=</span><span class="st">"boxh1"</span>></span>
|
||
<span id="cb1-12"><a href="#cb1-12"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"orientation"</span>>GTK_ORIENTATION_HORIZONTAL</<span class="kw">property</span>></span>
|
||
<span id="cb1-13"><a href="#cb1-13"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-14"><a href="#cb1-14"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkLabel"</span><span class="ot"> id=</span><span class="st">"dmy1"</span>></span>
|
||
<span id="cb1-15"><a href="#cb1-15"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"width-chars"</span>>10</<span class="kw">property</span>></span>
|
||
<span id="cb1-16"><a href="#cb1-16"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-17"><a href="#cb1-17"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-18"><a href="#cb1-18"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-19"><a href="#cb1-19"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkButton"</span><span class="ot"> id=</span><span class="st">"btnr"</span>></span>
|
||
<span id="cb1-20"><a href="#cb1-20"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"label"</span>>Run</<span class="kw">property</span>></span>
|
||
<span id="cb1-21"><a href="#cb1-21"></a> <<span class="kw">signal</span><span class="ot"> name=</span><span class="st">"clicked"</span><span class="ot"> handler=</span><span class="st">"run_cb"</span>></<span class="kw">signal</span>></span>
|
||
<span id="cb1-22"><a href="#cb1-22"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-23"><a href="#cb1-23"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-24"><a href="#cb1-24"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-25"><a href="#cb1-25"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkButton"</span><span class="ot"> id=</span><span class="st">"btno"</span>></span>
|
||
<span id="cb1-26"><a href="#cb1-26"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"label"</span>>Open</<span class="kw">property</span>></span>
|
||
<span id="cb1-27"><a href="#cb1-27"></a> <<span class="kw">signal</span><span class="ot"> name=</span><span class="st">"clicked"</span><span class="ot"> handler=</span><span class="st">"open_cb"</span>></<span class="kw">signal</span>></span>
|
||
<span id="cb1-28"><a href="#cb1-28"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-29"><a href="#cb1-29"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-30"><a href="#cb1-30"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-31"><a href="#cb1-31"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkLabel"</span><span class="ot"> id=</span><span class="st">"dmy2"</span>></span>
|
||
<span id="cb1-32"><a href="#cb1-32"></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="cb1-33"><a href="#cb1-33"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-34"><a href="#cb1-34"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-35"><a href="#cb1-35"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-36"><a href="#cb1-36"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkButton"</span><span class="ot"> id=</span><span class="st">"btns"</span>></span>
|
||
<span id="cb1-37"><a href="#cb1-37"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"label"</span>>Save</<span class="kw">property</span>></span>
|
||
<span id="cb1-38"><a href="#cb1-38"></a> <<span class="kw">signal</span><span class="ot"> name=</span><span class="st">"clicked"</span><span class="ot"> handler=</span><span class="st">"save_cb"</span>></<span class="kw">signal</span>></span>
|
||
<span id="cb1-39"><a href="#cb1-39"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-40"><a href="#cb1-40"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-41"><a href="#cb1-41"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-42"><a href="#cb1-42"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkButton"</span><span class="ot"> id=</span><span class="st">"btnc"</span>></span>
|
||
<span id="cb1-43"><a href="#cb1-43"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"label"</span>>Close</<span class="kw">property</span>></span>
|
||
<span id="cb1-44"><a href="#cb1-44"></a> <<span class="kw">signal</span><span class="ot"> name=</span><span class="st">"clicked"</span><span class="ot"> handler=</span><span class="st">"close_cb"</span>></<span class="kw">signal</span>></span>
|
||
<span id="cb1-45"><a href="#cb1-45"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-46"><a href="#cb1-46"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-47"><a href="#cb1-47"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-48"><a href="#cb1-48"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkLabel"</span><span class="ot"> id=</span><span class="st">"dmy3"</span>></span>
|
||
<span id="cb1-49"><a href="#cb1-49"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"width-chars"</span>>10</<span class="kw">property</span>></span>
|
||
<span id="cb1-50"><a href="#cb1-50"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-51"><a href="#cb1-51"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-52"><a href="#cb1-52"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-53"><a href="#cb1-53"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-54"><a href="#cb1-54"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-55"><a href="#cb1-55"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkBox"</span><span class="ot"> id=</span><span class="st">"boxh2"</span>></span>
|
||
<span id="cb1-56"><a href="#cb1-56"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"orientation"</span>>GTK_ORIENTATION_HORIZONTAL</<span class="kw">property</span>></span>
|
||
<span id="cb1-57"><a href="#cb1-57"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"homogeneous"</span>>TRUE</<span class="kw">property</span>></span>
|
||
<span id="cb1-58"><a href="#cb1-58"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-59"><a href="#cb1-59"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkScrolledWindow"</span><span class="ot"> id=</span><span class="st">"scr"</span>></span>
|
||
<span id="cb1-60"><a href="#cb1-60"></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="cb1-61"><a href="#cb1-61"></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="cb1-62"><a href="#cb1-62"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-63"><a href="#cb1-63"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"TfeTextView"</span><span class="ot"> id=</span><span class="st">"tv"</span>></span>
|
||
<span id="cb1-64"><a href="#cb1-64"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"wrap-mode"</span>>GTK_WRAP_WORD_CHAR</<span class="kw">property</span>></span>
|
||
<span id="cb1-65"><a href="#cb1-65"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-66"><a href="#cb1-66"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-67"><a href="#cb1-67"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-68"><a href="#cb1-68"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-69"><a href="#cb1-69"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-70"><a href="#cb1-70"></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="cb1-71"><a href="#cb1-71"></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="cb1-72"><a href="#cb1-72"></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="cb1-73"><a href="#cb1-73"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-74"><a href="#cb1-74"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-75"><a href="#cb1-75"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-76"><a href="#cb1-76"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-77"><a href="#cb1-77"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-78"><a href="#cb1-78"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-79"><a href="#cb1-79"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-80"><a href="#cb1-80"></a></<span class="kw">interface</span>></span></code></pre></div>
|
||
<ul>
|
||
<li>10-53: The horizontal box <code>boxh1</code> makes a tool bar which
|
||
has four buttons, <code>Run</code>, <code>Open</code>, <code>Save</code>
|
||
and <code>Close</code>. This is similar to the <code>tfe</code> text
|
||
editor in <a href="sec9.html">Section 9</a>. There are two differences.
|
||
<code>Run</code> button replaces <code>New</code> button. A signal
|
||
element is added to each button object. It has “name” attribute which is
|
||
a signal name and “handler” attribute which is the name of its signal
|
||
handler. Options “-WI, –export-dynamic” CFLAG is necessary when you
|
||
compile the application. You can achieve this by adding “export_dynamic:
|
||
true” argument to the executable function in <code>meson.build</code>.
|
||
And be careful that the handler must be defined without ‘static’
|
||
class.</li>
|
||
<li>54-76: The horizontal box <code>boxh2</code> includes
|
||
GtkScrolledWindow and GtkDrawingArea. GtkBox has “homogeneous property”
|
||
with TRUE value, so the two children have the same width in the box.
|
||
TfeTextView is a child of GtkScrolledWindow.</li>
|
||
</ul>
|
||
<p>The xml file for the resource compiler is almost same as before. Just
|
||
substitute “color” for “tfe”.</p>
|
||
<div class="sourceCode" id="cb2"><pre
|
||
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>
|
||
<span id="cb2-2"><a href="#cb2-2"></a><<span class="kw">gresources</span>></span>
|
||
<span id="cb2-3"><a href="#cb2-3"></a> <<span class="kw">gresource</span><span class="ot"> prefix=</span><span class="st">"/com/github/ToshioCP/color"</span>></span>
|
||
<span id="cb2-4"><a href="#cb2-4"></a> <<span class="kw">file</span>>color.ui</<span class="kw">file</span>></span>
|
||
<span id="cb2-5"><a href="#cb2-5"></a> </<span class="kw">gresource</span>></span>
|
||
<span id="cb2-6"><a href="#cb2-6"></a></<span class="kw">gresources</span>></span></code></pre></div>
|
||
<h2 id="drawing-function-and-surface">Drawing function and surface</h2>
|
||
<p>The main point of this program is a drawing function.</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="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb3-2"><a href="#cb3-2"></a>draw_func <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> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb3-3"><a href="#cb3-3"></a> <span class="cf">if</span> <span class="op">(</span>surface<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb3-4"><a href="#cb3-4"></a> cairo_set_source_surface <span class="op">(</span>cr<span class="op">,</span> surface<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb3-5"><a href="#cb3-5"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb3-6"><a href="#cb3-6"></a> <span class="op">}</span></span>
|
||
<span id="cb3-7"><a href="#cb3-7"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>The <code>surface</code> variable in line 3 is a static variable.</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">static</span> cairo_surface_t <span class="op">*</span>surface <span class="op">=</span> NULL<span class="op">;</span></span></code></pre></div>
|
||
<p>The drawing function just copies the <code>surface</code> to its own
|
||
surface with the <code>cairo_paint</code> function. The surface (pointed
|
||
by the static variable <code>surface</code>) is built by the
|
||
<code>run</code> function.</p>
|
||
<div class="sourceCode" id="cb5"><pre
|
||
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>
|
||
<span id="cb5-2"><a href="#cb5-2"></a>run <span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-3"><a href="#cb5-3"></a> GtkTextBuffer <span class="op">*</span>tb <span class="op">=</span> gtk_text_view_get_buffer <span class="op">(</span>GTK_TEXT_VIEW <span class="op">(</span>tv<span class="op">));</span></span>
|
||
<span id="cb5-4"><a href="#cb5-4"></a> GtkTextIter start_iter<span class="op">;</span></span>
|
||
<span id="cb5-5"><a href="#cb5-5"></a> GtkTextIter end_iter<span class="op">;</span></span>
|
||
<span id="cb5-6"><a href="#cb5-6"></a> <span class="dt">char</span> <span class="op">*</span>contents<span class="op">;</span></span>
|
||
<span id="cb5-7"><a href="#cb5-7"></a> cairo_t <span class="op">*</span>cr<span class="op">;</span></span>
|
||
<span id="cb5-8"><a href="#cb5-8"></a></span>
|
||
<span id="cb5-9"><a href="#cb5-9"></a> gtk_text_buffer_get_bounds <span class="op">(</span>tb<span class="op">,</span> <span class="op">&</span>start_iter<span class="op">,</span> <span class="op">&</span>end_iter<span class="op">);</span></span>
|
||
<span id="cb5-10"><a href="#cb5-10"></a> contents <span class="op">=</span> gtk_text_buffer_get_text <span class="op">(</span>tb<span class="op">,</span> <span class="op">&</span>start_iter<span class="op">,</span> <span class="op">&</span>end_iter<span class="op">,</span> FALSE<span class="op">);</span></span>
|
||
<span id="cb5-11"><a href="#cb5-11"></a> <span class="cf">if</span> <span class="op">(</span>surface<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-12"><a href="#cb5-12"></a> cr <span class="op">=</span> cairo_create <span class="op">(</span>surface<span class="op">);</span></span>
|
||
<span id="cb5-13"><a href="#cb5-13"></a> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"red"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb5-14"><a href="#cb5-14"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb5-15"><a href="#cb5-15"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"green"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb5-16"><a href="#cb5-16"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb5-17"><a href="#cb5-17"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"blue"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb5-18"><a href="#cb5-18"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">);</span></span>
|
||
<span id="cb5-19"><a href="#cb5-19"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"white"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb5-20"><a href="#cb5-20"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">);</span></span>
|
||
<span id="cb5-21"><a href="#cb5-21"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"black"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb5-22"><a href="#cb5-22"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb5-23"><a href="#cb5-23"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"light"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb5-24"><a href="#cb5-24"></a> cairo_set_source_rgba <span class="op">(</span>cr<span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="fl">0.5</span><span class="op">);</span></span>
|
||
<span id="cb5-25"><a href="#cb5-25"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"dark"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb5-26"><a href="#cb5-26"></a> cairo_set_source_rgba <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="fl">0.5</span><span class="op">);</span></span>
|
||
<span id="cb5-27"><a href="#cb5-27"></a> <span class="cf">else</span></span>
|
||
<span id="cb5-28"><a href="#cb5-28"></a> cairo_set_source_surface <span class="op">(</span>cr<span class="op">,</span> surface<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb5-29"><a href="#cb5-29"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb5-30"><a href="#cb5-30"></a> cairo_destroy <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb5-31"><a href="#cb5-31"></a> <span class="op">}</span></span>
|
||
<span id="cb5-32"><a href="#cb5-32"></a> g_free <span class="op">(</span>contents<span class="op">);</span></span>
|
||
<span id="cb5-33"><a href="#cb5-33"></a><span class="op">}</span></span></code></pre></div>
|
||
<ul>
|
||
<li>9-10: Gets the string in the GtkTextBuffer and inserts it to
|
||
<code>contents</code>.</li>
|
||
<li>11: If the variable <code>surface</code> points a surface instance,
|
||
it is painted as follows.</li>
|
||
<li>12- 30: The source is set based on the string <code>contents</code>
|
||
and copied to the surface with <code>cairo_paint</code>.</li>
|
||
<li>24,26: Alpha channel is used in “light” and “dark” procedure.</li>
|
||
</ul>
|
||
<p>The drawing area just reflects the <code>surface</code>. But one
|
||
problem is resizing. If a user resizes the main window, the drawing area
|
||
is also resized. It makes size difference between the surface and the
|
||
drawing area. So, the surface needs to be resized to fit the drawing
|
||
area.</p>
|
||
<p>It is accomplished by connecting the “resize” signal on the drawing
|
||
area to a handler.</p>
|
||
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>g_signal_connect <span class="op">(</span>GTK_DRAWING_AREA <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></code></pre></div>
|
||
<p>The handler is as follows.</p>
|
||
<div class="sourceCode" id="cb7"><pre
|
||
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb7-2"><a href="#cb7-2"></a>resize_cb <span class="op">(</span>GtkDrawingArea <span class="op">*</span>drawing_area<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="cb7-3"><a href="#cb7-3"></a> <span class="cf">if</span> <span class="op">(</span>surface<span class="op">)</span></span>
|
||
<span id="cb7-4"><a href="#cb7-4"></a> cairo_surface_destroy <span class="op">(</span>surface<span class="op">);</span></span>
|
||
<span id="cb7-5"><a href="#cb7-5"></a> surface <span class="op">=</span> cairo_image_surface_create <span class="op">(</span>CAIRO_FORMAT_ARGB32<span class="op">,</span> width<span class="op">,</span> height<span class="op">);</span></span>
|
||
<span id="cb7-6"><a href="#cb7-6"></a> run <span class="op">();</span></span>
|
||
<span id="cb7-7"><a href="#cb7-7"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>If the variable <code>surface</code> sets a surface instance, it is
|
||
destroyed. A new surface is created and its size fits the drawing area.
|
||
The surface is assigned to the variable <code>surface</code>. The
|
||
function <code>run</code> is called and the surface is colored.</p>
|
||
<p>The signal is emitted when:</p>
|
||
<ul>
|
||
<li>The drawing area is realized (it appears on the display).</li>
|
||
<li>It is changed (resized) while realized</li>
|
||
</ul>
|
||
<p>So, the first surface is created when it is realized.</p>
|
||
<h2 id="colorapplication.c">Colorapplication.c</h2>
|
||
<p>This is the main file.</p>
|
||
<ul>
|
||
<li>Builds widgets by GtkBuilder.</li>
|
||
<li>Sets a drawing function for GtkDrawingArea. And connects a handler
|
||
to the “resize” signal on the GtkDrawingArea instance.</li>
|
||
<li>Implements each call back function. Particularly, <code>Run</code>
|
||
signal handler is the point in this program.</li>
|
||
</ul>
|
||
<p>The following is <code>colorapplication.c</code>.</p>
|
||
<div class="sourceCode" id="cb8"><pre
|
||
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb8-1"><a href="#cb8-1"></a><span class="pp">#include </span><span class="im"><gtk/gtk.h></span></span>
|
||
<span id="cb8-2"><a href="#cb8-2"></a><span class="pp">#include </span><span class="im">"../tfetextview/tfetextview.h"</span></span>
|
||
<span id="cb8-3"><a href="#cb8-3"></a></span>
|
||
<span id="cb8-4"><a href="#cb8-4"></a><span class="dt">static</span> GtkWidget <span class="op">*</span>win<span class="op">;</span></span>
|
||
<span id="cb8-5"><a href="#cb8-5"></a><span class="dt">static</span> GtkWidget <span class="op">*</span>tv<span class="op">;</span></span>
|
||
<span id="cb8-6"><a href="#cb8-6"></a><span class="dt">static</span> GtkWidget <span class="op">*</span>da<span class="op">;</span></span>
|
||
<span id="cb8-7"><a href="#cb8-7"></a></span>
|
||
<span id="cb8-8"><a href="#cb8-8"></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="cb8-9"><a href="#cb8-9"></a></span>
|
||
<span id="cb8-10"><a href="#cb8-10"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb8-11"><a href="#cb8-11"></a>run <span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-12"><a href="#cb8-12"></a> GtkTextBuffer <span class="op">*</span>tb <span class="op">=</span> gtk_text_view_get_buffer <span class="op">(</span>GTK_TEXT_VIEW <span class="op">(</span>tv<span class="op">));</span></span>
|
||
<span id="cb8-13"><a href="#cb8-13"></a> GtkTextIter start_iter<span class="op">;</span></span>
|
||
<span id="cb8-14"><a href="#cb8-14"></a> GtkTextIter end_iter<span class="op">;</span></span>
|
||
<span id="cb8-15"><a href="#cb8-15"></a> <span class="dt">char</span> <span class="op">*</span>contents<span class="op">;</span></span>
|
||
<span id="cb8-16"><a href="#cb8-16"></a> cairo_t <span class="op">*</span>cr<span class="op">;</span></span>
|
||
<span id="cb8-17"><a href="#cb8-17"></a></span>
|
||
<span id="cb8-18"><a href="#cb8-18"></a> gtk_text_buffer_get_bounds <span class="op">(</span>tb<span class="op">,</span> <span class="op">&</span>start_iter<span class="op">,</span> <span class="op">&</span>end_iter<span class="op">);</span></span>
|
||
<span id="cb8-19"><a href="#cb8-19"></a> contents <span class="op">=</span> gtk_text_buffer_get_text <span class="op">(</span>tb<span class="op">,</span> <span class="op">&</span>start_iter<span class="op">,</span> <span class="op">&</span>end_iter<span class="op">,</span> FALSE<span class="op">);</span></span>
|
||
<span id="cb8-20"><a href="#cb8-20"></a> <span class="cf">if</span> <span class="op">(</span>surface<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-21"><a href="#cb8-21"></a> cr <span class="op">=</span> cairo_create <span class="op">(</span>surface<span class="op">);</span></span>
|
||
<span id="cb8-22"><a href="#cb8-22"></a> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"red"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb8-23"><a href="#cb8-23"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb8-24"><a href="#cb8-24"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"green"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb8-25"><a href="#cb8-25"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb8-26"><a href="#cb8-26"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"blue"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb8-27"><a href="#cb8-27"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">);</span></span>
|
||
<span id="cb8-28"><a href="#cb8-28"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"white"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb8-29"><a href="#cb8-29"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">);</span></span>
|
||
<span id="cb8-30"><a href="#cb8-30"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"black"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb8-31"><a href="#cb8-31"></a> cairo_set_source_rgb <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb8-32"><a href="#cb8-32"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"light"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb8-33"><a href="#cb8-33"></a> cairo_set_source_rgba <span class="op">(</span>cr<span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="fl">0.5</span><span class="op">);</span></span>
|
||
<span id="cb8-34"><a href="#cb8-34"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>g_strcmp0 <span class="op">(</span><span class="st">"dark"</span><span class="op">,</span> contents<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
|
||
<span id="cb8-35"><a href="#cb8-35"></a> cairo_set_source_rgba <span class="op">(</span>cr<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="fl">0.5</span><span class="op">);</span></span>
|
||
<span id="cb8-36"><a href="#cb8-36"></a> <span class="cf">else</span></span>
|
||
<span id="cb8-37"><a href="#cb8-37"></a> cairo_set_source_surface <span class="op">(</span>cr<span class="op">,</span> surface<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb8-38"><a href="#cb8-38"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb8-39"><a href="#cb8-39"></a> cairo_destroy <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb8-40"><a href="#cb8-40"></a> <span class="op">}</span></span>
|
||
<span id="cb8-41"><a href="#cb8-41"></a> g_free <span class="op">(</span>contents<span class="op">);</span></span>
|
||
<span id="cb8-42"><a href="#cb8-42"></a><span class="op">}</span></span>
|
||
<span id="cb8-43"><a href="#cb8-43"></a></span>
|
||
<span id="cb8-44"><a href="#cb8-44"></a><span class="dt">void</span></span>
|
||
<span id="cb8-45"><a href="#cb8-45"></a>run_cb <span class="op">(</span>GtkWidget <span class="op">*</span>btnr<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-46"><a href="#cb8-46"></a> run <span class="op">();</span></span>
|
||
<span id="cb8-47"><a href="#cb8-47"></a> gtk_widget_queue_draw <span class="op">(</span>GTK_WIDGET <span class="op">(</span>da<span class="op">));</span></span>
|
||
<span id="cb8-48"><a href="#cb8-48"></a><span class="op">}</span></span>
|
||
<span id="cb8-49"><a href="#cb8-49"></a></span>
|
||
<span id="cb8-50"><a href="#cb8-50"></a><span class="dt">void</span></span>
|
||
<span id="cb8-51"><a href="#cb8-51"></a>open_cb <span class="op">(</span>GtkWidget <span class="op">*</span>btno<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-52"><a href="#cb8-52"></a> tfe_text_view_open <span class="op">(</span>TFE_TEXT_VIEW <span class="op">(</span>tv<span class="op">),</span> GTK_WINDOW <span class="op">(</span>win<span class="op">));</span></span>
|
||
<span id="cb8-53"><a href="#cb8-53"></a><span class="op">}</span></span>
|
||
<span id="cb8-54"><a href="#cb8-54"></a></span>
|
||
<span id="cb8-55"><a href="#cb8-55"></a><span class="dt">void</span></span>
|
||
<span id="cb8-56"><a href="#cb8-56"></a>save_cb <span class="op">(</span>GtkWidget <span class="op">*</span>btns<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-57"><a href="#cb8-57"></a> tfe_text_view_save <span class="op">(</span>TFE_TEXT_VIEW <span class="op">(</span>tv<span class="op">));</span></span>
|
||
<span id="cb8-58"><a href="#cb8-58"></a><span class="op">}</span></span>
|
||
<span id="cb8-59"><a href="#cb8-59"></a></span>
|
||
<span id="cb8-60"><a href="#cb8-60"></a><span class="dt">void</span></span>
|
||
<span id="cb8-61"><a href="#cb8-61"></a>close_cb <span class="op">(</span>GtkWidget <span class="op">*</span>btnc<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-62"><a href="#cb8-62"></a> gtk_window_destroy <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">));</span></span>
|
||
<span id="cb8-63"><a href="#cb8-63"></a><span class="op">}</span></span>
|
||
<span id="cb8-64"><a href="#cb8-64"></a></span>
|
||
<span id="cb8-65"><a href="#cb8-65"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb8-66"><a href="#cb8-66"></a>resize_cb <span class="op">(</span>GtkDrawingArea <span class="op">*</span>drawing_area<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-67"><a href="#cb8-67"></a> <span class="cf">if</span> <span class="op">(</span>surface<span class="op">)</span></span>
|
||
<span id="cb8-68"><a href="#cb8-68"></a> cairo_surface_destroy <span class="op">(</span>surface<span class="op">);</span></span>
|
||
<span id="cb8-69"><a href="#cb8-69"></a> surface <span class="op">=</span> cairo_image_surface_create <span class="op">(</span>CAIRO_FORMAT_ARGB32<span class="op">,</span> width<span class="op">,</span> height<span class="op">);</span></span>
|
||
<span id="cb8-70"><a href="#cb8-70"></a> run <span class="op">();</span></span>
|
||
<span id="cb8-71"><a href="#cb8-71"></a><span class="op">}</span></span>
|
||
<span id="cb8-72"><a href="#cb8-72"></a></span>
|
||
<span id="cb8-73"><a href="#cb8-73"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb8-74"><a href="#cb8-74"></a>draw_func <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> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-75"><a href="#cb8-75"></a> <span class="cf">if</span> <span class="op">(</span>surface<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-76"><a href="#cb8-76"></a> cairo_set_source_surface <span class="op">(</span>cr<span class="op">,</span> surface<span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span>
|
||
<span id="cb8-77"><a href="#cb8-77"></a> cairo_paint <span class="op">(</span>cr<span class="op">);</span></span>
|
||
<span id="cb8-78"><a href="#cb8-78"></a> <span class="op">}</span></span>
|
||
<span id="cb8-79"><a href="#cb8-79"></a><span class="op">}</span></span>
|
||
<span id="cb8-80"><a href="#cb8-80"></a></span>
|
||
<span id="cb8-81"><a href="#cb8-81"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb8-82"><a href="#cb8-82"></a>app_activate <span class="op">(</span>GApplication <span class="op">*</span>application<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-83"><a href="#cb8-83"></a> gtk_window_present <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">));</span></span>
|
||
<span id="cb8-84"><a href="#cb8-84"></a><span class="op">}</span></span>
|
||
<span id="cb8-85"><a href="#cb8-85"></a></span>
|
||
<span id="cb8-86"><a href="#cb8-86"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb8-87"><a href="#cb8-87"></a>app_startup <span class="op">(</span>GApplication <span class="op">*</span>application<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-88"><a href="#cb8-88"></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="cb8-89"><a href="#cb8-89"></a> GtkBuilder <span class="op">*</span>build<span class="op">;</span></span>
|
||
<span id="cb8-90"><a href="#cb8-90"></a> GdkDisplay <span class="op">*</span>display<span class="op">;</span></span>
|
||
<span id="cb8-91"><a href="#cb8-91"></a></span>
|
||
<span id="cb8-92"><a href="#cb8-92"></a> build <span class="op">=</span> gtk_builder_new_from_resource <span class="op">(</span><span class="st">"/com/github/ToshioCP/color/color.ui"</span><span class="op">);</span></span>
|
||
<span id="cb8-93"><a href="#cb8-93"></a> win <span class="op">=</span> GTK_WIDGET <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="cb8-94"><a href="#cb8-94"></a> gtk_window_set_application <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">),</span> app<span class="op">);</span></span>
|
||
<span id="cb8-95"><a href="#cb8-95"></a> tv <span class="op">=</span> GTK_WIDGET <span class="op">(</span>gtk_builder_get_object <span class="op">(</span>build<span class="op">,</span> <span class="st">"tv"</span><span class="op">));</span></span>
|
||
<span id="cb8-96"><a href="#cb8-96"></a> da <span class="op">=</span> GTK_WIDGET <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="cb8-97"><a href="#cb8-97"></a> g_object_unref<span class="op">(</span>build<span class="op">);</span></span>
|
||
<span id="cb8-98"><a href="#cb8-98"></a> g_signal_connect <span class="op">(</span>GTK_DRAWING_AREA <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="cb8-99"><a href="#cb8-99"></a> gtk_drawing_area_set_draw_func <span class="op">(</span>GTK_DRAWING_AREA <span class="op">(</span>da<span class="op">),</span> draw_func<span class="op">,</span> NULL<span class="op">,</span> NULL<span class="op">);</span></span>
|
||
<span id="cb8-100"><a href="#cb8-100"></a></span>
|
||
<span id="cb8-101"><a href="#cb8-101"></a> display <span class="op">=</span> gdk_display_get_default <span class="op">();</span></span>
|
||
<span id="cb8-102"><a href="#cb8-102"></a> GtkCssProvider <span class="op">*</span>provider <span class="op">=</span> gtk_css_provider_new <span class="op">();</span></span>
|
||
<span id="cb8-103"><a href="#cb8-103"></a> gtk_css_provider_load_from_data <span class="op">(</span>provider<span class="op">,</span> <span class="st">"textview {padding: 10px; font-family: monospace; font-size: 12pt;}"</span><span class="op">,</span> <span class="op">-</span><span class="dv">1</span><span class="op">);</span></span>
|
||
<span id="cb8-104"><a href="#cb8-104"></a> gtk_style_context_add_provider_for_display <span class="op">(</span>display<span class="op">,</span> GTK_STYLE_PROVIDER <span class="op">(</span>provider<span class="op">),</span> GTK_STYLE_PROVIDER_PRIORITY_USER<span class="op">);</span></span>
|
||
<span id="cb8-105"><a href="#cb8-105"></a><span class="op">}</span></span>
|
||
<span id="cb8-106"><a href="#cb8-106"></a></span>
|
||
<span id="cb8-107"><a href="#cb8-107"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb8-108"><a href="#cb8-108"></a>app_shutdown <span class="op">(</span>GApplication <span class="op">*</span>application<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-109"><a href="#cb8-109"></a> <span class="cf">if</span> <span class="op">(</span>surface<span class="op">)</span></span>
|
||
<span id="cb8-110"><a href="#cb8-110"></a> cairo_surface_destroy <span class="op">(</span>surface<span class="op">);</span></span>
|
||
<span id="cb8-111"><a href="#cb8-111"></a><span class="op">}</span></span>
|
||
<span id="cb8-112"><a href="#cb8-112"></a></span>
|
||
<span id="cb8-113"><a href="#cb8-113"></a><span class="pp">#define APPLICATION_ID "com.github.ToshioCP.color"</span></span>
|
||
<span id="cb8-114"><a href="#cb8-114"></a></span>
|
||
<span id="cb8-115"><a href="#cb8-115"></a><span class="dt">int</span></span>
|
||
<span id="cb8-116"><a href="#cb8-116"></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="cb8-117"><a href="#cb8-117"></a> GtkApplication <span class="op">*</span>app<span class="op">;</span></span>
|
||
<span id="cb8-118"><a href="#cb8-118"></a> <span class="dt">int</span> stat<span class="op">;</span></span>
|
||
<span id="cb8-119"><a href="#cb8-119"></a></span>
|
||
<span id="cb8-120"><a href="#cb8-120"></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="cb8-121"><a href="#cb8-121"></a></span>
|
||
<span id="cb8-122"><a href="#cb8-122"></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="cb8-123"><a href="#cb8-123"></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="cb8-124"><a href="#cb8-124"></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="cb8-125"><a href="#cb8-125"></a></span>
|
||
<span id="cb8-126"><a href="#cb8-126"></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="cb8-127"><a href="#cb8-127"></a> g_object_unref <span class="op">(</span>app<span class="op">);</span></span>
|
||
<span id="cb8-128"><a href="#cb8-128"></a> <span class="cf">return</span> stat<span class="op">;</span></span>
|
||
<span id="cb8-129"><a href="#cb8-129"></a><span class="op">}</span></span></code></pre></div>
|
||
<ul>
|
||
<li>4-8: Win, tv, da and surface are defined as static variables.</li>
|
||
<li>10-42: Run function.</li>
|
||
<li>44-63: Handlers for button signals.</li>
|
||
<li>65-71: Resize handler.</li>
|
||
<li>73-79: Drawing function.</li>
|
||
<li>81-84: Application activate handler. It just shows the main
|
||
window.</li>
|
||
<li>86-105: Application startup handler.</li>
|
||
<li>92- 97: It builds widgets according to the ui resource. The static
|
||
variables win, tv and da are assigned instances.</li>
|
||
<li>98: Connects “resize” signal and a handler.</li>
|
||
<li>99: Drawing function is set.</li>
|
||
<li>101-104: CSS for textview padding is set.</li>
|
||
<li>107-111: Application shutdown handler. If there exists a surface
|
||
instance, it will be destroyed.</li>
|
||
<li>116-129: A function <code>main</code>. It creates a new application
|
||
instance. And connects three signals startup, shutdown and activate to
|
||
their handlers. It runs the application. It releases the reference to
|
||
the application and returns with <code>stat</code> value.</li>
|
||
</ul>
|
||
<h2 id="meson.build">Meson.build</h2>
|
||
<p>This file is almost same as before. An argument “export_dynamic:
|
||
true” is added to executable function.</p>
|
||
<div class="sourceCode" id="cb9"><pre
|
||
class="sourceCode numberSource numberLines"><code class="sourceCode"><span id="cb9-1"><a href="#cb9-1"></a>project('color', 'c')</span>
|
||
<span id="cb9-2"><a href="#cb9-2"></a></span>
|
||
<span id="cb9-3"><a href="#cb9-3"></a>gtkdep = dependency('gtk4')</span>
|
||
<span id="cb9-4"><a href="#cb9-4"></a></span>
|
||
<span id="cb9-5"><a href="#cb9-5"></a>gnome=import('gnome')</span>
|
||
<span id="cb9-6"><a href="#cb9-6"></a>resources = gnome.compile_resources('resources','color.gresource.xml')</span>
|
||
<span id="cb9-7"><a href="#cb9-7"></a></span>
|
||
<span id="cb9-8"><a href="#cb9-8"></a>sourcefiles=files('colorapplication.c', '../tfetextview/tfetextview.c')</span>
|
||
<span id="cb9-9"><a href="#cb9-9"></a></span>
|
||
<span id="cb9-10"><a href="#cb9-10"></a>executable('color', sourcefiles, resources, dependencies: gtkdep, export_dynamic: true)</span></code></pre></div>
|
||
<h2 id="build-and-try">Build and try</h2>
|
||
<p>Type the following to compile the program.</p>
|
||
<pre><code>$ meson _build
|
||
$ ninja -C _build</code></pre>
|
||
<p>The application is made in <code>_build</code> directory. Type the
|
||
following to execute it.</p>
|
||
<pre><code>$ _build/color</code></pre>
|
||
<p>Type “red”, “green”, “blue”, “white”, black”, “light” or “dark” in
|
||
the TfeTextView. No new line charactor is needed. Then, click on the
|
||
<code>Run</code> button. Make sure the color of GtkDrawingArea
|
||
changes.</p>
|
||
<p>In this program TfeTextView is used to change the color. You can use
|
||
buttons or menus instead of textview. Probably it is more appropriate.
|
||
Using textview is unnatural. It is a good practice to make such
|
||
application by yourself.</p>
|
||
</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>
|