mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
653 lines
66 KiB
HTML
653 lines
66 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="sec26.html">Prev: section26</a>
|
||
</li>
|
||
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="sec28.html">Next: section28</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
<h1 id="gtkgridview-and-activate-signal">GtkGridView and activate
|
||
signal</h1>
|
||
<p>GtkGridView is similar to GtkListView. It displays a GListModel as a
|
||
grid, which is like a square tessellation.</p>
|
||
<figure>
|
||
<img src="image/list4.png" alt="Grid" />
|
||
<figcaption aria-hidden="true">Grid</figcaption>
|
||
</figure>
|
||
<p>This is often seen when you use a file browser like GNOME Files
|
||
(Nautilus).</p>
|
||
<p>In this section, let’s make a very simple file browser
|
||
<code>list4</code>. It just shows the files in the current directory.
|
||
And a user can choose list or grid by clicking on buttons in the tool
|
||
bar. Each item in the list or grid has an icon and a filename. In
|
||
addition, <code>list4</code> provides the way to open the
|
||
<code>tfe</code> text editor to show a text file. A user can do that by
|
||
double clicking on an item or pressing enter key when an item is
|
||
selected.</p>
|
||
<h2 id="gtkdirectorylist">GtkDirectoryList</h2>
|
||
<p>GtkDirectoryList implements GListModel and it contains information of
|
||
files in a certain directory. The items of the list are GFileInfo
|
||
objects.</p>
|
||
<p>In the <code>list4</code> source files, GtkDirectoryList is described
|
||
in a ui file and built by GtkBuilder. The GtkDirectoryList instance is
|
||
assigned to the “model” property of a GtkSingleSelection instance. And
|
||
the GtkSingleSelection instance is assigned to the “model” property of a
|
||
GListView or GGridView instance.</p>
|
||
<pre><code>GtkListView (model property) => GtkSingleSelection (model property) => GtkDirectoryList
|
||
GtkGridView (model property) => GtkSingleSelection (model property) => GtkDirectoryList</code></pre>
|
||
<figure>
|
||
<img src="image/directorylist.png" alt="DirectoryList" />
|
||
<figcaption aria-hidden="true">DirectoryList</figcaption>
|
||
</figure>
|
||
<p>The following is a part of the ui file <code>list4.ui</code>.</p>
|
||
<div class="sourceCode" id="cb2"><pre
|
||
class="sourceCode xml"><code class="sourceCode xml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkListView"</span><span class="ot"> id=</span><span class="st">"list"</span>></span>
|
||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>></span>
|
||
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkSingleSelection"</span><span class="ot"> id=</span><span class="st">"singleselection"</span>></span>
|
||
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>></span>
|
||
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkDirectoryList"</span><span class="ot"> id=</span><span class="st">"directorylist"</span>></span>
|
||
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"attributes"</span>>standard::name,standard::icon,standard::content-type</<span class="kw">property</span>></span>
|
||
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a></<span class="kw">object</span>></span>
|
||
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkGridView"</span><span class="ot"> id=</span><span class="st">"grid"</span>></span>
|
||
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>>singleselection</<span class="kw">property</span>></span>
|
||
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a></<span class="kw">object</span>></span></code></pre></div>
|
||
<p>GtkDirectoryList has an “attributes” property. It is attributes of
|
||
GFileInfo such as “standard::name”, “standard::icon” and
|
||
“standard::content-type”.</p>
|
||
<ul>
|
||
<li>standard::name is a filename.</li>
|
||
<li>standard::icon is an icon of the file. It is a GIcon object.</li>
|
||
<li>standard::content-type is a content-type. Content-type is the same
|
||
as mime type for the internet. For example, “text/plain” is a text file,
|
||
“text/x-csrc” is a C source code and so on. (“text/x-csrc”is not
|
||
registered to IANA media types. Such “x-” subtype is not a standard mime
|
||
type.) Content type is also used by desktop systems.</li>
|
||
</ul>
|
||
<p>GtkGridView uses the same GtkSingleSelection instance
|
||
(<code>singleselection</code>). So, its model property is set with
|
||
it.</p>
|
||
<h2 id="ui-file-of-the-window">Ui file of the window</h2>
|
||
<p>The window is built with the following ui file. (See the screenshot
|
||
at the beginning of this section).</p>
|
||
<div class="sourceCode" id="cb3"><pre
|
||
class="sourceCode numberSource xml numberLines"><code class="sourceCode xml"><span id="cb3-1"><a href="#cb3-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="cb3-2"><a href="#cb3-2"></a><<span class="kw">interface</span>></span>
|
||
<span id="cb3-3"><a href="#cb3-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="cb3-4"><a href="#cb3-4"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"title"</span>>file list</<span class="kw">property</span>></span>
|
||
<span id="cb3-5"><a href="#cb3-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="cb3-6"><a href="#cb3-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="cb3-7"><a href="#cb3-7"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-8"><a href="#cb3-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="cb3-9"><a href="#cb3-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="cb3-10"><a href="#cb3-10"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-11"><a href="#cb3-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">"boxh"</span>></span>
|
||
<span id="cb3-12"><a href="#cb3-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="cb3-13"><a href="#cb3-13"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-14"><a href="#cb3-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="cb3-15"><a href="#cb3-15"></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="cb3-16"><a href="#cb3-16"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-17"><a href="#cb3-17"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-18"><a href="#cb3-18"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-19"><a href="#cb3-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">"btnlist"</span>></span>
|
||
<span id="cb3-20"><a href="#cb3-20"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"name"</span>>btnlist</<span class="kw">property</span>></span>
|
||
<span id="cb3-21"><a href="#cb3-21"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"action-name"</span>>win.view</<span class="kw">property</span>></span>
|
||
<span id="cb3-22"><a href="#cb3-22"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"action-target"</span>><span class="dv">&apos;</span>list<span class="dv">&apos;</span></<span class="kw">property</span>></span>
|
||
<span id="cb3-23"><a href="#cb3-23"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-24"><a href="#cb3-24"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkImage"</span>></span>
|
||
<span id="cb3-25"><a href="#cb3-25"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"resource"</span>>/com/github/ToshioCP/list4/list.png</<span class="kw">property</span>></span>
|
||
<span id="cb3-26"><a href="#cb3-26"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-27"><a href="#cb3-27"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-28"><a href="#cb3-28"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-29"><a href="#cb3-29"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-30"><a href="#cb3-30"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-31"><a href="#cb3-31"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkButton"</span><span class="ot"> id=</span><span class="st">"btngrid"</span>></span>
|
||
<span id="cb3-32"><a href="#cb3-32"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"name"</span>>btngrid</<span class="kw">property</span>></span>
|
||
<span id="cb3-33"><a href="#cb3-33"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"action-name"</span>>win.view</<span class="kw">property</span>></span>
|
||
<span id="cb3-34"><a href="#cb3-34"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"action-target"</span>><span class="dv">&apos;</span>grid<span class="dv">&apos;</span></<span class="kw">property</span>></span>
|
||
<span id="cb3-35"><a href="#cb3-35"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-36"><a href="#cb3-36"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkImage"</span>></span>
|
||
<span id="cb3-37"><a href="#cb3-37"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"resource"</span>>/com/github/ToshioCP/list4/grid.png</<span class="kw">property</span>></span>
|
||
<span id="cb3-38"><a href="#cb3-38"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-39"><a href="#cb3-39"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-40"><a href="#cb3-40"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-41"><a href="#cb3-41"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-42"><a href="#cb3-42"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-43"><a href="#cb3-43"></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="cb3-44"><a href="#cb3-44"></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="cb3-45"><a href="#cb3-45"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-46"><a href="#cb3-46"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-47"><a href="#cb3-47"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-48"><a href="#cb3-48"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-49"><a href="#cb3-49"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb3-50"><a href="#cb3-50"></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="cb3-51"><a href="#cb3-51"></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="cb3-52"><a href="#cb3-52"></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="cb3-53"><a href="#cb3-53"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-54"><a href="#cb3-54"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-55"><a href="#cb3-55"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-56"><a href="#cb3-56"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb3-57"><a href="#cb3-57"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-58"><a href="#cb3-58"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkListView"</span><span class="ot"> id=</span><span class="st">"list"</span>></span>
|
||
<span id="cb3-59"><a href="#cb3-59"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>></span>
|
||
<span id="cb3-60"><a href="#cb3-60"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkSingleSelection"</span><span class="ot"> id=</span><span class="st">"singleselection"</span>></span>
|
||
<span id="cb3-61"><a href="#cb3-61"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>></span>
|
||
<span id="cb3-62"><a href="#cb3-62"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkDirectoryList"</span><span class="ot"> id=</span><span class="st">"directory_list"</span>></span>
|
||
<span id="cb3-63"><a href="#cb3-63"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"attributes"</span>>standard::name,standard::icon,standard::content-type</<span class="kw">property</span>></span>
|
||
<span id="cb3-64"><a href="#cb3-64"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-65"><a href="#cb3-65"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb3-66"><a href="#cb3-66"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-67"><a href="#cb3-67"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb3-68"><a href="#cb3-68"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-69"><a href="#cb3-69"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkGridView"</span><span class="ot"> id=</span><span class="st">"grid"</span>></span>
|
||
<span id="cb3-70"><a href="#cb3-70"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>>singleselection</<span class="kw">property</span>></span>
|
||
<span id="cb3-71"><a href="#cb3-71"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb3-72"><a href="#cb3-72"></a></<span class="kw">interface</span>></span></code></pre></div>
|
||
<p>The file consists of two parts. The first part begins at the line 3
|
||
and ends at line 57. This part is the widgets from the top level window
|
||
to the scrolled window. It also includes two buttons. The second part
|
||
begins at line 58 and ends at line 71. This is the part of GtkListView
|
||
and GtkGridView.</p>
|
||
<ul>
|
||
<li>13-17, 42-46: Two labels are dummy labels. They just work as a space
|
||
to put the two buttons at the appropriate position.</li>
|
||
<li>18-41: GtkButton <code>btnlist</code> and <code>btngrid</code>.
|
||
These two buttons work as selection buttons to switch from list to grid
|
||
and vice versa. These two buttons are connected to a stateful action
|
||
<code>win.view</code>. This action has a parameter. Such action consists
|
||
of prefix, action name and parameter. The prefix of the action is
|
||
<code>win</code>, which means the action belongs to the top level
|
||
window. The prefix gives the scope of the action. The action name is
|
||
<code>view</code>. The parameters are <code>list</code> or
|
||
<code>grid</code>, which show the state of the action. A parameter is
|
||
also called a target, because it is a target to which the action changes
|
||
its state. We often write the detailed action like “win.view::list” or
|
||
“win.view::grid”.</li>
|
||
<li>21-22: The properties “action-name” and “action-target” belong to
|
||
GtkActionable interface. GtkButton implements GtkActionable. The action
|
||
name is “win.view” and the target is “list”. Generally, a target is
|
||
GVariant, which can be string, integer, float and so on. You need to use
|
||
GVariant text format to write GVariant value in ui files. If the type of
|
||
the GVariant value is string, then the value with GVariant text format
|
||
is bounded by single quotes or double quotes. Because ui file is xml
|
||
format text, single quote cannot be written without escape. Its escape
|
||
sequence is &apos;. Therefore, the target ‘list’ is written as
|
||
&apos;list&apos;. Because the button is connected to the action,
|
||
“clicked” signal handler isn’t needed.</li>
|
||
<li>23-27: The child widget of the button is GtkImage. GtkImage has a
|
||
“resource” property. It is a GResource and GtkImage reads an image data
|
||
from the resource and sets the image. This resource is built from
|
||
24x24-sized png image data, which is an original icon.</li>
|
||
<li>50-53: GtkScrolledWindow. Its child widget will be set with
|
||
GtkListView or GtkGridView.</li>
|
||
</ul>
|
||
<p>The action <code>view</code> is created, connected to the “activate”
|
||
signal handler and inserted to the window (action map) as follows.</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>act_view <span class="op">=</span> g_simple_action_new_stateful <span class="op">(</span><span class="st">"view"</span><span class="op">,</span> g_variant_type_new<span class="op">(</span><span class="st">"s"</span><span class="op">),</span> g_variant_new_string <span class="op">(</span><span class="st">"list"</span><span class="op">));</span></span>
|
||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>g_signal_connect <span class="op">(</span>act_view<span class="op">,</span> <span class="st">"activate"</span><span class="op">,</span> G_CALLBACK <span class="op">(</span>view_activated<span class="op">),</span> NULL<span class="op">);</span></span>
|
||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>g_action_map_add_action <span class="op">(</span>G_ACTION_MAP <span class="op">(</span>win<span class="op">),</span> G_ACTION <span class="op">(</span>act_view<span class="op">));</span></span></code></pre></div>
|
||
<p>The signal handler <code>view_activated</code> will be explained
|
||
later.</p>
|
||
<h2 id="factories">Factories</h2>
|
||
<p>Each view (GtkListView and GtkGridView) has its own factory because
|
||
its items have different structure of widgets. The factories are
|
||
GtkBuilderListItemFactory objects. Their ui files are as follows.</p>
|
||
<p>factory_list.ui</p>
|
||
<div class="sourceCode" id="cb5"><pre
|
||
class="sourceCode numberSource xml numberLines"><code class="sourceCode xml"><span id="cb5-1"><a href="#cb5-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="cb5-2"><a href="#cb5-2"></a><<span class="kw">interface</span>></span>
|
||
<span id="cb5-3"><a href="#cb5-3"></a> <<span class="kw">template</span><span class="ot"> class=</span><span class="st">"GtkListItem"</span>></span>
|
||
<span id="cb5-4"><a href="#cb5-4"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"child"</span>></span>
|
||
<span id="cb5-5"><a href="#cb5-5"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkBox"</span>></span>
|
||
<span id="cb5-6"><a href="#cb5-6"></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="cb5-7"><a href="#cb5-7"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"spacing"</span>>20</<span class="kw">property</span>></span>
|
||
<span id="cb5-8"><a href="#cb5-8"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb5-9"><a href="#cb5-9"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkImage"</span>></span>
|
||
<span id="cb5-10"><a href="#cb5-10"></a> <<span class="kw">binding</span><span class="ot"> name=</span><span class="st">"gicon"</span>></span>
|
||
<span id="cb5-11"><a href="#cb5-11"></a> <<span class="kw">closure</span><span class="ot"> type=</span><span class="st">"GIcon"</span><span class="ot"> function=</span><span class="st">"get_icon"</span>></span>
|
||
<span id="cb5-12"><a href="#cb5-12"></a> <<span class="kw">lookup</span><span class="ot"> name=</span><span class="st">"item"</span>>GtkListItem</<span class="kw">lookup</span>></span>
|
||
<span id="cb5-13"><a href="#cb5-13"></a> </<span class="kw">closure</span>></span>
|
||
<span id="cb5-14"><a href="#cb5-14"></a> </<span class="kw">binding</span>></span>
|
||
<span id="cb5-15"><a href="#cb5-15"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb5-16"><a href="#cb5-16"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb5-17"><a href="#cb5-17"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb5-18"><a href="#cb5-18"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkLabel"</span>></span>
|
||
<span id="cb5-19"><a href="#cb5-19"></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="cb5-20"><a href="#cb5-20"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"xalign"</span>>0</<span class="kw">property</span>></span>
|
||
<span id="cb5-21"><a href="#cb5-21"></a> <<span class="kw">binding</span><span class="ot"> name=</span><span class="st">"label"</span>></span>
|
||
<span id="cb5-22"><a href="#cb5-22"></a> <<span class="kw">closure</span><span class="ot"> type=</span><span class="st">"gchararray"</span><span class="ot"> function=</span><span class="st">"get_file_name"</span>></span>
|
||
<span id="cb5-23"><a href="#cb5-23"></a> <<span class="kw">lookup</span><span class="ot"> name=</span><span class="st">"item"</span>>GtkListItem</<span class="kw">lookup</span>></span>
|
||
<span id="cb5-24"><a href="#cb5-24"></a> </<span class="kw">closure</span>></span>
|
||
<span id="cb5-25"><a href="#cb5-25"></a> </<span class="kw">binding</span>></span>
|
||
<span id="cb5-26"><a href="#cb5-26"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb5-27"><a href="#cb5-27"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb5-28"><a href="#cb5-28"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb5-29"><a href="#cb5-29"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb5-30"><a href="#cb5-30"></a> </<span class="kw">template</span>></span>
|
||
<span id="cb5-31"><a href="#cb5-31"></a></<span class="kw">interface</span>></span></code></pre></div>
|
||
<p>factory_grid.ui</p>
|
||
<div class="sourceCode" id="cb6"><pre
|
||
class="sourceCode numberSource xml numberLines"><code class="sourceCode xml"><span id="cb6-1"><a href="#cb6-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="cb6-2"><a href="#cb6-2"></a><<span class="kw">interface</span>></span>
|
||
<span id="cb6-3"><a href="#cb6-3"></a> <<span class="kw">template</span><span class="ot"> class=</span><span class="st">"GtkListItem"</span>></span>
|
||
<span id="cb6-4"><a href="#cb6-4"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"child"</span>></span>
|
||
<span id="cb6-5"><a href="#cb6-5"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkBox"</span>></span>
|
||
<span id="cb6-6"><a href="#cb6-6"></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="cb6-7"><a href="#cb6-7"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"spacing"</span>>20</<span class="kw">property</span>></span>
|
||
<span id="cb6-8"><a href="#cb6-8"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb6-9"><a href="#cb6-9"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkImage"</span>></span>
|
||
<span id="cb6-10"><a href="#cb6-10"></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="cb6-11"><a href="#cb6-11"></a> <<span class="kw">binding</span><span class="ot"> name=</span><span class="st">"gicon"</span>></span>
|
||
<span id="cb6-12"><a href="#cb6-12"></a> <<span class="kw">closure</span><span class="ot"> type=</span><span class="st">"GIcon"</span><span class="ot"> function=</span><span class="st">"get_icon"</span>></span>
|
||
<span id="cb6-13"><a href="#cb6-13"></a> <<span class="kw">lookup</span><span class="ot"> name=</span><span class="st">"item"</span>>GtkListItem</<span class="kw">lookup</span>></span>
|
||
<span id="cb6-14"><a href="#cb6-14"></a> </<span class="kw">closure</span>></span>
|
||
<span id="cb6-15"><a href="#cb6-15"></a> </<span class="kw">binding</span>></span>
|
||
<span id="cb6-16"><a href="#cb6-16"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb6-17"><a href="#cb6-17"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb6-18"><a href="#cb6-18"></a> <<span class="kw">child</span>></span>
|
||
<span id="cb6-19"><a href="#cb6-19"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkLabel"</span>></span>
|
||
<span id="cb6-20"><a href="#cb6-20"></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="cb6-21"><a href="#cb6-21"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"xalign"</span>>0.5</<span class="kw">property</span>></span>
|
||
<span id="cb6-22"><a href="#cb6-22"></a> <<span class="kw">binding</span><span class="ot"> name=</span><span class="st">"label"</span>></span>
|
||
<span id="cb6-23"><a href="#cb6-23"></a> <<span class="kw">closure</span><span class="ot"> type=</span><span class="st">"gchararray"</span><span class="ot"> function=</span><span class="st">"get_file_name"</span>></span>
|
||
<span id="cb6-24"><a href="#cb6-24"></a> <<span class="kw">lookup</span><span class="ot"> name=</span><span class="st">"item"</span>>GtkListItem</<span class="kw">lookup</span>></span>
|
||
<span id="cb6-25"><a href="#cb6-25"></a> </<span class="kw">closure</span>></span>
|
||
<span id="cb6-26"><a href="#cb6-26"></a> </<span class="kw">binding</span>></span>
|
||
<span id="cb6-27"><a href="#cb6-27"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb6-28"><a href="#cb6-28"></a> </<span class="kw">child</span>></span>
|
||
<span id="cb6-29"><a href="#cb6-29"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb6-30"><a href="#cb6-30"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb6-31"><a href="#cb6-31"></a> </<span class="kw">template</span>></span>
|
||
<span id="cb6-32"><a href="#cb6-32"></a></<span class="kw">interface</span>></span></code></pre></div>
|
||
<p>The two files above are almost same. The difference is:</p>
|
||
<ul>
|
||
<li>The orientation of the box</li>
|
||
<li>The icon size</li>
|
||
<li>The position of the text of the label</li>
|
||
</ul>
|
||
<pre><code>$ cd list4; diff factory_list.ui factory_grid.ui
|
||
6c6
|
||
< <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
|
||
---
|
||
> <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
|
||
9a10
|
||
> <property name="icon-size">GTK_ICON_SIZE_LARGE</property>
|
||
20c21
|
||
< <property name="xalign">0</property>
|
||
---
|
||
> <property name="xalign">0.5</property></code></pre>
|
||
<p>Two properties “gicon” (property of GtkImage) and “label” (property
|
||
of GtkLabel) are in the ui files above. Because GFileInfo doesn’t have
|
||
properties correspond to icon or filename, the factory uses closure tag
|
||
to bind “gicon” and “label” properties to GFileInfo information. A
|
||
function <code>get_icon</code> gets GIcon from the GFileInfo object. And
|
||
a function <code>get_file_name</code> gets a filename from the GFileInfo
|
||
object.</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>GIcon <span class="op">*</span></span>
|
||
<span id="cb8-2"><a href="#cb8-2"></a>get_icon <span class="op">(</span>GtkListItem <span class="op">*</span>item<span class="op">,</span> GFileInfo <span class="op">*</span>info<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-3"><a href="#cb8-3"></a> GIcon <span class="op">*</span>icon<span class="op">;</span></span>
|
||
<span id="cb8-4"><a href="#cb8-4"></a></span>
|
||
<span id="cb8-5"><a href="#cb8-5"></a> <span class="cf">if</span> <span class="op">(!</span> G_IS_FILE_INFO <span class="op">(</span>info<span class="op">))</span></span>
|
||
<span id="cb8-6"><a href="#cb8-6"></a> <span class="cf">return</span> NULL<span class="op">;</span></span>
|
||
<span id="cb8-7"><a href="#cb8-7"></a> <span class="cf">else</span> <span class="op">{</span></span>
|
||
<span id="cb8-8"><a href="#cb8-8"></a> icon <span class="op">=</span> g_file_info_get_icon <span class="op">(</span>info<span class="op">);</span></span>
|
||
<span id="cb8-9"><a href="#cb8-9"></a> g_object_ref <span class="op">(</span>icon<span class="op">);</span></span>
|
||
<span id="cb8-10"><a href="#cb8-10"></a> <span class="cf">return</span> icon<span class="op">;</span></span>
|
||
<span id="cb8-11"><a href="#cb8-11"></a> <span class="op">}</span></span>
|
||
<span id="cb8-12"><a href="#cb8-12"></a><span class="op">}</span></span>
|
||
<span id="cb8-13"><a href="#cb8-13"></a></span>
|
||
<span id="cb8-14"><a href="#cb8-14"></a><span class="dt">char</span> <span class="op">*</span></span>
|
||
<span id="cb8-15"><a href="#cb8-15"></a>get_file_name <span class="op">(</span>GtkListItem <span class="op">*</span>item<span class="op">,</span> GFileInfo <span class="op">*</span>info<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb8-16"><a href="#cb8-16"></a> <span class="cf">if</span> <span class="op">(!</span> G_IS_FILE_INFO <span class="op">(</span>info<span class="op">))</span></span>
|
||
<span id="cb8-17"><a href="#cb8-17"></a> <span class="cf">return</span> NULL<span class="op">;</span></span>
|
||
<span id="cb8-18"><a href="#cb8-18"></a> <span class="cf">else</span></span>
|
||
<span id="cb8-19"><a href="#cb8-19"></a> <span class="cf">return</span> g_strdup <span class="op">(</span>g_file_info_get_name <span class="op">(</span>info<span class="op">));</span></span>
|
||
<span id="cb8-20"><a href="#cb8-20"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>One important thing is the ownership of the return values. When
|
||
GtkExpression (closure tag creates a GtkCClosureExpression – a child
|
||
class of GtkExpression) is evaluated, the value is owned by the caller.
|
||
So, <code>g_obect_ref</code> or <code>g_strdup</code> is necessary.</p>
|
||
<h2 id="an-activate-signal-handler-of-the-button-action">An activate
|
||
signal handler of the button action</h2>
|
||
<p>An activate signal handler <code>view_activate</code> switches the
|
||
view. It does two things.</p>
|
||
<ul>
|
||
<li>Changes the child widget of GtkScrolledWindow.</li>
|
||
<li>Changes the CSS of buttons to show the current state.</li>
|
||
</ul>
|
||
<div class="sourceCode" id="cb9"><pre
|
||
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb9-1"><a href="#cb9-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb9-2"><a href="#cb9-2"></a>view_activated<span class="op">(</span>GSimpleAction <span class="op">*</span>action<span class="op">,</span> GVariant <span class="op">*</span>parameter<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb9-3"><a href="#cb9-3"></a> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>view <span class="op">=</span> g_variant_get_string <span class="op">(</span>parameter<span class="op">,</span> NULL<span class="op">);</span></span>
|
||
<span id="cb9-4"><a href="#cb9-4"></a> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>other<span class="op">;</span></span>
|
||
<span id="cb9-5"><a href="#cb9-5"></a> <span class="dt">char</span> <span class="op">*</span>css<span class="op">;</span></span>
|
||
<span id="cb9-6"><a href="#cb9-6"></a></span>
|
||
<span id="cb9-7"><a href="#cb9-7"></a> <span class="cf">if</span> <span class="op">(</span>strcmp <span class="op">(</span>view<span class="op">,</span> <span class="st">"list"</span><span class="op">)</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb9-8"><a href="#cb9-8"></a> other <span class="op">=</span> <span class="st">"grid"</span><span class="op">;</span></span>
|
||
<span id="cb9-9"><a href="#cb9-9"></a> gtk_scrolled_window_set_child <span class="op">(</span>scr<span class="op">,</span> GTK_WIDGET <span class="op">(</span>list<span class="op">));</span></span>
|
||
<span id="cb9-10"><a href="#cb9-10"></a> <span class="op">}</span><span class="cf">else</span> <span class="op">{</span></span>
|
||
<span id="cb9-11"><a href="#cb9-11"></a> other <span class="op">=</span> <span class="st">"list"</span><span class="op">;</span></span>
|
||
<span id="cb9-12"><a href="#cb9-12"></a> gtk_scrolled_window_set_child <span class="op">(</span>scr<span class="op">,</span> GTK_WIDGET <span class="op">(</span>grid<span class="op">));</span></span>
|
||
<span id="cb9-13"><a href="#cb9-13"></a> <span class="op">}</span></span>
|
||
<span id="cb9-14"><a href="#cb9-14"></a> css <span class="op">=</span> g_strdup_printf <span class="op">(</span><span class="st">"button#btn%s {background: silver;} button#btn%s {background: white;}"</span><span class="op">,</span> view<span class="op">,</span> other<span class="op">);</span></span>
|
||
<span id="cb9-15"><a href="#cb9-15"></a> gtk_css_provider_load_from_data <span class="op">(</span>provider<span class="op">,</span> css<span class="op">,</span> <span class="op">-</span><span class="dv">1</span><span class="op">);</span></span>
|
||
<span id="cb9-16"><a href="#cb9-16"></a> g_free <span class="op">(</span>css<span class="op">);</span></span>
|
||
<span id="cb9-17"><a href="#cb9-17"></a> g_action_change_state <span class="op">(</span>G_ACTION <span class="op">(</span>action<span class="op">),</span> parameter<span class="op">);</span></span>
|
||
<span id="cb9-18"><a href="#cb9-18"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>The second parameter of this handler is the target of the clicked
|
||
button. Its type is GVariant.</p>
|
||
<ul>
|
||
<li>If <code>btnlist</code> has been clicked, then
|
||
<code>parameter</code> is a GVariant of the string “list”.</li>
|
||
<li>If <code>btngrid</code> has been clicked, then
|
||
<code>parameter</code> is a GVariant of the string “grid”.</li>
|
||
</ul>
|
||
<p>The third parameter <code>user_data</code> points NULL and it is
|
||
ignored here.</p>
|
||
<ul>
|
||
<li>3: <code>g_variant_get_string</code> gets the string from the
|
||
GVariant variable.</li>
|
||
<li>7-13: Sets the child of <code>scr</code>. The function
|
||
<code>gtk_scrolled_window_set_child</code> decreases the reference count
|
||
of the old child by one. And it increases the reference count of the new
|
||
child by one.</li>
|
||
<li>14-16: Sets the CSS for the buttons. The background of the clicked
|
||
button will be silver color and the other button will be white.</li>
|
||
<li>17: Changes the state of the action.</li>
|
||
</ul>
|
||
<h2 id="activate-signal-on-gtklistview-and-gtkgridview">Activate signal
|
||
on GtkListView and GtkGridView</h2>
|
||
<p>Views (GtkListView and GtkGridView) have an “activate” signal. It is
|
||
emitted when an item in the view is double clicked or the enter key is
|
||
pressed. You can do anything you like by connecting the “activate”
|
||
signal to the handler.</p>
|
||
<p>The example <code>list4</code> launches <code>tfe</code> text file
|
||
editor if the item of the list is a text file.</p>
|
||
<div class="sourceCode" id="cb10"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>list_activate <span class="op">(</span>GtkListView <span class="op">*</span>list<span class="op">,</span> <span class="dt">int</span> position<span class="op">,</span> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a> GFileInfo <span class="op">*</span>info <span class="op">=</span> G_FILE_INFO <span class="op">(</span>g_list_model_get_item <span class="op">(</span>G_LIST_MODEL <span class="op">(</span>gtk_list_view_get_model <span class="op">(</span>list<span class="op">)),</span> position<span class="op">));</span></span>
|
||
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a> launch_tfe_with_file <span class="op">(</span>info<span class="op">);</span></span>
|
||
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
|
||
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>grid_activate <span class="op">(</span>GtkGridView <span class="op">*</span>grid<span class="op">,</span> <span class="dt">int</span> position<span class="op">,</span> gpointer user_data<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a> GFileInfo <span class="op">*</span>info <span class="op">=</span> G_FILE_INFO <span class="op">(</span>g_list_model_get_item <span class="op">(</span>G_LIST_MODEL <span class="op">(</span>gtk_grid_view_get_model <span class="op">(</span>grid<span class="op">)),</span> position<span class="op">));</span></span>
|
||
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a> launch_tfe_with_file <span class="op">(</span>info<span class="op">);</span></span>
|
||
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
|
||
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a><span class="op">...</span> <span class="op">...</span></span>
|
||
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a><span class="op">...</span> <span class="op">...</span></span>
|
||
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a> g_signal_connect <span class="op">(</span>GTK_LIST_VIEW <span class="op">(</span>list<span class="op">),</span> <span class="st">"activate"</span><span class="op">,</span> G_CALLBACK <span class="op">(</span>list_activate<span class="op">),</span> NULL<span class="op">);</span></span>
|
||
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a> g_signal_connect <span class="op">(</span>GTK_GRID_VIEW <span class="op">(</span>grid<span class="op">),</span> <span class="st">"activate"</span><span class="op">,</span> G_CALLBACK <span class="op">(</span>grid_activate<span class="op">),</span> NULL<span class="op">);</span></span></code></pre></div>
|
||
<p>The second parameter of each handler is the position of the item
|
||
(GFileInfo) of the GListModel. So you can get the item with
|
||
<code>g_list_model_get_item</code> function.</p>
|
||
<h3 id="content-type-and-application-launch">Content type and
|
||
application launch</h3>
|
||
<p>The function <code>launch_tfe_with_file</code> gets a file from the
|
||
GFileInfo instance. If the file is a text file, it launches
|
||
<code>tfe</code> with the file.</p>
|
||
<p>GFileInfo has information about file type. The file type is like
|
||
“text/plain”, “text/x-csrc” and so on. It is called content type.
|
||
Content type can be got with <code>g_file_info_get_content_type</code>
|
||
function.</p>
|
||
<div class="sourceCode" id="cb11"><pre
|
||
class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb11-1"><a href="#cb11-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
|
||
<span id="cb11-2"><a href="#cb11-2"></a>launch_tfe_with_file <span class="op">(</span>GFileInfo <span class="op">*</span>info<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb11-3"><a href="#cb11-3"></a> GError <span class="op">*</span>err <span class="op">=</span> NULL<span class="op">;</span></span>
|
||
<span id="cb11-4"><a href="#cb11-4"></a> GFile <span class="op">*</span>file<span class="op">;</span></span>
|
||
<span id="cb11-5"><a href="#cb11-5"></a> GList <span class="op">*</span>files <span class="op">=</span> NULL<span class="op">;</span></span>
|
||
<span id="cb11-6"><a href="#cb11-6"></a> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>content_type<span class="op">;</span></span>
|
||
<span id="cb11-7"><a href="#cb11-7"></a> <span class="dt">const</span> <span class="dt">char</span> <span class="op">*</span>text_type <span class="op">=</span> <span class="st">"text/"</span><span class="op">;</span></span>
|
||
<span id="cb11-8"><a href="#cb11-8"></a> GAppInfo <span class="op">*</span>appinfo<span class="op">;</span></span>
|
||
<span id="cb11-9"><a href="#cb11-9"></a> <span class="dt">int</span> i<span class="op">;</span></span>
|
||
<span id="cb11-10"><a href="#cb11-10"></a></span>
|
||
<span id="cb11-11"><a href="#cb11-11"></a> <span class="cf">if</span> <span class="op">(!</span> info<span class="op">)</span></span>
|
||
<span id="cb11-12"><a href="#cb11-12"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb11-13"><a href="#cb11-13"></a> content_type <span class="op">=</span> g_file_info_get_content_type <span class="op">(</span>info<span class="op">);</span></span>
|
||
<span id="cb11-14"><a href="#cb11-14"></a><span class="pp">#ifdef debug</span></span>
|
||
<span id="cb11-15"><a href="#cb11-15"></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> content_type<span class="op">);</span></span>
|
||
<span id="cb11-16"><a href="#cb11-16"></a><span class="pp">#endif</span></span>
|
||
<span id="cb11-17"><a href="#cb11-17"></a> <span class="cf">if</span> <span class="op">(!</span> content_type<span class="op">)</span></span>
|
||
<span id="cb11-18"><a href="#cb11-18"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb11-19"><a href="#cb11-19"></a> <span class="cf">for</span> <span class="op">(</span>i<span class="op">=</span><span class="dv">0</span><span class="op">;</span>i<span class="op"><</span><span class="dv">5</span><span class="op">;++</span>i<span class="op">)</span> <span class="op">{</span> <span class="co">/* compare the first 5 characters */</span></span>
|
||
<span id="cb11-20"><a href="#cb11-20"></a> <span class="cf">if</span> <span class="op">(</span>content_type<span class="op">[</span>i<span class="op">]</span> <span class="op">!=</span> text_type<span class="op">[</span>i<span class="op">])</span></span>
|
||
<span id="cb11-21"><a href="#cb11-21"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb11-22"><a href="#cb11-22"></a> <span class="op">}</span></span>
|
||
<span id="cb11-23"><a href="#cb11-23"></a> appinfo <span class="op">=</span> g_app_info_create_from_commandline <span class="op">(</span><span class="st">"tfe"</span><span class="op">,</span> <span class="st">"tfe"</span><span class="op">,</span> G_APP_INFO_CREATE_NONE<span class="op">,</span> <span class="op">&</span>err<span class="op">);</span></span>
|
||
<span id="cb11-24"><a href="#cb11-24"></a> <span class="cf">if</span> <span class="op">(</span>err<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb11-25"><a href="#cb11-25"></a> g_printerr <span class="op">(</span><span class="st">"%s</span><span class="sc">\n</span><span class="st">"</span><span class="op">,</span> err<span class="op">-></span>message<span class="op">);</span></span>
|
||
<span id="cb11-26"><a href="#cb11-26"></a> g_error_free <span class="op">(</span>err<span class="op">);</span></span>
|
||
<span id="cb11-27"><a href="#cb11-27"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb11-28"><a href="#cb11-28"></a> <span class="op">}</span></span>
|
||
<span id="cb11-29"><a href="#cb11-29"></a> err <span class="op">=</span> NULL<span class="op">;</span></span>
|
||
<span id="cb11-30"><a href="#cb11-30"></a> file <span class="op">=</span> g_file_new_for_path <span class="op">(</span>g_file_info_get_name <span class="op">(</span>info<span class="op">));</span></span>
|
||
<span id="cb11-31"><a href="#cb11-31"></a> files <span class="op">=</span> g_list_append <span class="op">(</span>files<span class="op">,</span> file<span class="op">);</span></span>
|
||
<span id="cb11-32"><a href="#cb11-32"></a> <span class="cf">if</span> <span class="op">(!</span> <span class="op">(</span>g_app_info_launch <span class="op">(</span>appinfo<span class="op">,</span> files<span class="op">,</span> NULL<span class="op">,</span> <span class="op">&</span>err<span class="op">)))</span> <span class="op">{</span></span>
|
||
<span id="cb11-33"><a href="#cb11-33"></a> g_printerr <span class="op">(</span><span class="st">"%s</span><span class="sc">\n</span><span class="st">"</span><span class="op">,</span> err<span class="op">-></span>message<span class="op">);</span></span>
|
||
<span id="cb11-34"><a href="#cb11-34"></a> g_error_free <span class="op">(</span>err<span class="op">);</span></span>
|
||
<span id="cb11-35"><a href="#cb11-35"></a> <span class="op">}</span></span>
|
||
<span id="cb11-36"><a href="#cb11-36"></a> g_list_free_full <span class="op">(</span>files<span class="op">,</span> g_object_unref<span class="op">);</span></span>
|
||
<span id="cb11-37"><a href="#cb11-37"></a> g_object_unref <span class="op">(</span>appinfo<span class="op">);</span></span>
|
||
<span id="cb11-38"><a href="#cb11-38"></a><span class="op">}</span></span></code></pre></div>
|
||
<ul>
|
||
<li>13: Gets the content type of the file from GFileInfo.</li>
|
||
<li>14-16: Prints the content type if “debug” is defined. This is only
|
||
useful to know a content type of a file. If you don’t want this, delete
|
||
or uncomment the definition <code>#define debug 1</code> iat line 6 in
|
||
the source file.</li>
|
||
<li>17-22: If no content type or the content type doesn’t begin with
|
||
“text/”,the function returns.</li>
|
||
<li>23: Creates GAppInfo object of <code>tfe</code> application.
|
||
GAppInfo is an interface and the variable <code>appinfo</code> points a
|
||
GDesktopAppInfo instance. GAppInfo is a collection of information of
|
||
applications.</li>
|
||
<li>32: Launches the application (<code>tfe</code>) with an argument
|
||
<code>file</code>. <code>g_app_info_launch</code> has four parameters.
|
||
The first parameter is GAppInfo object. The second parameter is a list
|
||
of GFile objects. In this function, only one GFile instance is given to
|
||
<code>tfe</code>, but you can give more arguments. The third parameter
|
||
is GAppLaunchContext, but this program gives NULL instead. The last
|
||
parameter is the pointer to the pointer to a GError.</li>
|
||
<li>36: <code>g_list_free_full</code> frees the memories used by the
|
||
list and items.</li>
|
||
</ul>
|
||
<p>If your distribution supports GTK 4, using
|
||
<code>g_app_info_launch_default_for_uri</code> is convenient. The
|
||
function automatically determines the default application from the file
|
||
and launches it. For example, if the file is text, then it launches
|
||
gedit with the file. Such feature comes from desktop.</p>
|
||
<h2 id="compilation-and-execution">Compilation and execution</h2>
|
||
<p>The source files are located in src/list4 directory. To compile and
|
||
execute list4, type as follows.</p>
|
||
<pre><code>$ cd list4 # or cd src/list4. It depends your current directory.
|
||
$ meson _build
|
||
$ ninja -C _build
|
||
$ _build/list4</code></pre>
|
||
<p>Then a file list appears as a list style. Click on a button on the
|
||
tool bar so that you can change the style to grid or back to list.
|
||
Double click “list4.c” item, then <code>tfe</code> text editor runs with
|
||
the argument “list4.c”. The following is the screenshot.</p>
|
||
<figure>
|
||
<img src="image/screenshot_list4.png" alt="Screenshot" />
|
||
<figcaption aria-hidden="true">Screenshot</figcaption>
|
||
</figure>
|
||
<h2 id="gbytes-property-of-gtkbuilderlistitemfactory">“gbytes” property
|
||
of GtkBuilderListItemFactory</h2>
|
||
<p>GtkBuilderListItemFactory has “gbytes” property. The property
|
||
contains a byte sequence of ui data. If you use this property, you can
|
||
put the contents of <code>factory_list.ui</code> and
|
||
<code>factory_grid.ui</code>into <code>list4.ui</code>. The following
|
||
shows a part of the new ui file (<code>list5.ui</code>).</p>
|
||
<div class="sourceCode" id="cb13"><pre
|
||
class="sourceCode xml"><code class="sourceCode xml"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkListView"</span><span class="ot"> id=</span><span class="st">"list"</span>></span>
|
||
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>></span>
|
||
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkSingleSelection"</span><span class="ot"> id=</span><span class="st">"singleselection"</span>></span>
|
||
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"model"</span>></span>
|
||
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkDirectoryList"</span><span class="ot"> id=</span><span class="st">"directory_list"</span>></span>
|
||
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"attributes"</span>>standard::name,standard::icon,standard::content-type</<span class="kw">property</span>></span>
|
||
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"factory"</span>></span>
|
||
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a> <<span class="kw">object</span><span class="ot"> class=</span><span class="st">"GtkBuilderListItemFactory"</span>></span>
|
||
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a> <<span class="kw">property</span><span class="ot"> name=</span><span class="st">"bytes"</span>><span class="bn"><![CDATA[</span></span>
|
||
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a><?xml version="1.0" encoding="UTF-8"?></span>
|
||
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a><interface></span>
|
||
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a> <template class="GtkListItem"></span>
|
||
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a> <property name="child"></span>
|
||
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a> <object class="GtkBox"></span>
|
||
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a> <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property></span>
|
||
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a> <property name="spacing">20</property></span>
|
||
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a> <child></span>
|
||
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a> <object class="GtkImage"></span>
|
||
<span id="cb13-23"><a href="#cb13-23" aria-hidden="true" tabindex="-1"></a> <binding name="gicon"></span>
|
||
<span id="cb13-24"><a href="#cb13-24" aria-hidden="true" tabindex="-1"></a> <closure type="GIcon" function="get_icon"></span>
|
||
<span id="cb13-25"><a href="#cb13-25" aria-hidden="true" tabindex="-1"></a> <lookup name="item">GtkListItem</lookup></span>
|
||
<span id="cb13-26"><a href="#cb13-26" aria-hidden="true" tabindex="-1"></a> </closure></span>
|
||
<span id="cb13-27"><a href="#cb13-27" aria-hidden="true" tabindex="-1"></a> </binding></span>
|
||
<span id="cb13-28"><a href="#cb13-28" aria-hidden="true" tabindex="-1"></a> </object></span>
|
||
<span id="cb13-29"><a href="#cb13-29" aria-hidden="true" tabindex="-1"></a> </child></span>
|
||
<span id="cb13-30"><a href="#cb13-30" aria-hidden="true" tabindex="-1"></a> <child></span>
|
||
<span id="cb13-31"><a href="#cb13-31" aria-hidden="true" tabindex="-1"></a> <object class="GtkLabel"></span>
|
||
<span id="cb13-32"><a href="#cb13-32" aria-hidden="true" tabindex="-1"></a> <property name="hexpand">TRUE</property></span>
|
||
<span id="cb13-33"><a href="#cb13-33" aria-hidden="true" tabindex="-1"></a> <property name="xalign">0</property></span>
|
||
<span id="cb13-34"><a href="#cb13-34" aria-hidden="true" tabindex="-1"></a> <binding name="label"></span>
|
||
<span id="cb13-35"><a href="#cb13-35" aria-hidden="true" tabindex="-1"></a> <closure type="gchararray" function="get_file_name"></span>
|
||
<span id="cb13-36"><a href="#cb13-36" aria-hidden="true" tabindex="-1"></a> <lookup name="item">GtkListItem</lookup></span>
|
||
<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a> </closure></span>
|
||
<span id="cb13-38"><a href="#cb13-38" aria-hidden="true" tabindex="-1"></a> </binding></span>
|
||
<span id="cb13-39"><a href="#cb13-39" aria-hidden="true" tabindex="-1"></a> </object></span>
|
||
<span id="cb13-40"><a href="#cb13-40" aria-hidden="true" tabindex="-1"></a> </child></span>
|
||
<span id="cb13-41"><a href="#cb13-41" aria-hidden="true" tabindex="-1"></a> </object></span>
|
||
<span id="cb13-42"><a href="#cb13-42" aria-hidden="true" tabindex="-1"></a> </property></span>
|
||
<span id="cb13-43"><a href="#cb13-43" aria-hidden="true" tabindex="-1"></a> </template></span>
|
||
<span id="cb13-44"><a href="#cb13-44" aria-hidden="true" tabindex="-1"></a></interface></span>
|
||
<span id="cb13-45"><a href="#cb13-45" aria-hidden="true" tabindex="-1"></a> <span class="bn">]]></span></<span class="kw">property</span>></span>
|
||
<span id="cb13-46"><a href="#cb13-46" aria-hidden="true" tabindex="-1"></a> </<span class="kw">object</span>></span>
|
||
<span id="cb13-47"><a href="#cb13-47" aria-hidden="true" tabindex="-1"></a> </<span class="kw">property</span>></span>
|
||
<span id="cb13-48"><a href="#cb13-48" aria-hidden="true" tabindex="-1"></a> </<span class="kw">object</span>></span></code></pre></div>
|
||
<p>CDATA section begins with “<[CDATA[” and ends with ”]]>”. The
|
||
contents of CDATA section is recognized as a string. Any character, even
|
||
if it is a key syntax marker such as ‘<’ or ‘>’, is recognized
|
||
literally. Therefore, the text between “<[CDATA[” and ”]]>” is
|
||
inserted to “bytes” property as it is.</p>
|
||
<p>This method decreases the number of ui files. But, the new ui file is
|
||
a bit complicated especially for the beginners. If you feel some
|
||
difficulty, it is better for you to separate the ui file.</p>
|
||
<p>A directory src/list5 includes the ui file above.</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>
|