mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
644 lines
61 KiB
HTML
644 lines
61 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="sec19.html">Prev: section19</a>
|
||
</li>
|
||
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="sec21.html">Next: section21</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
<h1 id="composite-widgets-and-alert-dialog">Composite widgets and alert
|
||
dialog</h1>
|
||
<p>The source files are in the <a
|
||
href="https://github.com/ToshioCP/Gtk4-tutorial">Gtk4 tutorial GitHub
|
||
repository</a>. Download it and see <code>src/tfe6</code> directory.</p>
|
||
<h2 id="an-outline-of-new-tfe-text-editor">An outline of new Tfe text
|
||
editor</h2>
|
||
<p>Tfe text editor will be restructured. The program is divided into six
|
||
parts.</p>
|
||
<ul>
|
||
<li>Main program: the C main function.</li>
|
||
<li>TfeApplication object: It is like GtkApplication but keeps GSettings
|
||
and CSS Provider.</li>
|
||
<li>TfeWindow object: It is a window with buttons and a notebook.</li>
|
||
<li>TfePref object: A preference dialog.</li>
|
||
<li>TfeAlert object: An alert dialog.</li>
|
||
<li>pdf2css.h and pdf2css.c: Font and CSS utility functions.</li>
|
||
</ul>
|
||
<p>This section describes TfeAlert. Others will be explained in the
|
||
following sections.</p>
|
||
<h2 id="composite-widgets">Composite widgets</h2>
|
||
<p>The alert dialog is like this:</p>
|
||
<figure>
|
||
<img src="image/alert.png" alt="Alert dialog" />
|
||
<figcaption aria-hidden="true">Alert dialog</figcaption>
|
||
</figure>
|
||
<p>Tfe uses it when a user quits the application or closes a notebook
|
||
without saving data to files.</p>
|
||
<p>The dialog has a title, buttons, an icon and a message. Therefore, it
|
||
consists of several widgets. Such dialog is called a composite
|
||
widget.</p>
|
||
<p>Composite widgets are defined with template XMLs. The class is built
|
||
in the class initialization function and the instances are built and
|
||
desposed by the following functions.</p>
|
||
<ul>
|
||
<li>gtk_widget_init_template</li>
|
||
<li>gtk_widget_dispose_template</li>
|
||
</ul>
|
||
<p>TfeAlert is a good example to know composite widgets. It is defined
|
||
with the three files.</p>
|
||
<ul>
|
||
<li>tfealert.ui: XML file</li>
|
||
<li>tfealert.h: Header file</li>
|
||
<li>tfealert.c: C program file</li>
|
||
</ul>
|
||
<h2 id="the-xml-file">The XML file</h2>
|
||
<p>A template tag is used in a composite widget XML.</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">template</span><span class="ot"> class=</span><span class="st">"TfeAlert"</span><span class="ot"> parent=</span><span class="st">"GtkWindow"</span>></span>
|
||
<span id="cb1-4"><a href="#cb1-4"></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="cb1-5"><a href="#cb1-5"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"modal"</span>>TRUE</<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">"titlebar"</span>></span>
|
||
<span id="cb1-7"><a href="#cb1-7"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkHeaderBar"</span>></span>
|
||
<span id="cb1-8"><a href="#cb1-8"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"show-title-buttons"</span>>FALSE</<span class="kw">property</span>></span>
|
||
<span id="cb1-9"><a href="#cb1-9"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"title-widget"</span>></span>
|
||
<span id="cb1-10"><a href="#cb1-10"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkLabel"</span><span class="ot"> id=</span><span class="st">"lb_title"</span>></span>
|
||
<span id="cb1-11"><a href="#cb1-11"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"label"</span>>Are you sure?</<span class="kw">property</span>></span>
|
||
<span id="cb1-12"><a href="#cb1-12"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"single-line-mode"</span>>True</<span class="kw">property</span>></span>
|
||
<span id="cb1-13"><a href="#cb1-13"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-14"><a href="#cb1-14"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb1-15"><a href="#cb1-15"></a> <<span class="kw">child</span><span class="ot"> type=</span><span class="st">"start"</span>></span>
|
||
<span id="cb1-16"><a href="#cb1-16"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkButton"</span><span class="ot"> id=</span><span class="st">"btn_cancel"</span>></span>
|
||
<span id="cb1-17"><a href="#cb1-17"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"label"</span>>Cancel</<span class="kw">property</span>></span>
|
||
<span id="cb1-18"><a href="#cb1-18"></a> <<span class="kw">style</span>></span>
|
||
<span id="cb1-19"><a href="#cb1-19"></a> <<span class="kw">class</span><span class="ot"> name=</span><span class="st">"suggested-action"</span>/></span>
|
||
<span id="cb1-20"><a href="#cb1-20"></a> </<span class="kw">style</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">"cancel_cb"</span><span class="ot"> swapped=</span><span class="st">"TRUE"</span><span class="ot"> object=</span><span class="st">"TfeAlert"</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 class="ot"> type=</span><span class="st">"end"</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">"btn_accept"</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>>Close</<span class="kw">property</span>></span>
|
||
<span id="cb1-27"><a href="#cb1-27"></a> <<span class="kw">style</span>></span>
|
||
<span id="cb1-28"><a href="#cb1-28"></a> <<span class="kw">class</span><span class="ot"> name=</span><span class="st">"destructive-action"</span>/></span>
|
||
<span id="cb1-29"><a href="#cb1-29"></a> </<span class="kw">style</span>></span>
|
||
<span id="cb1-30"><a href="#cb1-30"></a> <<span class="kw">signal</span><span class="ot"> name=</span><span class="st">"clicked"</span><span class="ot"> handler=</span><span class="st">"accept_cb"</span><span class="ot"> swapped=</span><span class="st">"TRUE"</span><span class="ot"> object=</span><span class="st">"TfeAlert"</span>></<span class="kw">signal</span>></span>
|
||
<span id="cb1-31"><a href="#cb1-31"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-32"><a href="#cb1-32"></a> </<span class="kw">child</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">property</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">"GtkBox"</span>></span>
|
||
<span id="cb1-37"><a href="#cb1-37"></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-38"><a href="#cb1-38"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"spacing"</span>>12</<span class="kw">property</span>></span>
|
||
<span id="cb1-39"><a href="#cb1-39"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"margin-top"</span>>12</<span class="kw">property</span>></span>
|
||
<span id="cb1-40"><a href="#cb1-40"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"margin-bottom"</span>>12</<span class="kw">property</span>></span>
|
||
<span id="cb1-41"><a href="#cb1-41"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"margin-start"</span>>12</<span class="kw">property</span>></span>
|
||
<span id="cb1-42"><a href="#cb1-42"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"margin-end"</span>>12</<span class="kw">property</span>></span>
|
||
<span id="cb1-43"><a href="#cb1-43"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-44"><a href="#cb1-44"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkImage"</span>></span>
|
||
<span id="cb1-45"><a href="#cb1-45"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"icon-name"</span>>dialog-warning</<span class="kw">property</span>></span>
|
||
<span id="cb1-46"><a href="#cb1-46"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"icon-size"</span>>GTK_ICON_SIZE_LARGE</<span class="kw">property</span>></span>
|
||
<span id="cb1-47"><a href="#cb1-47"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-48"><a href="#cb1-48"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-49"><a href="#cb1-49"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb1-50"><a href="#cb1-50"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkLabel"</span><span class="ot"> id=</span><span class="st">"lb_message"</span>></span>
|
||
<span id="cb1-51"><a href="#cb1-51"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb1-52"><a href="#cb1-52"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb1-53"><a href="#cb1-53"></a> </<span class="kw">object</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">template</span>></span>
|
||
<span id="cb1-56"><a href="#cb1-56"></a></<span class="kw">interface</span>></span></code></pre></div>
|
||
<ul>
|
||
<li>3: A template tag defines a composite widget. The class attribute
|
||
tells the class name of the composite widget. The parent attribute tells
|
||
the parent class of the composite widget. So, TfeAlert is a child class
|
||
of GtkWindow. A parent attribute is an option and you can leave it out.
|
||
But it is recommended to write it in the template tag.</li>
|
||
<li>4-6: Its three properties are defined. These properties are
|
||
inherited from GtkWindow. The titlebar property has a widget for a
|
||
custom title bar. The typical widget is GtkHeaderBar.</li>
|
||
<li>8: If the property “show-title-buttons” is TRUE, the title buttons
|
||
like close, minimize and maximize are shown. Otherwise it is not shown.
|
||
The TfeAlert object is not resizable. It is closed when either of the
|
||
two buttons, cancel or accept, is clicked. Therefore the title buttons
|
||
are not necessary and this property is set to FALSE.</li>
|
||
<li>9-14: The bar has a title, which is a GtkLabel widget. The default
|
||
title is “Are you sure?” but it can be replaced by an instance
|
||
method.</li>
|
||
<li>15-32: The bar has two buttons, cancel and accept. The cancel button
|
||
is on the left so the child tag has <code>type="start"</code> attribute.
|
||
The accept button is on the right so the child tag has
|
||
<code>type="end"</code> attribute. The dialog is shown when the user
|
||
clicked the close button or the quit menu without saving the data.
|
||
Therefore, it is safer for the user to click on the cancel button of the
|
||
alert dialog. So, the cancel button has a “suggested-action” CSS class.
|
||
Ubuntu colors the button green but the color can be blue or other
|
||
appropriate one defined by the system. In the same way the accept button
|
||
has a “destructive-action” CSS class and is colored red. Two buttons
|
||
have signals which are defined by the signal tags.</li>
|
||
<li>35-54: A horizontal box has an image icon and a label.</li>
|
||
<li>44-47: The GtkImage widget displays an image. The “icon-name”
|
||
property is an icon name in the icon theme. The theme depends on your
|
||
system. You can check it with an icon browser.</li>
|
||
</ul>
|
||
<pre><code>$ gtk4-icon-browser</code></pre>
|
||
<p>The “dialog-warning” icon is something like this.</p>
|
||
<figure>
|
||
<img src="image/dialog_warning.png"
|
||
alt="dialog-warning icon is like …" />
|
||
<figcaption aria-hidden="true">dialog-warning icon is like
|
||
…</figcaption>
|
||
</figure>
|
||
<p>These are made by my hand. The real image on the alert dialog is
|
||
nicer.</p>
|
||
<p>It is possible to define the alert widget as a child of GtkDialog.
|
||
But GtkDialog is deprecated since GTK version 4.10. And users should use
|
||
GtkWindow instead of GtkDialog.</p>
|
||
<h2 id="the-header-file">The header file</h2>
|
||
<p>The header file is similar to the one of TfeTextView.</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">#pragma once</span></span>
|
||
<span id="cb3-2"><a href="#cb3-2"></a></span>
|
||
<span id="cb3-3"><a href="#cb3-3"></a><span class="pp">#include </span><span class="im"><gtk/gtk.h></span></span>
|
||
<span id="cb3-4"><a href="#cb3-4"></a></span>
|
||
<span id="cb3-5"><a href="#cb3-5"></a><span class="pp">#define TFE_TYPE_ALERT tfe_alert_get_type ()</span></span>
|
||
<span id="cb3-6"><a href="#cb3-6"></a>G_DECLARE_FINAL_TYPE <span class="op">(</span>TfeAlert<span class="op">,</span> tfe_alert<span class="op">,</span> TFE<span class="op">,</span> ALERT<span class="op">,</span> GtkWindow<span class="op">)</span></span>
|
||
<span id="cb3-7"><a href="#cb3-7"></a></span>
|
||
<span id="cb3-8"><a href="#cb3-8"></a><span class="co">/* "response" signal id */</span></span>
|
||
<span id="cb3-9"><a href="#cb3-9"></a><span class="kw">enum</span> TfeAlertResponseType</span>
|
||
<span id="cb3-10"><a href="#cb3-10"></a><span class="op">{</span></span>
|
||
<span id="cb3-11"><a href="#cb3-11"></a> TFE_ALERT_RESPONSE_ACCEPT<span class="op">,</span></span>
|
||
<span id="cb3-12"><a href="#cb3-12"></a> TFE_ALERT_RESPONSE_CANCEL</span>
|
||
<span id="cb3-13"><a href="#cb3-13"></a><span class="op">};</span></span>
|
||
<span id="cb3-14"><a href="#cb3-14"></a></span>
|
||
<span id="cb3-15"><a href="#cb3-15"></a><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span></span>
|
||
<span id="cb3-16"><a href="#cb3-16"></a>tfe_alert_get_title <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">);</span></span>
|
||
<span id="cb3-17"><a href="#cb3-17"></a></span>
|
||
<span id="cb3-18"><a href="#cb3-18"></a><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span></span>
|
||
<span id="cb3-19"><a href="#cb3-19"></a>tfe_alert_get_message <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">);</span></span>
|
||
<span id="cb3-20"><a href="#cb3-20"></a></span>
|
||
<span id="cb3-21"><a href="#cb3-21"></a><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span></span>
|
||
<span id="cb3-22"><a href="#cb3-22"></a>tfe_alert_get_button_label <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">);</span></span>
|
||
<span id="cb3-23"><a href="#cb3-23"></a></span>
|
||
<span id="cb3-24"><a href="#cb3-24"></a><span class="dt">void</span></span>
|
||
<span id="cb3-25"><a href="#cb3-25"></a>tfe_alert_set_title <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>title<span class="op">);</span></span>
|
||
<span id="cb3-26"><a href="#cb3-26"></a></span>
|
||
<span id="cb3-27"><a href="#cb3-27"></a><span class="dt">void</span></span>
|
||
<span id="cb3-28"><a href="#cb3-28"></a>tfe_alert_set_message <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>message<span class="op">);</span></span>
|
||
<span id="cb3-29"><a href="#cb3-29"></a></span>
|
||
<span id="cb3-30"><a href="#cb3-30"></a><span class="dt">void</span></span>
|
||
<span id="cb3-31"><a href="#cb3-31"></a>tfe_alert_set_button_label <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>btn_label<span class="op">);</span></span>
|
||
<span id="cb3-32"><a href="#cb3-32"></a></span>
|
||
<span id="cb3-33"><a href="#cb3-33"></a>GtkWidget <span class="op">*</span></span>
|
||
<span id="cb3-34"><a href="#cb3-34"></a>tfe_alert_new <span class="op">(</span><span class="dt">void</span><span class="op">);</span></span>
|
||
<span id="cb3-35"><a href="#cb3-35"></a></span>
|
||
<span id="cb3-36"><a href="#cb3-36"></a>GtkWidget <span class="op">*</span></span>
|
||
<span id="cb3-37"><a href="#cb3-37"></a>tfe_alert_new_with_data <span class="op">(</span><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>title<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>message<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span><span class="op">*</span> btn_label<span class="op">);</span></span></code></pre></div>
|
||
<ul>
|
||
<li>5-6: These two lines are always needed to define a new object.
|
||
<code>TFE_TYPE_ALERT</code> is the type of TfeAlert object and it is a
|
||
macro expanded into <code>tfe_alert_get_type ()</code>.
|
||
G_DECLARE_FINAL_TYPE macro is expanded into:
|
||
<ul>
|
||
<li>The declaration of the function <code>tfe_alert_get_type</code></li>
|
||
<li><code>TfeAlert</code> is defined as a typedef of
|
||
<code>struct _TfeAlert</code>, which is defined in the C file.</li>
|
||
<li><code>TFE_ALERT</code> and <code>TFE_IS_ALERT</code> macro is
|
||
defined as a cast and type check function.</li>
|
||
<li><code>TfeAlertClass</code> structure is defined as a final
|
||
class.</li>
|
||
</ul></li>
|
||
<li>8-13: The TfeAlert class has a “response” signal. It has a parameter
|
||
and the parameter type is defined as a <code>TfeAlertResponseType</code>
|
||
enumerative constant.</li>
|
||
<li>15-31: Getter and setter methods.</li>
|
||
<li>33-37: Functions to create a instance. The function
|
||
<code>tfe_alert_new_with_data</code> is a convenience function, which
|
||
creates an instance and sets data at once.</li>
|
||
</ul>
|
||
<h2 id="the-c-file">The C file</h2>
|
||
<h3 id="functions-for-composite-widgets">Functions for composite
|
||
widgets</h3>
|
||
<p>The following codes are extracted from <code>tfealert.c</code>.</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="pp">#include </span><span class="im"><gtk/gtk.h></span></span>
|
||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">"tfealert.h"</span></span>
|
||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> _TfeAlert <span class="op">{</span></span>
|
||
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a> GtkWindow parent<span class="op">;</span></span>
|
||
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a> GtkLabel <span class="op">*</span>lb_title<span class="op">;</span></span>
|
||
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a> GtkLabel <span class="op">*</span>lb_message<span class="op">;</span></span>
|
||
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a> GtkButton <span class="op">*</span>btn_accept<span class="op">;</span></span>
|
||
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a> GtkButton <span class="op">*</span>btn_cancel<span class="op">;</span></span>
|
||
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
|
||
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>G_DEFINE_FINAL_TYPE <span class="op">(</span>TfeAlert<span class="op">,</span> tfe_alert<span class="op">,</span> GTK_TYPE_WINDOW<span class="op">);</span></span>
|
||
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>cancel_cb <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a> <span class="op">...</span> <span class="op">...</span> <span class="op">...</span></span>
|
||
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
|
||
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>accept_cb <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a> <span class="op">...</span> <span class="op">...</span> <span class="op">...</span></span>
|
||
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
|
||
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a>tfe_alert_dispose <span class="op">(</span>GObject <span class="op">*</span>gobject<span class="op">)</span> <span class="op">{</span> <span class="co">// gobject is actually a TfeAlert instance.</span></span>
|
||
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a> gtk_widget_dispose_template <span class="op">(</span>GTK_WIDGET <span class="op">(</span>gobject<span class="op">),</span> TFE_TYPE_ALERT<span class="op">);</span></span>
|
||
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a> G_OBJECT_CLASS <span class="op">(</span>tfe_alert_parent_class<span class="op">)-></span>dispose <span class="op">(</span>gobject<span class="op">);</span></span>
|
||
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
|
||
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true" tabindex="-1"></a>tfe_alert_init <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true" tabindex="-1"></a> gtk_widget_init_template <span class="op">(</span>GTK_WIDGET <span class="op">(</span>alert<span class="op">));</span></span>
|
||
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
|
||
<span id="cb4-34"><a href="#cb4-34" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-35"><a href="#cb4-35" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb4-36"><a href="#cb4-36" aria-hidden="true" tabindex="-1"></a>tfe_alert_class_init <span class="op">(</span>TfeAlertClass <span class="op">*</span>class<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb4-37"><a href="#cb4-37" aria-hidden="true" tabindex="-1"></a> G_OBJECT_CLASS <span class="op">(</span>class<span class="op">)-></span>dispose <span class="op">=</span> tfe_alert_dispose<span class="op">;</span></span>
|
||
<span id="cb4-38"><a href="#cb4-38" aria-hidden="true" tabindex="-1"></a> gtk_widget_class_set_template_from_resource <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> <span class="st">"/com/github/ToshioCP/tfe/tfealert.ui"</span><span class="op">);</span></span>
|
||
<span id="cb4-39"><a href="#cb4-39" aria-hidden="true" tabindex="-1"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> lb_title<span class="op">);</span></span>
|
||
<span id="cb4-40"><a href="#cb4-40" aria-hidden="true" tabindex="-1"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> lb_message<span class="op">);</span></span>
|
||
<span id="cb4-41"><a href="#cb4-41" aria-hidden="true" tabindex="-1"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> btn_accept<span class="op">);</span></span>
|
||
<span id="cb4-42"><a href="#cb4-42" aria-hidden="true" tabindex="-1"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> btn_cancel<span class="op">);</span></span>
|
||
<span id="cb4-43"><a href="#cb4-43" aria-hidden="true" tabindex="-1"></a> gtk_widget_class_bind_template_callback <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> cancel_cb<span class="op">);</span></span>
|
||
<span id="cb4-44"><a href="#cb4-44" aria-hidden="true" tabindex="-1"></a> gtk_widget_class_bind_template_callback <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> accept_cb<span class="op">);</span></span>
|
||
<span id="cb4-45"><a href="#cb4-45" aria-hidden="true" tabindex="-1"></a> <span class="op">...</span> <span class="op">...</span> <span class="op">...</span></span>
|
||
<span id="cb4-46"><a href="#cb4-46" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
|
||
<span id="cb4-47"><a href="#cb4-47" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb4-48"><a href="#cb4-48" aria-hidden="true" tabindex="-1"></a>GtkWidget <span class="op">*</span></span>
|
||
<span id="cb4-49"><a href="#cb4-49" aria-hidden="true" tabindex="-1"></a>tfe_alert_new <span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb4-50"><a href="#cb4-50" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> GTK_WIDGET <span class="op">(</span>g_object_new <span class="op">(</span>TFE_TYPE_ALERT<span class="op">,</span> NULL<span class="op">));</span></span>
|
||
<span id="cb4-51"><a href="#cb4-51" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<ul>
|
||
<li>The macro <code>G_DEFINE_FINAL_TYPE</code> is available since GLib
|
||
version 2.70. It is used only for a final type class. You can use
|
||
<code>G_DEFINE_TYPE</code> macro instead. They are expanded into:
|
||
<ul>
|
||
<li>The declaration of the functions <code>tfe_alert_init</code> and
|
||
<code>tfe_alert_class_init</code>. They are defined in the following
|
||
part of the C program.</li>
|
||
<li>The definition of the variable
|
||
<code>tfe_alert_parent_class</code>.</li>
|
||
<li>The definition of the function <code>tfe_alert_get_type</code>.</li>
|
||
</ul></li>
|
||
<li>The names of the members of <code>_TfeAlert</code>, which are
|
||
<code>lb_title</code>, <code>lb_message</code>, <code>btn_accept</code>
|
||
and <code>btn_cancel</code>, must be the same as the id attribute in the
|
||
XML file <code>tfealert.ui</code>.</li>
|
||
<li>The function <code>tfe_alert_class_init</code> initializes the
|
||
composite widget class.
|
||
<ul>
|
||
<li>The function
|
||
<code>gtk_widget_class_set_template_from_resource</code> sets the
|
||
template of the class. The template is built from the XML resource
|
||
“tfealert.ui”. At this moment no instance is created. It just makes the
|
||
class recognize the structure of the object. That’s why the top level
|
||
tag is not object but template in the XML file.</li>
|
||
<li>The function macro <code>gtk_widget_class_bind_template_child</code>
|
||
connects the member of TfeAlert and the object class in the template.
|
||
So, for example, you can access to <code>lb_title</code> GtkLabel
|
||
instance via <code>alert->lb_title</code> where <code>alert</code> is
|
||
an instance of TfeAlert class.</li>
|
||
<li>The function <code>gtk_widget_class_bind_template_callback</code>
|
||
connects the callback function and the <code>handler</code> attribute of
|
||
the signal tag in the XML. For example, the “clicked” signal on the
|
||
cancel button has a handler named “cancel_cb” in the signal tag. And the
|
||
function <code>cancel_cb</code> exists in the C file above. These two
|
||
are connected so when the signal is emitted the function
|
||
<code>cancel_cb</code> is called. You can add <code>static</code>
|
||
storage class to the callback function thanks to this connection.</li>
|
||
</ul></li>
|
||
<li>The function <code>tfe_alert_init</code> initializes the newly
|
||
created instance. You need to call <code>gtk_widget_init_template</code>
|
||
to create and initialize the child widgets in the template.</li>
|
||
<li>The function <code>tfe_alert_despose</code> releases objects. The
|
||
function <code>gtk_widget_despose_template</code> clears the template
|
||
children.</li>
|
||
<li>The function <code>tfe_alert_new</code> creates the composite widget
|
||
TfeAlert instance. It creates not only TfeAlert itself but also all the
|
||
child widgets that the composite widget has.</li>
|
||
</ul>
|
||
<h3 id="other-functions">Other functions</h3>
|
||
<p>The following is the full codes of <code>tfealert.c</code>.</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="pp">#include </span><span class="im"><gtk/gtk.h></span></span>
|
||
<span id="cb5-2"><a href="#cb5-2"></a><span class="pp">#include </span><span class="im">"tfealert.h"</span></span>
|
||
<span id="cb5-3"><a href="#cb5-3"></a></span>
|
||
<span id="cb5-4"><a href="#cb5-4"></a><span class="kw">struct</span> _TfeAlert <span class="op">{</span></span>
|
||
<span id="cb5-5"><a href="#cb5-5"></a> GtkWindow parent<span class="op">;</span></span>
|
||
<span id="cb5-6"><a href="#cb5-6"></a> GtkLabel <span class="op">*</span>lb_title<span class="op">;</span></span>
|
||
<span id="cb5-7"><a href="#cb5-7"></a> GtkLabel <span class="op">*</span>lb_message<span class="op">;</span></span>
|
||
<span id="cb5-8"><a href="#cb5-8"></a> GtkButton <span class="op">*</span>btn_accept<span class="op">;</span></span>
|
||
<span id="cb5-9"><a href="#cb5-9"></a> GtkButton <span class="op">*</span>btn_cancel<span class="op">;</span></span>
|
||
<span id="cb5-10"><a href="#cb5-10"></a><span class="op">};</span></span>
|
||
<span id="cb5-11"><a href="#cb5-11"></a></span>
|
||
<span id="cb5-12"><a href="#cb5-12"></a>G_DEFINE_FINAL_TYPE <span class="op">(</span>TfeAlert<span class="op">,</span> tfe_alert<span class="op">,</span> GTK_TYPE_WINDOW<span class="op">);</span></span>
|
||
<span id="cb5-13"><a href="#cb5-13"></a></span>
|
||
<span id="cb5-14"><a href="#cb5-14"></a><span class="kw">enum</span> <span class="op">{</span></span>
|
||
<span id="cb5-15"><a href="#cb5-15"></a> RESPONSE<span class="op">,</span></span>
|
||
<span id="cb5-16"><a href="#cb5-16"></a> NUMBER_OF_SIGNALS</span>
|
||
<span id="cb5-17"><a href="#cb5-17"></a><span class="op">};</span></span>
|
||
<span id="cb5-18"><a href="#cb5-18"></a></span>
|
||
<span id="cb5-19"><a href="#cb5-19"></a><span class="dt">static</span> guint tfe_alert_signals<span class="op">[</span>NUMBER_OF_SIGNALS<span class="op">];</span></span>
|
||
<span id="cb5-20"><a href="#cb5-20"></a></span>
|
||
<span id="cb5-21"><a href="#cb5-21"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb5-22"><a href="#cb5-22"></a>cancel_cb <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-23"><a href="#cb5-23"></a> g_signal_emit <span class="op">(</span>alert<span class="op">,</span> tfe_alert_signals<span class="op">[</span>RESPONSE<span class="op">],</span> <span class="dv">0</span><span class="op">,</span> TFE_ALERT_RESPONSE_CANCEL<span class="op">);</span></span>
|
||
<span id="cb5-24"><a href="#cb5-24"></a> gtk_window_destroy <span class="op">(</span>GTK_WINDOW <span class="op">(</span>alert<span class="op">));</span></span>
|
||
<span id="cb5-25"><a href="#cb5-25"></a><span class="op">}</span></span>
|
||
<span id="cb5-26"><a href="#cb5-26"></a></span>
|
||
<span id="cb5-27"><a href="#cb5-27"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb5-28"><a href="#cb5-28"></a>accept_cb <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-29"><a href="#cb5-29"></a> g_signal_emit <span class="op">(</span>alert<span class="op">,</span> tfe_alert_signals<span class="op">[</span>RESPONSE<span class="op">],</span> <span class="dv">0</span><span class="op">,</span> TFE_ALERT_RESPONSE_ACCEPT<span class="op">);</span></span>
|
||
<span id="cb5-30"><a href="#cb5-30"></a> gtk_window_destroy <span class="op">(</span>GTK_WINDOW <span class="op">(</span>alert<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></span>
|
||
<span id="cb5-33"><a href="#cb5-33"></a><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span></span>
|
||
<span id="cb5-34"><a href="#cb5-34"></a>tfe_alert_get_title <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-35"><a href="#cb5-35"></a> <span class="cf">return</span> gtk_label_get_text <span class="op">(</span>alert<span class="op">-></span>lb_title<span class="op">);</span></span>
|
||
<span id="cb5-36"><a href="#cb5-36"></a><span class="op">}</span></span>
|
||
<span id="cb5-37"><a href="#cb5-37"></a></span>
|
||
<span id="cb5-38"><a href="#cb5-38"></a><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span></span>
|
||
<span id="cb5-39"><a href="#cb5-39"></a>tfe_alert_get_message <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-40"><a href="#cb5-40"></a> <span class="cf">return</span> gtk_label_get_text <span class="op">(</span>alert<span class="op">-></span>lb_message<span class="op">);</span></span>
|
||
<span id="cb5-41"><a href="#cb5-41"></a><span class="op">}</span></span>
|
||
<span id="cb5-42"><a href="#cb5-42"></a></span>
|
||
<span id="cb5-43"><a href="#cb5-43"></a><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span></span>
|
||
<span id="cb5-44"><a href="#cb5-44"></a>tfe_alert_get_button_label <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-45"><a href="#cb5-45"></a> <span class="cf">return</span> gtk_button_get_label <span class="op">(</span>alert<span class="op">-></span>btn_accept<span class="op">);</span></span>
|
||
<span id="cb5-46"><a href="#cb5-46"></a><span class="op">}</span></span>
|
||
<span id="cb5-47"><a href="#cb5-47"></a></span>
|
||
<span id="cb5-48"><a href="#cb5-48"></a><span class="dt">void</span></span>
|
||
<span id="cb5-49"><a href="#cb5-49"></a>tfe_alert_set_title <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>title<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-50"><a href="#cb5-50"></a> gtk_label_set_text <span class="op">(</span>alert<span class="op">-></span>lb_title<span class="op">,</span> title<span class="op">);</span></span>
|
||
<span id="cb5-51"><a href="#cb5-51"></a><span class="op">}</span></span>
|
||
<span id="cb5-52"><a href="#cb5-52"></a></span>
|
||
<span id="cb5-53"><a href="#cb5-53"></a><span class="dt">void</span></span>
|
||
<span id="cb5-54"><a href="#cb5-54"></a>tfe_alert_set_message <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>message<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-55"><a href="#cb5-55"></a> gtk_label_set_text <span class="op">(</span>alert<span class="op">-></span>lb_message<span class="op">,</span> message<span class="op">);</span></span>
|
||
<span id="cb5-56"><a href="#cb5-56"></a><span class="op">}</span></span>
|
||
<span id="cb5-57"><a href="#cb5-57"></a></span>
|
||
<span id="cb5-58"><a href="#cb5-58"></a><span class="dt">void</span></span>
|
||
<span id="cb5-59"><a href="#cb5-59"></a>tfe_alert_set_button_label <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>btn_label<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-60"><a href="#cb5-60"></a> gtk_button_set_label <span class="op">(</span>alert<span class="op">-></span>btn_accept<span class="op">,</span> btn_label<span class="op">);</span></span>
|
||
<span id="cb5-61"><a href="#cb5-61"></a><span class="op">}</span></span>
|
||
<span id="cb5-62"><a href="#cb5-62"></a></span>
|
||
<span id="cb5-63"><a href="#cb5-63"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb5-64"><a href="#cb5-64"></a>tfe_alert_dispose <span class="op">(</span>GObject <span class="op">*</span>gobject<span class="op">)</span> <span class="op">{</span> <span class="co">// gobject is actually a TfeAlert instance.</span></span>
|
||
<span id="cb5-65"><a href="#cb5-65"></a> gtk_widget_dispose_template <span class="op">(</span>GTK_WIDGET <span class="op">(</span>gobject<span class="op">),</span> TFE_TYPE_ALERT<span class="op">);</span></span>
|
||
<span id="cb5-66"><a href="#cb5-66"></a> G_OBJECT_CLASS <span class="op">(</span>tfe_alert_parent_class<span class="op">)-></span>dispose <span class="op">(</span>gobject<span class="op">);</span></span>
|
||
<span id="cb5-67"><a href="#cb5-67"></a><span class="op">}</span></span>
|
||
<span id="cb5-68"><a href="#cb5-68"></a></span>
|
||
<span id="cb5-69"><a href="#cb5-69"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb5-70"><a href="#cb5-70"></a>tfe_alert_init <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-71"><a href="#cb5-71"></a> gtk_widget_init_template <span class="op">(</span>GTK_WIDGET <span class="op">(</span>alert<span class="op">));</span></span>
|
||
<span id="cb5-72"><a href="#cb5-72"></a><span class="op">}</span></span>
|
||
<span id="cb5-73"><a href="#cb5-73"></a></span>
|
||
<span id="cb5-74"><a href="#cb5-74"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb5-75"><a href="#cb5-75"></a>tfe_alert_class_init <span class="op">(</span>TfeAlertClass <span class="op">*</span>class<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-76"><a href="#cb5-76"></a> G_OBJECT_CLASS <span class="op">(</span>class<span class="op">)-></span>dispose <span class="op">=</span> tfe_alert_dispose<span class="op">;</span></span>
|
||
<span id="cb5-77"><a href="#cb5-77"></a> gtk_widget_class_set_template_from_resource <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> <span class="st">"/com/github/ToshioCP/tfe/tfealert.ui"</span><span class="op">);</span></span>
|
||
<span id="cb5-78"><a href="#cb5-78"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> lb_title<span class="op">);</span></span>
|
||
<span id="cb5-79"><a href="#cb5-79"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> lb_message<span class="op">);</span></span>
|
||
<span id="cb5-80"><a href="#cb5-80"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> btn_accept<span class="op">);</span></span>
|
||
<span id="cb5-81"><a href="#cb5-81"></a> gtk_widget_class_bind_template_child <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> TfeAlert<span class="op">,</span> btn_cancel<span class="op">);</span></span>
|
||
<span id="cb5-82"><a href="#cb5-82"></a> gtk_widget_class_bind_template_callback <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> cancel_cb<span class="op">);</span></span>
|
||
<span id="cb5-83"><a href="#cb5-83"></a> gtk_widget_class_bind_template_callback <span class="op">(</span>GTK_WIDGET_CLASS <span class="op">(</span>class<span class="op">),</span> accept_cb<span class="op">);</span></span>
|
||
<span id="cb5-84"><a href="#cb5-84"></a></span>
|
||
<span id="cb5-85"><a href="#cb5-85"></a> tfe_alert_signals<span class="op">[</span>RESPONSE<span class="op">]</span> <span class="op">=</span> g_signal_new <span class="op">(</span><span class="st">"response"</span><span class="op">,</span></span>
|
||
<span id="cb5-86"><a href="#cb5-86"></a> G_TYPE_FROM_CLASS <span class="op">(</span>class<span class="op">),</span></span>
|
||
<span id="cb5-87"><a href="#cb5-87"></a> G_SIGNAL_RUN_LAST <span class="op">|</span> G_SIGNAL_NO_RECURSE <span class="op">|</span> G_SIGNAL_NO_HOOKS<span class="op">,</span></span>
|
||
<span id="cb5-88"><a href="#cb5-88"></a> <span class="dv">0</span> <span class="co">/* class offset */</span><span class="op">,</span></span>
|
||
<span id="cb5-89"><a href="#cb5-89"></a> NULL <span class="co">/* accumulator */</span><span class="op">,</span></span>
|
||
<span id="cb5-90"><a href="#cb5-90"></a> NULL <span class="co">/* accumulator data */</span><span class="op">,</span></span>
|
||
<span id="cb5-91"><a href="#cb5-91"></a> NULL <span class="co">/* C marshaller */</span><span class="op">,</span></span>
|
||
<span id="cb5-92"><a href="#cb5-92"></a> G_TYPE_NONE <span class="co">/* return_type */</span><span class="op">,</span></span>
|
||
<span id="cb5-93"><a href="#cb5-93"></a> <span class="dv">1</span> <span class="co">/* n_params */</span><span class="op">,</span></span>
|
||
<span id="cb5-94"><a href="#cb5-94"></a> G_TYPE_INT</span>
|
||
<span id="cb5-95"><a href="#cb5-95"></a> <span class="op">);</span></span>
|
||
<span id="cb5-96"><a href="#cb5-96"></a><span class="op">}</span></span>
|
||
<span id="cb5-97"><a href="#cb5-97"></a></span>
|
||
<span id="cb5-98"><a href="#cb5-98"></a>GtkWidget <span class="op">*</span></span>
|
||
<span id="cb5-99"><a href="#cb5-99"></a>tfe_alert_new <span class="op">(</span><span class="dt">void</span><span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-100"><a href="#cb5-100"></a> <span class="cf">return</span> GTK_WIDGET <span class="op">(</span>g_object_new <span class="op">(</span>TFE_TYPE_ALERT<span class="op">,</span> NULL<span class="op">));</span></span>
|
||
<span id="cb5-101"><a href="#cb5-101"></a><span class="op">}</span></span>
|
||
<span id="cb5-102"><a href="#cb5-102"></a></span>
|
||
<span id="cb5-103"><a href="#cb5-103"></a>GtkWidget <span class="op">*</span></span>
|
||
<span id="cb5-104"><a href="#cb5-104"></a>tfe_alert_new_with_data <span class="op">(</span><span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>title<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>message<span class="op">,</span> <span class="dt">const</span> <span class="dt">char</span><span class="op">*</span> btn_label<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb5-105"><a href="#cb5-105"></a> GtkWidget <span class="op">*</span>alert <span class="op">=</span> tfe_alert_new <span class="op">();</span></span>
|
||
<span id="cb5-106"><a href="#cb5-106"></a> tfe_alert_set_title <span class="op">(</span>TFE_ALERT <span class="op">(</span>alert<span class="op">),</span> title<span class="op">);</span></span>
|
||
<span id="cb5-107"><a href="#cb5-107"></a> tfe_alert_set_message <span class="op">(</span>TFE_ALERT <span class="op">(</span>alert<span class="op">),</span> message<span class="op">);</span></span>
|
||
<span id="cb5-108"><a href="#cb5-108"></a> tfe_alert_set_button_label <span class="op">(</span>TFE_ALERT <span class="op">(</span>alert<span class="op">),</span> btn_label<span class="op">);</span></span>
|
||
<span id="cb5-109"><a href="#cb5-109"></a> <span class="cf">return</span> alert<span class="op">;</span></span>
|
||
<span id="cb5-110"><a href="#cb5-110"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>The function <code>tfe_alert_new_with_data</code> is used more often
|
||
than <code>tfe_alert_new</code> to create a new instance. It creates the
|
||
instance and sets three data at the same time. The following is the
|
||
common process when you use the TfeAlert class.</p>
|
||
<ul>
|
||
<li>Call <code>tfe_alert_new_with_data</code> and create an
|
||
instance.</li>
|
||
<li>Call <code>gtk_window_set_transient_for</code> to set the transient
|
||
parent window.</li>
|
||
<li>Call <code>gtk_window_present</code> to show the TfeAlert
|
||
dialog.</li>
|
||
<li>Connect “response” signal and a handler.</li>
|
||
<li>The user clicks on the cancel or accept button. Then the dialog
|
||
emits the “response” signal and destroy itself.</li>
|
||
<li>The user catches the signal and do something.</li>
|
||
</ul>
|
||
<p>The rest of the program is:</p>
|
||
<ul>
|
||
<li>14-19: An array for a signal id. You can use a variable instead of
|
||
an array because the class has only one signal. But using an array is a
|
||
common way.</li>
|
||
<li>21-31: Signal handlers. They emits the “response” signal and destroy
|
||
the instance itself.</li>
|
||
<li>33-61: Getters and setters.</li>
|
||
<li>85-95: Creates the “response” signal.</li>
|
||
<li>103-110: A convenience function <code>tfe_alert_new_with_data</code>
|
||
creates an instance and sets labels.</li>
|
||
</ul>
|
||
<h2 id="an-example">An example</h2>
|
||
<p>There’s an example in the <code>src/tfe6/example</code> directory. It
|
||
shows how to use TfeAlert. The program is
|
||
<code>src/example/ex_alert.c</code>.</p>
|
||
<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="pp">#include </span><span class="im"><gtk/gtk.h></span></span>
|
||
<span id="cb6-2"><a href="#cb6-2"></a><span class="pp">#include </span><span class="im">"../tfealert.h"</span></span>
|
||
<span id="cb6-3"><a href="#cb6-3"></a></span>
|
||
<span id="cb6-4"><a href="#cb6-4"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb6-5"><a href="#cb6-5"></a>alert_response_cb <span class="op">(</span>TfeAlert <span class="op">*</span>alert<span class="op">,</span> <span class="dt">int</span> response<span class="op">,</span> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb6-6"><a href="#cb6-6"></a> <span class="cf">if</span> <span class="op">(</span>response <span class="op">==</span> TFE_ALERT_RESPONSE_ACCEPT<span class="op">)</span></span>
|
||
<span id="cb6-7"><a href="#cb6-7"></a> g_print <span class="op">(</span><span class="st">"%s</span><span class="sc">\n</span><span class="st">"</span><span class="op">,</span> tfe_alert_get_button_label <span class="op">(</span>alert<span class="op">));</span></span>
|
||
<span id="cb6-8"><a href="#cb6-8"></a> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>response <span class="op">==</span> TFE_ALERT_RESPONSE_CANCEL<span class="op">)</span></span>
|
||
<span id="cb6-9"><a href="#cb6-9"></a> g_print <span class="op">(</span><span class="st">"Cancel</span><span class="sc">\n</span><span class="st">"</span><span class="op">);</span></span>
|
||
<span id="cb6-10"><a href="#cb6-10"></a> <span class="cf">else</span></span>
|
||
<span id="cb6-11"><a href="#cb6-11"></a> g_print <span class="op">(</span><span class="st">"Unexpected error</span><span class="sc">\n</span><span class="st">"</span><span class="op">);</span></span>
|
||
<span id="cb6-12"><a href="#cb6-12"></a><span class="op">}</span></span>
|
||
<span id="cb6-13"><a href="#cb6-13"></a></span>
|
||
<span id="cb6-14"><a href="#cb6-14"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb6-15"><a href="#cb6-15"></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-16"><a href="#cb6-16"></a> GtkWidget <span class="op">*</span>alert<span class="op">;</span></span>
|
||
<span id="cb6-17"><a href="#cb6-17"></a> <span class="dt">char</span> <span class="op">*</span>title<span class="op">,</span> <span class="op">*</span>message<span class="op">,</span> <span class="op">*</span>btn_label<span class="op">;</span></span>
|
||
<span id="cb6-18"><a href="#cb6-18"></a></span>
|
||
<span id="cb6-19"><a href="#cb6-19"></a> title <span class="op">=</span> <span class="st">"Example for TfeAlert"</span><span class="op">;</span> message <span class="op">=</span> <span class="st">"Click on Cancel or Accept button"</span><span class="op">;</span> btn_label <span class="op">=</span> <span class="st">"Accept"</span><span class="op">;</span></span>
|
||
<span id="cb6-20"><a href="#cb6-20"></a> alert <span class="op">=</span> tfe_alert_new_with_data <span class="op">(</span>title<span class="op">,</span> message<span class="op">,</span> btn_label<span class="op">);</span></span>
|
||
<span id="cb6-21"><a href="#cb6-21"></a> g_signal_connect <span class="op">(</span>TFE_ALERT <span class="op">(</span>alert<span class="op">),</span> <span class="st">"response"</span><span class="op">,</span> G_CALLBACK <span class="op">(</span>alert_response_cb<span class="op">),</span> NULL<span class="op">);</span></span>
|
||
<span id="cb6-22"><a href="#cb6-22"></a> gtk_window_set_application <span class="op">(</span>GTK_WINDOW <span class="op">(</span>alert<span class="op">),</span> GTK_APPLICATION <span class="op">(</span>application<span class="op">));</span></span>
|
||
<span id="cb6-23"><a href="#cb6-23"></a> gtk_window_present <span class="op">(</span>GTK_WINDOW <span class="op">(</span>alert<span class="op">));</span></span>
|
||
<span id="cb6-24"><a href="#cb6-24"></a><span class="op">}</span></span>
|
||
<span id="cb6-25"><a href="#cb6-25"></a></span>
|
||
<span id="cb6-26"><a href="#cb6-26"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb6-27"><a href="#cb6-27"></a>app_startup <span class="op">(</span>GApplication <span class="op">*</span>application<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb6-28"><a href="#cb6-28"></a><span class="op">}</span></span>
|
||
<span id="cb6-29"><a href="#cb6-29"></a></span>
|
||
<span id="cb6-30"><a href="#cb6-30"></a><span class="pp">#define APPLICATION_ID "com.github.ToshioCP.example_tfe_alert"</span></span>
|
||
<span id="cb6-31"><a href="#cb6-31"></a></span>
|
||
<span id="cb6-32"><a href="#cb6-32"></a><span class="dt">int</span></span>
|
||
<span id="cb6-33"><a href="#cb6-33"></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="cb6-34"><a href="#cb6-34"></a> GtkApplication <span class="op">*</span>app<span class="op">;</span></span>
|
||
<span id="cb6-35"><a href="#cb6-35"></a> <span class="dt">int</span> stat<span class="op">;</span></span>
|
||
<span id="cb6-36"><a href="#cb6-36"></a></span>
|
||
<span id="cb6-37"><a href="#cb6-37"></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="cb6-38"><a href="#cb6-38"></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="cb6-39"><a href="#cb6-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="cb6-40"><a href="#cb6-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="cb6-41"><a href="#cb6-41"></a> g_object_unref <span class="op">(</span>app<span class="op">);</span></span>
|
||
<span id="cb6-42"><a href="#cb6-42"></a> <span class="cf">return</span> stat<span class="op">;</span></span>
|
||
<span id="cb6-43"><a href="#cb6-43"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>The “activate” signal handler <code>app_activate</code> initializes
|
||
the alert dialog.</p>
|
||
<ul>
|
||
<li>A TfeAlert instance is created.</li>
|
||
<li>Its “response” signal is connected to the handler
|
||
<code>alert_response_cb</code>.</li>
|
||
<li>TfeAlert class is a sub class of GtkWindow so it can be a top level
|
||
window that is connected to an application instance. The function
|
||
<code>gtk_window_set_application</code> does that.</li>
|
||
<li>The dialog is shown.</li>
|
||
</ul>
|
||
<p>A user clicks on either the cancel button or the accept button. Then,
|
||
the “response” signal is emitted and the dialog is destroyed. The signal
|
||
handler <code>alert_response_cb</code> checks the response and prints
|
||
“Accept” or “Cancel”. If an error happens, it prints “Unexpected
|
||
error”.</p>
|
||
<p>You can compile it with meson and ninja.</p>
|
||
<pre><code>$ cd src/tfe6/example
|
||
$ meson setup _build
|
||
$ ninja -C _build
|
||
$ _build/ex_alert
|
||
Accept #<= if you clicked on the accept button</code></pre>
|
||
</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>
|