From 11e0332b849224e490337b199d2370f9d5df25d2 Mon Sep 17 00:00:00 2001 From: Toshio Sekiya Date: Mon, 21 Dec 2020 21:12:05 +0900 Subject: [PATCH] Initialize git. Unstable version. --- .gitignore | 5 + Rakefile | 55 +++ Readme.md | 22 ++ Readme_for_developers.md | 151 ++++++++ image/TfeTextView.png | Bin 0 -> 40601 bytes image/TfeTextViewClass.png | Bin 0 -> 78173 bytes image/box.png | Bin 0 -> 4856 bytes image/child.png | Bin 0 -> 10879 bytes image/dispose_handler.png | Bin 0 -> 26557 bytes image/menu.png | Bin 0 -> 12993 bytes image/menu1.png | Bin 0 -> 22655 bytes image/menu1_screenshot.png | Bin 0 -> 8376 bytes image/menu2.png | Bin 0 -> 15142 bytes image/menu3.png | Bin 0 -> 15200 bytes image/menu_structure.png | Bin 0 -> 25493 bytes image/open.png | Bin 0 -> 45838 bytes image/refcount.png | Bin 0 -> 13128 bytes image/saveas.png | Bin 0 -> 18529 bytes image/screenshot_gtk_notebook.png | Bin 0 -> 53033 bytes image/screenshot_lb1.png | Bin 0 -> 3949 bytes image/screenshot_lb2.png | Bin 0 -> 20950 bytes image/screenshot_lb4.png | Bin 0 -> 5649 bytes image/screenshot_pr3.png | Bin 0 -> 2895 bytes image/screenshot_pr4.png | Bin 0 -> 3265 bytes image/screenshot_tfe2.png | Bin 0 -> 44137 bytes image/screenshot_tfv1.png | Bin 0 -> 22128 bytes image/screenshot_tfv3.png | Bin 0 -> 27385 bytes image/window_widget.png | Bin 0 -> 17674 bytes lib/lib_sec_file.rb | 142 +++++++ lib/lib_src2md.rb | 70 ++++ sec1.md | 284 ++++++++++++++ sec10.md | 345 +++++++++++++++++ sec11.md | 204 ++++++++++ sec12.md | 269 +++++++++++++ sec13.md | 619 ++++++++++++++++++++++++++++++ sec14.md | 215 +++++++++++ sec15.md | 369 ++++++++++++++++++ sec16.md | 336 ++++++++++++++++ sec17.md | 5 + sec2.md | 309 +++++++++++++++ sec3.md | 164 ++++++++ sec4.md | 304 +++++++++++++++ sec5.md | 347 +++++++++++++++++ sec6.md | 450 ++++++++++++++++++++++ sec7.md | 421 ++++++++++++++++++++ sec8.md | 426 ++++++++++++++++++++ sec9.md | 162 ++++++++ src/class_gobject.c | 38 ++ src/classes.c | 108 ++++++ src/gvarianttype_test.c | 8 + src/lb1.c | 29 ++ src/lb2.c | 35 ++ src/lb3.c | 36 ++ src/lb4.c | 58 +++ src/menu1.c | 47 +++ src/menu2.c | 105 +++++ src/menu3/menu3.c | 106 +++++ src/menu3/menu3.gresource.xml | 6 + src/menu3/menu3.ui | 72 ++++ src/menu3/meson.build | 10 + src/misc/pr1.c | 13 + src/misc/pr2.c | 19 + src/misc/pr3.c | 23 ++ src/misc/pr4.c | 24 ++ src/sec1.src.md | 238 ++++++++++++ src/sec10.src.md | 176 +++++++++ src/sec11.src.md | 92 +++++ src/sec12.src.md | 153 ++++++++ src/sec13.src.md | 45 +++ src/sec14.src.md | 168 ++++++++ src/sec15.src.md | 257 +++++++++++++ src/sec16.src.md | 145 +++++++ src/sec17.src.md | 4 + src/sec2.src.md | 141 +++++++ src/sec3.src.md | 57 +++ src/sec4.src.md | 178 +++++++++ src/sec5.src.md | 187 +++++++++ src/sec6.src.md | 174 +++++++++ src/sec7.src.md | 191 +++++++++ src/sec8.src.md | 258 +++++++++++++ src/sec9.src.md | 135 +++++++ src/tfe1.c | 136 +++++++ src/tfe2.c | 146 +++++++ src/tfe3.c | 107 ++++++ src/tfe3.gresource.xml | 6 + src/tfe3.ui | 59 +++ src/tfe4/Makefile | 19 + src/tfe4/Rakefile | 25 ++ src/tfe4/meson.build | 10 + src/tfe4/tfe.c | 70 ++++ src/tfe4/tfe.gresource.xml | 6 + src/tfe4/tfe.ui | 59 +++ src/tfe4/tfetextview.c | 34 ++ src/tfe4/tfetextview.h | 14 + src/tfe5/meson.build | 10 + src/tfe5/tfe.gresource.xml | 6 + src/tfe5/tfe.h | 4 + src/tfe5/tfe.ui | 64 +++ src/tfe5/tfeapplication.c | 117 ++++++ src/tfe5/tfenotebook.c | 114 ++++++ src/tfe5/tfenotebook.h | 12 + src/tfe5/tfetextview.c | 218 +++++++++++ src/tfe5/tfetextview.h | 29 ++ src/tfv1.c | 46 +++ src/tfv2.c | 50 +++ src/tfv3.c | 56 +++ src/tfv4.c | 71 ++++ src2md.rb | 21 + 108 files changed, 10519 insertions(+) create mode 100644 .gitignore create mode 100755 Rakefile create mode 100644 Readme.md create mode 100755 Readme_for_developers.md create mode 100644 image/TfeTextView.png create mode 100644 image/TfeTextViewClass.png create mode 100644 image/box.png create mode 100644 image/child.png create mode 100644 image/dispose_handler.png create mode 100644 image/menu.png create mode 100644 image/menu1.png create mode 100644 image/menu1_screenshot.png create mode 100644 image/menu2.png create mode 100644 image/menu3.png create mode 100644 image/menu_structure.png create mode 100644 image/open.png create mode 100644 image/refcount.png create mode 100644 image/saveas.png create mode 100644 image/screenshot_gtk_notebook.png create mode 100644 image/screenshot_lb1.png create mode 100644 image/screenshot_lb2.png create mode 100644 image/screenshot_lb4.png create mode 100644 image/screenshot_pr3.png create mode 100644 image/screenshot_pr4.png create mode 100644 image/screenshot_tfe2.png create mode 100644 image/screenshot_tfv1.png create mode 100644 image/screenshot_tfv3.png create mode 100644 image/window_widget.png create mode 100644 lib/lib_sec_file.rb create mode 100755 lib/lib_src2md.rb create mode 100644 sec1.md create mode 100644 sec10.md create mode 100644 sec11.md create mode 100644 sec12.md create mode 100644 sec13.md create mode 100644 sec14.md create mode 100644 sec15.md create mode 100644 sec16.md create mode 100644 sec17.md create mode 100644 sec2.md create mode 100644 sec3.md create mode 100644 sec4.md create mode 100644 sec5.md create mode 100644 sec6.md create mode 100644 sec7.md create mode 100644 sec8.md create mode 100644 sec9.md create mode 100644 src/class_gobject.c create mode 100644 src/classes.c create mode 100644 src/gvarianttype_test.c create mode 100644 src/lb1.c create mode 100644 src/lb2.c create mode 100644 src/lb3.c create mode 100644 src/lb4.c create mode 100644 src/menu1.c create mode 100644 src/menu2.c create mode 100644 src/menu3/menu3.c create mode 100644 src/menu3/menu3.gresource.xml create mode 100644 src/menu3/menu3.ui create mode 100644 src/menu3/meson.build create mode 100644 src/misc/pr1.c create mode 100644 src/misc/pr2.c create mode 100644 src/misc/pr3.c create mode 100644 src/misc/pr4.c create mode 100644 src/sec1.src.md create mode 100644 src/sec10.src.md create mode 100644 src/sec11.src.md create mode 100644 src/sec12.src.md create mode 100644 src/sec13.src.md create mode 100644 src/sec14.src.md create mode 100644 src/sec15.src.md create mode 100644 src/sec16.src.md create mode 100644 src/sec17.src.md create mode 100644 src/sec2.src.md create mode 100644 src/sec3.src.md create mode 100644 src/sec4.src.md create mode 100644 src/sec5.src.md create mode 100644 src/sec6.src.md create mode 100644 src/sec7.src.md create mode 100644 src/sec8.src.md create mode 100644 src/sec9.src.md create mode 100644 src/tfe1.c create mode 100644 src/tfe2.c create mode 100644 src/tfe3.c create mode 100644 src/tfe3.gresource.xml create mode 100644 src/tfe3.ui create mode 100644 src/tfe4/Makefile create mode 100644 src/tfe4/Rakefile create mode 100644 src/tfe4/meson.build create mode 100644 src/tfe4/tfe.c create mode 100644 src/tfe4/tfe.gresource.xml create mode 100644 src/tfe4/tfe.ui create mode 100644 src/tfe4/tfetextview.c create mode 100644 src/tfe4/tfetextview.h create mode 100644 src/tfe5/meson.build create mode 100644 src/tfe5/tfe.gresource.xml create mode 100644 src/tfe5/tfe.h create mode 100644 src/tfe5/tfe.ui create mode 100644 src/tfe5/tfeapplication.c create mode 100644 src/tfe5/tfenotebook.c create mode 100644 src/tfe5/tfenotebook.h create mode 100644 src/tfe5/tfetextview.c create mode 100644 src/tfe5/tfetextview.h create mode 100644 src/tfv1.c create mode 100644 src/tfv2.c create mode 100644 src/tfv3.c create mode 100644 src/tfv4.c create mode 100755 src2md.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24b81f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# .gitignore + +insertfunc.rb +makehtml.rb +pickoutfunc.rb diff --git a/Rakefile b/Rakefile new file mode 100755 index 0000000..4b9296c --- /dev/null +++ b/Rakefile @@ -0,0 +1,55 @@ +require 'rake/clean' + +require_relative 'lib/lib_sec_file.rb' +require_relative 'lib/lib_src2md.rb' + + +srcfiles = [] +FileList['src/*.src.md'].each do |file| + srcfiles << Sec_file.new(file) +end +srcfiles = Sec_files.new srcfiles +srcfiles.renum + +mdfilenames = srcfiles.map {|srcfile| srcfile.to_md} + +CLEAN.append(*mdfilenames) +CLEAN << "Readme.md" + +task default: :md + +task md: mdfilenames + +0.upto(srcfiles.size - 1) do |i| + file srcfiles[i].to_md => (srcfiles[i].c_files << srcfiles[i].path) do + src2md srcfiles[i].path, srcfiles[i].to_md + if srcfiles.size == 1 + nav = "Up: [Readme.md](#{srcfiles[i].dirname}/Readme.md)" + elsif i == 0 + nav = "Up: [Readme.md](#{srcfiles[i].dirname}/Readme.md), Next: [Section 2}](#{srcfiles[1].path})" + elsif i == srcfiles.size - 1 + nav = "Up: [Readme.md](#{srcfiles[i].dirname}/Readme.md), Prev: [Section #{i}}](#{srcfiles[i-1].path})" + else + nav = "Up: [Readme.md](#{srcfiles[i].dirname}/Readme.md), Prev: [Section #{i}}](#{srcfiles[i-1].path}), Next: [Section #{i+2}[(#{srcfiles[i+1].path})" + end + buf = IO.readlines srcfiles[i].to_md + buf.insert(0, nav, "") + buf.append("", nav) + IO.write srcfiles[i].to_md, buf.join + end +end + +task :md do + buf = [ "# Gtk4 TUtorial for beginners\n", "\n" ] + buf << "This tutorial is under development and unstable.\n" + buf << "You should be careful because there might exists bugs, errors or mistakes.\n" + buf << "\n" + 0.upto(srcfiles.size-1) do |i| + h = File.open(srcfiles[i].path) { |file| file.readline } + h = h.gsub(/^#* */,"").chomp + buf << "- [#{h}](#{srcfiles[i].to_md})\n" + end + File.write("Readme.md", buf.join) +end + +task :clean diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..8b6cfa8 --- /dev/null +++ b/Readme.md @@ -0,0 +1,22 @@ +# Gtk4 TUtorial for beginners + +This tutorial is under development and unstable. +You should be careful because there might exists bugs, errors or mistakes. + +- [GtkApplication and GtkApplicationWindow](sec1.md) +- [Widgets (1)](sec2.md) +- [Widgets (2)](sec3.md) +- [Widgets (3)](sec4.md) +- [Define Child object](sec5.md) +- [Ui file and GtkBuiler](sec6.md) +- [Build system](sec7.md) +- [Instance and class](sec8.md) +- [Signals](sec9.md) +- [Functions in TfeTextView](sec10.md) +- [Functions with GtkNotebook](sec11.md) +- [tfeapplication.c](sec12.md) +- [tfe5 source files](sec13.md) +- [Menu and action](sec14.md) +- [Stateful action](sec15.md) +- [Ui file for menu and action entries](sec16.md) +- [GtkMenuButton](sec17.md) diff --git a/Readme_for_developers.md b/Readme_for_developers.md new file mode 100755 index 0000000..13cadce --- /dev/null +++ b/Readme_for_developers.md @@ -0,0 +1,151 @@ +# How to build Gtk4 Tutorial + +## Src.md file and .md file (markdown file) + +This tutorial uses 'github flavored markdown', which is often shortened as GFM. +We will call it `markdown' as a simple form in this document. +If you are not familiar with it, refer the website [github flavoer markdown spec](https://github.github.com/gfm/). + +However, if you want to generate html or latex using pandoc, you need to use the markdown within the syntax common to GFM and pandoc. + +### Definition + +Src.md is similar to markdown but it has two commands which isn't included in markdown. +They are @@@ command and $$$ command. + + @@@ C\_source\_file \[function_list\] + +This command includes the C source file, but if a function list is given, only the functions in the C source file are included. + + $$$ + shell command + ... ... + $$$ + +This command executes the shell command and substitutes the strings in the standard output for the lines between $$$ inclusive. + +These two commands are carried out by scripts like src2md.rb, which is described in the next subsection. + +### Conversion + +A ruby script src2md converts src.md file to md file. + + ruby src2md.rb src.md_file md_file + +This script recognizes and carrys out the commands described in the previous subsection. +For example, it is assumed that there are two files sample.src.md and sample.c. +Their contents are as follows. + + $ cat sample.src.md + The following is the contents of the file 'sample.c'. + + @@@ sample.c + + $ cat sample.c + #include + + int + main(int argc, char **argv) { + printf("Hello world.\n"); + } + +Now, convert sample.src.md to a markdown file sample.md with src2md.rb. + + $ ruby src2md.rb sample.src.md sample.md + $ cat sample.md + The following is the contents of the file 'sample.c'. + + #include + + int + main(int argc, char **argv) { + printf("Hello world.\n"); + } + +Compare sample.src.md and sample.md. +The contents of sample.c is substituted for the line `@@@ sample.c`. + +These two commands have two advantages. + +1. Less typing. +2. You don't need to modify your src.md file, even if the C sourcefile, which is included by @@@ command, is modified. +In the same way, any upgrade of the shell commands described between $$$ commands doesn't affect the src.md file. + +There's a method src2md in the src2md.rb script. +This method converts src.md file into md file. +This method is also used in other ruby scripts like Rakefile. + +## Directory structure + +There are four directories under `gtk4_tutorial` directory. +They are `src`, `image`, `html` and `latex`. + +-src: This directory contains src.md files. +-image: This directory contains image files like png or jpg. +-html: This directory is empty at first. A ruby script will convert md files to html files and store them in this directory. +-latex: This directory is empty at first. A ruby script will convert md files to latexl files and store them in this directory. +-lib: This directory includes ruby library files. + +### Src and top directories + +Src directory contains src.md files. +The top directory, which is gtk_tutorial directory, contains md files correspond to src.md files in src directory. +They are generated by scripts like src2md.rb. +However, usually they are generated by Rakefile. + +Md files are generated from src.md files, so most of the lines in each md file corresponds to the lines in the original src.md file. +But some lines in md files don't have their original lines and they are newly generated by ruby scripts. +Those are mainly links to other md files. +In addition, readme.md file, which have title, table of contents and abstract, is generated by ruby script +and it doesn't have an original src.md file. + +### The name of files in src directory + +Each file in src directory is a section of the whole document. +The name of the files are "sec", number of the section and ".src.md" suffix. +For example, "sec1.src.md", "sec5.src.md" or "sec12.src.md". +They are the files correspond to section 1, section 5 and section 12 respectively. + +### C source file directory + +Src.md files might have @@@ commands and they include C source files. +Such C source files are located in the src directory or its subdirectories. + +Usually, those C files are compiled and tested. +At that time, some auxiliary files and target file like a.out are generated. +If you locate the C source files under src directory, those temporary files make the directory messy. +Therefore, It is a good idea to make subdirectories under src directory and put each C source file under the corresponding subdirectory. + +The name of the subdirectories should be independent of section names. +It is because of renumbering, which will be explained in the next subsection. + +### Renumbering + +Sometimes you want to insert a section. +For example, inserting it between section 4 and section 5. +You can make a temporary section 4.5, that is a rational number between 4 and 5. +However, section numbers are usually integer so it must change to section 5 and the following sections also must be added by one. + +This renumbering is done by a ruby script `renumber.rb`. + +- It changes file names. +- If there are references to sections in src.md files, the section numbers will be automatically renumbered. + +## Rakefile + +Rakefile is a similar file to Makefile, but controlled by rake, which is a make-like program written in ruby. +Rakefile has the following tasks. + +- md: generate markdown files. This is the default. +- html: generate html files. +- latex: generate latex files and a pdf file, which is generated by latex. +- all: generate md, html, latex and pdf files. + +If renumbering is necessary, rake does it before the tasks above. + +### Generate markdown files +#### Readme.nd file +#### Section files +#### Cross reference +### Generate html files +### Generate latex files and a pdf file diff --git a/image/TfeTextView.png b/image/TfeTextView.png new file mode 100644 index 0000000000000000000000000000000000000000..6c81eaafcd96eb33f97efbdb9acbe19795c6fd21 GIT binary patch literal 40601 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 k0BvE-CGgp9M0aWFRWQ_g)3zt2M`~Uy| literal 0 HcmV?d00001 diff --git a/image/TfeTextViewClass.png b/image/TfeTextViewClass.png new file mode 100644 index 0000000000000000000000000000000000000000..35cebea8574fece9a0ffe7604461b56ea930db6f GIT binary patch literal 78173 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

iXiuY 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 Y^bGX%Znu*FAxjZ~WtC)5&kcS5178NEmjD0& literal 0 HcmV?d00001 diff --git a/image/box.png b/image/box.png new file mode 100644 index 0000000000000000000000000000000000000000..7b31757bb590c64b2e9e7069dcb5a414457a37c1 GIT binary patch literal 4856 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 literal 0 HcmV?d00001 diff --git a/image/child.png b/image/child.png new file mode 100644 index 0000000000000000000000000000000000000000..8a733ed5e06ef6c9a0f8518cd1d4883212f9428e GIT binary patch literal 10879 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 literal 0 HcmV?d00001 diff --git a/image/dispose_handler.png b/image/dispose_handler.png new file mode 100644 index 0000000000000000000000000000000000000000..4e2d713fd1868c317c5538443d9748ec3be87c61 GIT binary patch literal 26557 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

M$ab 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 Smm_^6S5-;tdF30|a*n?#{BnA_?vU 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 literal 0 HcmV?d00001 diff --git a/image/menu2.png b/image/menu2.png new file mode 100644 index 0000000000000000000000000000000000000000..b3fa53a2b3a4ac6b70b119169f6e81f09bb4ee88 GIT binary patch literal 15142 zcmajG1yozn)-4>|tw@Vo@B*c{y99T4io3fM3KVxJ?h+h|Yg-D%9fG@SafcV~f4_IX z_rH7JH!{u`87DhC=j^@KoO8`}5}~Xpje$yp3IG5wKr#}l002xP^w2;?gr4bjw7v!a za4mh*wcS)rJSm)994)Nv%qiTwoy;lBy{s(&0I!9r3>}Y6zBdvtb&-a!CBJJ)qIWMb zeeV2mlkMis=UqB2Qxxz~O#3N6!WQYgJe+d9tkbos%O~rrDh!ime%dQfR>y^(h2GsgkN7n`S2}Xt8~d#~F#n>{E6I$xJ>N#4 z%N-4GK6~2yv2HK*ycxP}aBs%jyxM6w?`u$D%Vsj+7FA|;)E?Sk@@H#(DfRYKK0g?C4i@VA_ z=m?e=-RRX(Kf6bIvz-qK9b10&Pfbko^QmbGKYcr8dEPO*CbOX`?fZRo;!+D~u^>9& zeUf7$*|;8YbV2ufSz2-=hmBJ14RIOP*EatCbWjlG8&~D@NMc1tQiJD0JEn*9?Q31= zKuZvkor|cx3zu(hc26t<5~sz9_$4V84~}qpQ5+@Ev7XiN&rZ&fq8_V|w;%@BIx!$6fexWHRXkS5Wso;b-<2uxu4q)`9fkl0Lad5O;jA+9Mp-7}@7kW@W^(VcAAHqAyy~q=|F_T5nZ%A^Y4Z~Io9gJwAbLb!8*+)%Gs4;V3G|T^DI#ILLaZU zD=*+A?l$Fv0m-SN_rVX_{WP?Z(+pupdm*k5;#CB#HLZ z!5WJ-JyJwFAu_dEiouq%gsF=8(WudZ6Pe$dnsj#J1M+tGIr84vI)kSUjkLmVD*5`b z33?RU#irCbqAwdwPb9`&hsGXuuF5*Umo3?tLR9R6uE_c%;_dM=yK`5No89ubX{}2Syl=0}VIGZ+ zsLnXGm6^)dvI<-g>j-oXxw|4&a`@2QwK;&XWX4~d-L9Y!3m;AIffdgviQsp$#{X$y(HAX7H9U94DR{V)iRMd0p<>zelTBR+O z4jVIv=ezTT%@09C*1USdKNu0xs}>N*5dyBY%|E(!bR8z=J0BmGM(rFQG}WVBrG)y} zV48E>^cxW%j$(gjGp-~#`dW!#w=hf}4pNhG))DS+fz z$m`kVx;bIQe=jbCJn_ZvcC3)S>CXDNhGqG&;aV%rAwc(`LXKOw>S?Apv)joRF_UDS zT$G`xA>@|@Uob&Q@lCZ#I^JBEDRq*d#NX&8f;j;q(18bS!qcLu9tg~6ggA|1@0K*E zGQ&>as8#8j27g6#GCsO9@aBWZ&${lPa)m+jrVdUrHd3fU4Bk#`JnCVm8G0X>@YsWP zMT+y}oAPmK?UJ&X*4SrInPHJ6Fz(ViT^Fl7XZ!F z7hL>Mce0k@tQ&@z_->v@T;`3E5OKULK?UyyX4KfDO-9bt91f)jIuY~ikTB;r9{f6x z@I*S7H>iwH@i@yszKp=wv}V0L;hn8cqM4en;RGszA*Ef=I7~bz@Rf*hb%#-_75J)y z-S0~tl!uh2Q!ELN$jc!q+P7o>IXISWpB>0P6kD)3Zepqdk(#PHKp^tfJV-_v4NIq{ zOh;1hIHKhC%axtwuaD@K&ki=`M}33DVzXg#gTb9e9T`OhVjD&Frlj?(qW=KjuBzSK zGhV}&vN$oPL}w^Wb({aAUF^%iNA~Y@Y1kfPRBcsl(g)L|Mqq5iDFg@7u#;lk4F4Xn zM;gde#Q1iE9%D-1*?X945Es{Q_e~n*m~wL--8~$_BrS_5o1&DN2jhOKS)F1r4$(u^ zbQ7+?+#;eEFJt>#i%iY>&m?vOKz%ssSZt@Na6Gk0FNS2#5oAE`CeP^mlJ2NJUh{MR zuHRFfD6S)>+UXI<5>41OG0|ZFk6Y5nI6~PkIJkGo#cRm@B^=!eJKqZSo7@`_gVkIx zKiiPE)5Tb|;#VV^9lCT^sc8*txJ(TWT=C7gQg)~Rw2IQ-lOAUzHnCsE;g+OE#WtO9 zt>C&;f^~`StQFb}3psEU!QP%wil*@Y=p(E6d+u%APA1}~xU$8Rjr}IIEG6W>fn`XDUj^j4723hOX#;eB+%s`d*W5`bki zmhBgpOvwI(mj$GcaY5rG&QFVIk-ABxa**08|?4~UUuf)<4o*2vhG?1?Un$7W0dsIic6pxVdP)3->q;y zNb0q4lh#}SUWKImaevKAN>edzE3s*N#$g>9>P6E!M)l-BY1=phl1YsXu71YeJGdj6 zA}H5JKmts|!=idCoLTBQzWBdQ?=7&7V4U*%_uuAZ$75|rPh5I088 z5~Q=+)uWle$8&a6_g^~XOr{)iIZo6r@RdPR_-vv2VZIB?2Hq|+m=nzJLtLTYKbIAg z7X4w`zB{YTBtg~fNTsSES4}mMyAFM>g_%a=z%uWL>`|M+I7)6(f1h-mE=+(bMA}wF zbGRH+ZD_Bx4DsfBMDn`&oo8IMkPTz?y>h1zD#N+%+hm}4Sn{Wro#t&$J2#~l?s|1`Xz_YA2V5mcg7B8nelvHtPR z5=Y#tYq1mGg{y3JiGy6q< zs*p(D<)vL>!9lQ=xska?2Ah(?shWuHg7Ue=Nt>|#ja{-XO#C*08Z%FK0PYJnvIVtcZI|VarAuokBR%KEsV(T6qurgSU9`z zjM;>XfwVuJLU^yy));qQkCG|uwzp(5I7b{=JS#^-HH zuq0F<%E`8D6uNlMA0=NYM*6D7YI!Y?F(}u|B&ive_1EYs`7zGxi{_EuqfQ;Nt5fXQ z0YLC1%3Hm1`GvY_vR`Osy31*TU_{h*-nGqyKLlwp4wilJSX1`-i7f$&kZ5s)vvAD+ zL#?;BDbgju!w6!$B25&RvH{jvc#n_+`ALF50iI|vwYNvHZB#{NoPY0<#=lc$`=&K-k+9af zOi4&`u8y=EQTA(?61!+srG%1ay9*OW##{XJod8w*u&TBXH!rZVoDF$|Y7_MeK6ssw zn1j}7yxRWjJ-Oc=JwR1x_5e;fgfS5r8Tm~?LH#9fPhu4-I?s6KmKt(4XHr$>;dJx) z2Q?1T6Zd4~cWeSVx;u&U%I4qXtCUs6Jnhu;+{7Gf{e}b)T;SAlw&TYp&VEygIQ@9| zpsaSW|4~fZe=Yu-OBq-Qa|ILuKJi^G8dnj!f466qU-)JCxf3c8tpcdOJV&?in=9+O z)`guGE58JoB^8Yznw7(AMh46pz!$2a@`RGmqNij*d|Hm?v$QkbmWRiSW5b|wtA298 z{afnmXhP2VypyrM;pz?G5EzCvH1KJVwkqo9o%wWQW81LwOw9PpZ*}d;#`dJ_JSOp0 zTv|Wnx-jv>>c0A8!D3g%{E4q39(mLVobBw5I=)FJ@Xw9Xst-hKg6_s*eufqVz>ljXX6Q~eLlYzllsQ$5%nS~ z_3rp~H6CZ@?6+_Nj+Fav1t~m#J|2Xm0v6dmDZ_0z4^0QvH9lkRP^YUaa$i zIQ{m|Sw98}GU1uYN}JS;xqZBr@V2MrQL?`=CAzCdHcbuen`u%hy!bX5TYLmshgm5T zcIc1FYIjSOv6g{@2+@GCb6wlF z=MuKR6`Q(D>G*hchZQCnm)8*iZ|j!%W)1ecY#4vVWHAd&7yVm~kY;n)NkFLgA)H<_ zEpJ=wk|q;Jg*&smRZL%T(FbHZ*js@SI{h@E`}QCZ`8woE9LyHj&U@2Jm7d16`=fxE zI8sYaiP%2@et%|i-ib|OY!)9b$#@inD)$}2msOYI5}OzDyDaaN+o!pSo8iBlrZU6d zIq=tlh>Iit&NjDPO0u7Z{3@DxYh=MoO#yJL!LXQg{xA`pQ}?`Pcrr?S?@YFY^%Xq# zR+;)(-{^!|GdBt; zx8h({D~-uIFAFJ!FbK)AJ_XoE)8(5Oa`r3bn{-9RtbPge9ssg_3A>vm=|;x5a6t7Y zsX-cS2-+|pHJIXk zspUl~AL_q-u@)Cs28oORm*oaE+Oqr;1Z8?eNP3ObimC8%qQ3G-lqnKONRl+7N|s^U zgldw?vpivEZ~z%tVuNje{*3D_4~hC-jaeN`aSOAtwO6!9Mf1$c(D3zat%dybMDSz< zMy%>LM}Eq{~@oz!-h_jiZ^YvEjO*lEfnO*zexE$vujYhLA(ZHU;M0K(5oaGARz# znV9}c7g1PVqSh6EroG+KtHY$By_xeEx}Me5@!LHkM8+5~18ydU>PbF230 zY+|3qN$v;1mNZMmDgFC z1U-Y|B%|XB0HEQ%9x#B6tas3pNNyknNu(_#0ytWHMuO)v0DuAjk`Pt*S~yTSq3@$i5dhD_=socx7D+wp$}=jRs{i(C#1 z>ffmbmOAzB9GYe2(PWuMFsOX7y!|y z%@T#-1OR}j?*n?H)%^L7d}aXPpr`(Q>rFZnr3}{>xtgo3++2-q+`Fn-@24E$Yfq>u!veOws ziV^plK80`zHOV_aj1*6Y<}^^0X*s4~yxkUeQw>K_wGZNMCe1li_{JYhwbx#l)PzI#;~4Qt0*+jlCWF&^-GVn?_;z=dXh5 zcwUmQBHSK-PVxp=#s}l#EZkB#Q4jA~mTEsoOu~x(h?_F2pA84tU>DUdN=iFlW*@Lf zgW>;h=^@3mUg^f1tSB;PNHPeN>8G!Dm(HASm-URB96%_g23M=cjC|#>gxW>#G+vDC zoDY1Tfd&D6po691k^-Zy+526~!-yGS@O1go31PEA>BMp(9yxCDS7W)}cJ9MYnmF6* zL1xA}V2^hOnb(s?wy|Fg9ZQG)*fGb5NdYOWWr8&a~>0 zN)5lNZ-2cPQm&<5e(#1ndC%&1Ng4YM-dCiq5nV2&^Qj)F5f%X)I!$riaKmT*rb+t# zArb?%tW_{iu>})r(!9kys%1hU8zCrla88z}v94lLXOu9)x6i7z zM6)`2;kL^kT8~#^s5Lejvbn&}zdL(U`BAd@q~^Qhah}yFO`DlP^?Pz{&li-$CmtDs4{=y5icBVGdMhlP28R-y~!<}l8T)g z9uugSFTF?KE2jWiJbo~6(bPk@>zYYQi=AlQjh?t;7gCA9DHJt(F0j}MSnOO!j}fxZ zBD?!VJ!Dt%na(rm$tjGK%4cuVTC1#7FmJd~$yP%*C_p?(L^8M}g|1h4Z;=%LUN1Vo zwpN+&^ZTb-8nw?b_INnk$qI>l9$IO};$ag8T7oat)eFr*GFIT7lH|shFsAy3yY}}8 z_f4AWm2zC5=P*1)=RdZS(d`^fa^IG6g{$=}yI8rWsCj;!Gh!MNAMw+vayB%cW(_>M zFdZ0KVgs#AK^sYdrwt+26_0UiH=2UR{qex5WQGC87m#E3Wq!bX=?7#yzvAH_^>iN2 zyNa&kX%40u2f$dBx zET?4VMrpvtKC{^C7smt7cder-WOdt(MsE?$>LlZj3UCxH2^-8p^Q#8B;7kE2`QdBeR z>X=itU)ngHN1Qto_+pr6%A`K}_hVJ7b3;j>{+N=_YO~Kx2uU^1!BBMM zOjlz>`Ui=^xVS_xYA6Y}A-mB#qbtVbhraAKkDoh;7zv+6DuyN>jWIlZ0tM54qxSpX z^dgaLFoANKjS_dWi#ZntnZ@OZZ?pB}n>NS(xE%I8)XYxPt&Eo#Ae@Iw4DA19^gYBH zyhIo(y9txM94KtI+8JcMlFQHk+G2(9aDF+I8gp;u+QbMvq#SZz1=JbHE&m+c{G|y9TG+Z*5KO==r*jpXSt3(DTKT@}%EX9uCite59R~>b zOJ@u|7f2H9q7ID4m$ruiK+zl^3Jaisat}PpKaLK-48qFjPnb{=ML>RO%x>XH98}!5*aJsufjR)uAp|5ET&k@v2SCRP(bD zii(H**!4kRW)x?K^e6Yl0<7~b^hWSBv2p-N@@n%LRnB!~aAJ@ZEk$Qd?M5@d&E3tl zxB)c*xZFskcKWPbDR?r-SYkVbz06hKs;U<*n~1n_mBhl&tBH&FMDpw{=~fw)vQEmUw|7^Qr49zJHdzHd_JhpNoH7<& z301|p_i7LgQMQHj%^4)$U0K8X-&ME$6d0#C43=LNynVx)P-U4eH%jl?oIkNc z&w{6C^D{gwg3o0i7itR|eA6@IAI(UfEWJ&>6_o)K1Q$x?}$Ewt+8-CEMbm9I~Yk`XS5g*5tvAdz3YCh*U#%pXB)d}gyA%k7ME9+~-5s@Wfb zp$M6bm+F{uI*I5#d1kqk%NqQP24gI zT&`BiyH1^LKdZphoA@?0ege}D<^5_p3Jnpi{Wzbjq+_)TeWgif(V|eAt@Si{1>pgI z{NiQKy_iFJ8R2?96jg-x4d7c$wLTfl42AMVA4CHAI_mA8?*$Oj!+e@ClKv3Kw>OAc zUdASxOh5fn+$R8+t_)~E2)qv_sU*6$yd^)w0{$4s!@q|HQW@qO(826SiJPn>ZL`+D z#%hEQS@B*&)@P9@-}h5690c1~q!TDh!fu>wr>Z|$gt_yASJM78N?7u60Kh3(q2e(dDhz)(ip2x|LxN%hyPI|5#%9k` zDlmP>0V44vllM0(YCckZqNi|x*jT9x13fJRejW0_^L>~&rS>PTY+j2?9RKQ()xerR z7Go2TRX?VhvC`jP;A2RH$bLvsP9Sc?(Q<& zmhl>8WXA2Amw=`0viu$=$s-(4!OJrn0%RNn8-fLG?fK2O_SlH6V2qVrJ92a3JUHCkl~@) z6G%(jZ}EM<+jh49@M^Yg824hwb|pBJi2GW9#NRHp`tCu)W~ROvxW9a}qNS?JG!n37 zGSYEsc(uPQmw35%#Oq_ZU!{K;W=l#v0o_}{~5LkEdf9b(GSZwD$ zRR_R>{4bBE^tko8Tkiv8oc`iqBrp~#5`)#kF((!eS7+++nJypa(%iPc47v51r`bHj zW}kZv5?!u$x>{xkki|XwLj*HCZY~f0_zUH_xVRkH)hI*}M0~^$4-E~4-Y_=sYCAf* zGKYOGcZ37FeQ|THp*~1wmrP~|)cSprpzQ1J2`tNEh@;rO#q!wRB zqcG^9@5gV0>5z^~8*8?AOlM#QGJ=ZVM}`hX}Y zDGw%Fzw5K4jq;gA=jhfd*T27#0jZd%Bi2QNBU3YplZv$sY-Ptngi%znDiHFM$1mfc@bsH&*1j=RX{uj35j;d>1@J?8JEvX22yl^=@+ zK`=w6@4E)v4&cRQErbC)gC!czJ>Vrk(CU|eF}=t?ap~WShkwd}S4r?+1EG)@RODYh z-(`NGb%X&eZ;?Q|4uY?W0@2J0?Y|Fu6(au>BmX5W{xM&XXw&0ulF;L=St}aqo&n&N z6rQuu$ZA>7ap3R*Y@f;HA}Kl11Ndu+ns|QhV*lup6!3Uw+4@?A%eyu3c^u_E`#%hF z5JtcOg10DSWn~-P=09%l?96%zF!Ae^jFiAU-B0Mf0_oB#kUBV2lf)W7ZEuO%ES5CN zPpNw-n%BMyqa3Qg>`gN|sHo{yQBg^NLdi5gr-q}TX|APWF z*vsA13ksCbcwAp87^!5%|d>>HLEXfUc)=9j4!qQV$QOP$B7iXK8Na>EZmQ5{&-UO)p#s|uz zQ}jDBP+<}OGvsxfyamXrblR(>e7(F{XrsF&1XbG(hZKyguQIr=X88{_3=LU82Pq5R zeR6uB;eB(m?6W!2Sig8|18K7FoP`6B^x#JTIc*6_(fXcpeTs_u_uU2?=JD|GidtHD z+>a-9K8uKiAYn}Yz*SQI^r@&rC>Of1muX2z`(I$-%9~ve;wfKw02&3_+S@orS2|b# zr*FMMK)G@O2&_Vp8r?h9j}I_ERJf`VG=P90Gu(eEfd3r<$1PY~%b^&ZTgHQAS=W!q1oNf*1g4(72-xFLZ#* z_mA6=5gJz7EkJNXiwvPPKOXU_K6BFItgl}4^Wm!QcZX~!-5zvO4 z$Hi4pg7%!y607vMh8#TUi#-DgEk=IPf)#v^7wRI=L9`!=He{k<*eYIpZzK=&*BRX{3LEHs;94;LiW9KRJf z7_`eK4t5#}3f-V|cKI|y6E|hDGZQr`a?c#V6Gy>XGs#Lc7zvR{C-+Now<4~`59 z9PuWV(U$_jm6a|}(w1WrwoIBf=S83lVb9pC1Vx3`Guo8o?}n99kO%}|{1K^?CvJ}GI{ zG#LXU{rhRA8fJ()M868km@09}C$9uN=-J-rJf+1*Pd|QGp>&4#@cM z{HC|JZ*mCWgvaS+Rnal5CRk@ko^P_w$a*miHOU~|6**6c>S6IFWtOs$JHtNOENOB^ zffrT(jcbjVfVoP%yu1sowrPGsfmh@20C@?B0~6CVj^qm2E}hV!4y{j^q2b{b;tzwA z9CE4hQ`6a=OVyigZs0n@?=3v`i(TT0c(t&XjDW{jB7p{ck~fS>)}YR`o8(k_9$VpAy)&X zxf2zDacI+qUaR5bqz64%;el@#R4F2I(xFe&B}Lof*kF;1 z&-K!Z*~g*Ijw{pW>WD!pT^a!)l+S+)nKwJ(Rg5ufUq%DLN;QUzSIOnmoB3%ld29#~ z%Q%&Dw>t}sW{09!FIDxne>8jhxYL$#{Ipq5>Z4dE+g>`0rOABt0_WYoLSTV6*>E(+gC+mHvKS@y@LoXDDcU$cAuB$WOa-D{D}$W{R)G{rb`Y02~8MK zF7f@4&3L2+9dK4NUHfy8$MGCv?wH;w?i*)#e)nKXn(yQQ67wm{?^NK)E?4g2QhNwD zv2ev1K10sro7M{#eB#xP(MSY<)6s*1w0)zzL&fbE0!F7@E%FUw0vzyf&4F;iECeWs zB1EY3TE2Ok`y&TFNSJ}e4&mQ2;lEJiK;7S>ou4(W69$k+^}oyTSI+%!y!&5-D!t;^ zWzoKRnp9dO0mYP}LEDz_uy7{&{?Qd^Rgx$^G&HJyKWYz+LHd3Nt@!2Y^N(?po(^h; z9u^_ZQ1x5zaFUz<{3kc>3jy;qV{4-#DVKg!ZeUIhY*2}2!Vze-I4_Taruh)q^TDQ} zw~vmV+cxgH=u}l~sL02@CNEFKGRM8C$zicX?vGJHz|%drrA2$y|0X*!GIEarU?nS> zn3fHOPSMM$lx(iU`2Kz6b8TF7v^tbmHZtfK>0F!7>)G+AD!sE8I|BRQ7S1>0eEer* zuVfVj_gtnP8Q3h)cH26s;O~4<+N8c zYiK<%zjSCE&Q_^ONreHyzOs=gox2WK$BSuDrX~>!32%A~$c;o@j*L-?H`iI{xZ_v2 z`y=f3>qnB?uLwBKyZghd&UUm) z9WOM_46$|=Nh+~UN6=+afZ7gE+OL*2dfPT*1FdHww_REb+}0)EY9Z+x9FzM$CbW4R zm%lag6GeN=0_`_U(WDucY;2gW&;Xo(OmCDx5x=OjKBB+MY9FszYTYisP$--Ot!K(1 z_)sznC(B}h((^iwqPMIp9^p3M9v8dEsiujEN$1P`=|W?LA{j^7eLz4!7lGhKC0Q1m zxS3R3Do~KeEbRXBuvAItPTl|En)lNKxHN|fbT9`lM9lT82Qsj+sq}=!jcXbCSAB+4 z+RBCnNS9Ncc@J$PW2OS}@$s#f+g>!nzXB0pVX6$;6`@U&M4+^j(-n>Zl9`U?b`)C- z+=7MBWxOKqm1DSmAavOonVDxAAqJ(;P)Z&z2!;MST@9pEFx~gHbZ}8kl+M9 zr2kSj6A}=VBv4E3&6p2ePK^n3-=ZfUEAI-w5vU{I0pLu5*RqdvW6n{yA!``ZV$Wc zV~nai0HB*vCOG&g(yc8yvr*c41UDsd(f~`4=ev($(ZOG%DUOt+R=os8tK3DNGy6>%0h%b&?{zY=l2VS{CBE312m~00|GmhWPT^$3UVs`vqT`Z zkW{6~H&29SXiC$ubf`2>McmeTYFb56i*kbETS{0!AZ+)3S=Bd-k?rVM@L6%pPs)6k z-ahCXC{#_m!iips=hz_wtQK0x{trv>-(Xpp+Ew~-^*8NnL_kpFzpxN0x&E7v`6|2C z=CBg~X_4%40<0tgE;twcS6uL0E;I~x5`YNdUl<4RncJyvzjn_-i|taiF!X$=mji|e z`7C&BTbK{x<5rB z)eGOKs8~`8odIEBmO0bBnLl~5y&L`e4zdnZmOy!`qRC;t@;bYH#?}{V{-{8z4cwNC zK<7T4vWty!O2Q9W)om8_hW=*=(EOf+`oPGfvm~$AGJlK-#Z@nnuQG`y8L|!#6{x)0 zw_ZH#T((M+gKFUl$J`aZ!)Ue)fqffub4w;c>cZJ=B|`7E9D~Qlni?i*@h2qA$z9^E zc;MYrz=*$1j#RdL(|xX6eV>tYF<0P=U?(OZ@KgM4$2L?vsY5T;oh5U+r1MoyUZisG z@j^l7qsQrN;HsB6^Bdgha`UL3`)#spLFt+*ZSX)6t@ZN~uZt8P=XPJFx~i(!7~Bt> z$+i3{SkEqfwz@`5szwc3=!QWT9{+8w^6vSI?*r)-ky9|VS8A?D7KHE28JzBr=helR|Wam_uNmG(rM%V6b7!k$CWG#K0zV} zchwXXF$J*zf$H%j3OMWQ2jkBW%I`v*zWaxc-81FT_710vT?s??s?lN7dmSjkc&<3N z#~w}=OX)$ClMfl-xr_n@6Gg+?S>^xJOYf=9YYnr;c9TjgbTl);gaseNiGnZ&G7djGCUst^Exta&69mS{foDYz_aDUi7BxZwg%n6)tiU~w^-AaCI3Q4-&rdkm7IpQV^n7~IPRQ1{m8#i*ZShL2Zg zWOK8E{MB>y@i@D<#7Z*W5B1qH=lpwbyy-AXz%>kVmDPZp;cfges< z<;0)Q(|iyHh96D~q5kujX2Nhbw-W!9hxIeAtNYb&rYp!#y2D|%Le7^6-h=(v zuq6b9M$LCnOZPz7DPCyx@2l?UGjvL@7|BsHdtkQ|EQeMsWtQDAub~6Yj||oLuA8L9_@!kps~(8a?j36Tr{fWM`f ziMJLb&=n{@?S9Fhy{^)026rq~Y;Ao4CH}*CJnZz}KmufV#eWG4J8%>aw}D<@quK5# zkv-G_KqFvQmGEjo#Hh?#{2J?F{SYujDk~#X`&w(-19(u0M%KHNs@r6VxdOl_xG&XF zEIdYk-1iIoJiAhvjlis3kE*XQVQOXy1O<``XrtwNYi9GitM0~ z+nE1P9$}-y!@VutzR}ckVc^oE613#Ao&3!NeTald3>}nudHBWC>}=~10qPwWXRsgQ zkU|>K1ZU!3lWO1y2_QY+AO)50rv(>dkXidh_x0j5uw1DkpZOlPfzO#FNh<;%M!pau z5t`g1-vXK^J&q?WiMx~=m?E)Z0KrA;iAjmcS;-Pm2Z6fx>i=p9{>uY=WaBzrk*|Te zoldu!f!}rO>&T&fLmqiKAsy%+@r+=CXbFK>mHt7U&e6Wc$8ZamL$m{eg{l6n^4y(nNn6;^M(Oi63YA*7>rG3wbdti9{`t6EW`v4*A`>gLAE#ya zzckwnRa=3%$r;Jz7jeQy)M`@YdZyghs?-hMHx^aT7LBQX^%9vL$E2g>sBhXCnQ#F- z870T$Ks6?DiRaE2#Osy!*BXUSxIdPBE6T;n#eUOnA@9Vl*mt222>tce4n>@^!v6QOQok_sP?8LNoC^SwRFtR|GYNdHo}a}*t)tTCGIU6@CaMnAI(UbyDEb9nY@ z!XR|!TXM!F)b=yq!aaq_Tb&(mC<8mVq>zS2+-iDqM?GNgo%{Hfc~4MOo*q7vG|=BZ zM-oETczO?%#NSF1MELIHtk=Z$$-2=Uw$6c@klEms)dz*;4f@_cUpKAL1m4Q-7My9A z=sW*BWu$Ok9*pQ<=npt<(QNUy&O{dVdfegF@Qy18UmmP5Gry>noXx4P^W9c&fwbIXvphFwC&!&8zy_b zESsL+WvGm^P*KqS2X>tbD`qbxBUWQwn$^sc%G9Fd;oGLkwf{*6Qou zZ3w-lhT5$&0v?~6+DVkoGqsFLEy^Elkr|nv&@|33>~quXT0HT;sYO6ApxD!dz@Z@D z;b;5fd!SH%(CG{Q!AX;lXt3s+`7uO9BA79RMxkdXUlvY9Lw-Q7u7d(Ui!nw61KBY( zE*h1O{HxwC^Xc5oWXuwolpB2e!OU-T^Zca=stOa)lGHWTljg;RW+OGz>Kez=>QIn1 z+sf*eCD(MNO!CIXGLNHaA4tQQ9k%2}2`sO~?}nKjchrp1EN{qZ=yde9zbb25UK1=q zQ#&m*UeYz4)INUrBg4JFH&Br3wy-Z-#?$<;eF<6S7cjeZ5nDqeTV^{Ocfl&mz%GA@ zLl}d8=E8{leq4|DGS?pUGWC9#?E|%vYHqUi68sM1w?wD+JnQ>S-rTn;UiRwXLF)_a zbo-q~@XuZR(#L~3EG-S?-JR_UE`*VM-e^zC2fCSav?Bjp=umI(nPuhP=)7J{<>4W5 z3wO(jj-9$P^WCm+4}1dqaFp9*E{P1r@;TS+gJ7mo0=;hWudYf7!`l*p=2w0Y22As& zmQeP$yj3bh`f)xXtUI#7Gf#ViHYG!<3ZqE6M10p|Y|jUU1}|lCkxjXcvj>#Nev6`- zo?laOlqsO<`o6i~4HKBEbZMk0^%Zr?pPGKrtT<&io^dpzQJxr^kWtZ-RZb&6?HUy2 z32oMepR0XzR=I7SxHzbAvP8h{h$eQ?-l*TR@UCE&+o{k=&O(PbEV2FZHbD!KxH+Z9{LR@tIUo@id0n0uBTu|aKt8*g?^+dhExJN~G`;UxZ;kH~)K z^&I6-%!uh2h9BkzvIgQg1pAU*6ay^kE)<`?;?$oci-n{gufe7dQbAot)pu4eq=fU? zd{NI3WXSmAsfU8gkBfakA&6(lT2+rYe&@z4wZl$|9|nWqtPPtW)V;MCehOnw!AFr~ zYo-RZ-5V?XGGJ?R;h7$FW;s6TlNUBoOONELCyq-kE= z%=3!fJZd_Vxg>V>P}iKt>ozb>Z@0!S19I3r8BQ=7cRDc-D@291@zZ>tRyYOaCHS&) z7gel!?PpW9t_-o*owVI|j~i~h?{9olwl!n;lqZ&3U}3vk5aX}E>46`P7(}^!5&7g8 zMDfMfMQUW*`R0>_nDo9f`u+M2u1aqR(&daAI${dNH&M zZ0#0QIF9;So2-o8Y4a5&*zg7vQMgbTtXMeNqJHx z`ZY^bB&sHyGx67wHV9u7u=G!OSLjW_-keY@X}g-zAQr_*hEt3N?7Kuv(F@GD*zLiA|!NGB;o z_4^e}-Su~7T0c0Y_~Bq`g+sZoq4mSw)O46bqhOGP!8zZMs(cKNYQzN<4|lKd8#JGi8!Mq(EMp@>>mlo7TZUXuoElk4870mxQp%DhY9=S1?&Rw*WaU zqNZ!tiEtjlDu13+)1Z60b9C@tR1}vsQKrzPu1w~UcRA0{ zZymc5)@p^m;eyY)Ui8d)AN2FILFP0Q4$F-UovaaseNLnE zmt#o(2k6^YB&5JMMS7R8!3^>^=iQ)*4+j)3Z)HUlY0-XLN~W9FT_E7d?_yYxz&I2B*dLGi13g3u(vT{R#T)CflA5kj zv(B3$vF_G0*+@F#xASA9FT?zPc>bG~v&^%rNa^ zCzL)O)h}kVfFu)Iu2EmDa?2R#K1-HYzIMZ1E z>mT)i?(j%fMbLNwBz~to9?8V<-lwbfuX#mp+ati4dU$6y#ip)VTtY(I`WEK%NN4A; zG@=fdJl3ks)qqq&zE zYozT0qobU#eYhfzg(XwE(IB4JYlF+9i9CXOfzN~Zpd)#$B%v#Opgb@I*ON*YGbqiA zqFImWOqwharm}@GtQTc_B$ygXLJT<`V?@?ZvhJU2Uy{A;1Yx>o{_C!xr;Yj7uba$P zk}9%z+eIASs}DINS2nea9AG>4EiVVNtNPZ;EO#cofpbM(?=Qxv5M*q2SE6Br-ThFJ z1XlHWyJQ1qV$yPL)RYUpg!pn8_2_pxHwFyDW$*YkGHqa;si${kP+Up1PM9t~>wl(m z(Skg3=tr!nsQ$((6{jUPkWL<*Xkc+E%0Z&oz(St)!vy9t5;wEyxjo8}lbw^OC~@gp<%+yfPgi^SJo(wEV0;diQte)YVKx&17|+wi9A`E2fN@%JO|XD>|blcs*v zsu-Bl5MFW51W%d=4oFRgcP6JFMWL3h*6>Btfa)a~T_R`*Z?PpTVE1AJ5Cf&mvqk3PdGP-^gHA#Kt|%W;HYN zF=@W&l%nV0zDEphQ!9pG)s`vM)?Qv^jV%bfe<}Z5Z|1~Gip8lF zaHf#oSAO#>3OXV`_(9;K+y=uNIqZ%QQF%GJt;KacF1qari1&s#a;AZC6`53@a756q z^iT~=iMo+GS^2RnuIHd?Ce%mSA(FY zS5uuDRsORp-D9$w{%&>hP7(ajkkhf7AjlnIF3hwqTdZT|&S*-WId)h^DzjqoX4y{m zf_AK|sN~Tz>BU6tHs#`}h?9$EY>RfiSgU~(Rz!0YG6lj(^&ebcO|Uo6(|I3|(VU4qWf8LF&K8 zhfFdIpp|3f(_Nl2LktwF`aP#J{%Zz_+S5SMZ|N&z-TF$V=Hu4Uc~tud8cBnMBImXMY=9635wqTJyvo^KJXq7bBT zSPKmq#MJeQ1x3iTNrB-QtLWM)OC`lpHQGT+Vu#jc&s_c(Y^CC&G#6||WM3F^q~%#r zbeakXs`)LJ`n?{+ka^X-5T$QjjEBblreIs?|yt% z8_tUs?1@Wp_wy2NS=hRlRoHB=4PRZaxqf|y#%2xU(pbs)0`|%79~Vo+TYK|nR{zHa z7A?H4fA4M(hFYi!fsl0Pg5ZwIdLJO|B6F^5G2(ziswrgKYow4VjjsSBuo_Bez`Q-Kup`| zkLX!~zcADt85*t-lCh)FvBWxR*4Fy;W;%M*RA5vD-amnC?Hm*wqENvJ=<3}rHcJuC zw}j58pe%XA9t;SC(4MAmc8^XYs`n-$9N%F1HY477+O2Z0T-QX0ZGTe=3?v*BM!Bf}_SK|KmE zGz7zg`J$=B;f2XE_kyGPahI6JCF=Sm?iX182oD#iv!+O-es5_7v%}G+wYE zRr|-iCj0od9?0#ew~BnC^a=6CiJQF6`0kcVzNV(0MR$s4KK9u1iu#PxjTdu`-d1cf z%lfP_+2qwd%*AKxgk3W5n}Hwmho^;lV+nqO=)R)2m5<<8hO4X}KD0#YhyJxMWP5cu^k zv!x&gSOaJCMa>=rLO^@{K!B1{v4NE^4&u@xFk3K~??`Z`H4v;oAYzcXuz-@w!tt`R z1NwGn-}&hgMM^p?nG*FI-=A`*52QU2h}_ud)ycHyI=N29z|TPemyRg7iUOp<8)*@4=@Ri{81$1||-|!dt;oQ?%poX`QGjQFz%t zz%Snbd%^?XOFQ3~p-4#lG9Y5@92L3`polrfIt%d;ymzo506!BYSX>_x;~rvwvK=QR zk7ew;7;X2-!+tcbhuSK2q~!%o!QTr_Q#jY=z+`Mg0E{pf%J;&WVTn8Z#m?BZD8-1F zgaqsW8Ny+5nBXXVxPTb*0)Zsaz?o$8XET{d2x~$_7(Pknrr12Z4;*|sl>Os*p-vIF zAowUfIvKZnZL0e5yC2rqZB56(*icU=>H~3m=<)rZ45-!9YIz!`YHdG#j6eHsZ_HkO ztY{RGF_4eOftx9Kk^+9(MYfIz4Xodfn9uv7++j}W|Mszb-oP@ruR>SX*O4cAB|t-o zOF@hmw9{i!k3*4mtR^MZ{7^{yR(MPKqEz&E_ykl^AsKnWCYoHb*@zocr2}Tm#-Gy zL2Ix~F~sySZ)7V$Hta_u^36G`)>O9epx@pb&93KOT+IxD^=5|DTGPnZY%#+zk8|u` zq23bib`CVeRn-;sYZ8=RFN&L^p;Rb@nsoKyxzV04+8l{U)*fP`QRL0zmXK=3V;eTO zE@Exn-)A+}Rf=fIOQ?wL6yqEmH@uUkWU*L15N#Mqe3DYatiiJbi8pp$axV#OAu*_> zGBVq$=&R`0HnOiEJRjJZfCGC};N0ey1JT`|`}a{<{C z?b3j4W#Op4mtdIux;U(sUMAa9gp2%??g!5p{M#Z*ymi(9pck z+K|NhlL!f^lONxs9L_*yhwLe^CsL|CD8Vc^x%cw-zar!LS*aAIe=h-k)sXSr+pi;>e*2TVTsd+;+a@s)w|#Saz{aft*qZ?eCqj zX(>&!FHqHi{UESSbzlUcqAd|m6Q1z$6uz|2*JcWvE9Xdd33Ed@3fa{@H3iv~)Q=1! zv)TQ+tWdKd>cbmS!RI#Z2Elnw9M2~xX@riVk)=hGs^{lX$Hvt*-Z09~cP)U;m-Sm96RCO3E-$Hb_o;fb# ziMCSFz8&Y48)s}BVZ5;mDmI87@#kCas((dO|dK6sDCDKj0hMn_87L>YQPV9e1=+9(| zrISi$uNIW}w}|>&Jy`5{TM}mVC8tdKEqGm-!=$DlwaXBS2~hhE!418?7dhPT%@j#0 zj)N6X_ag#N(}H@&GQguEh{3G5?TH2E`bHEn$=m)dzt~t248YCNaf?-s4Cs|9R`S7k zjIHzFXU+Fh;s?Kxzg;M6g8KaZ*jrVV)@o^|bS7B5DB??f`}rc02HC8U*7k$U=YYe1 zbLR7~oKNMsgDkLLs=qN`+`V%;stQ$W_@TcKy#gU(GbFw<=X?C*zN&V?U?a`Z-gb-s zVdSi*Ef8-$2xh+di6{N3jrwS4GAlBLo^iG_l6XnUK6^LN{J^XQ zfcM^nUikNd%F>Qtr8@J6cUP+bdIo;^z`R}zLupTY)!G|jpAo+|I#_-9$nHGy3cQTo zSd^MaYQnC&-!4vybH5>I8#h)`&4d{|3s9q=G#s(HXa4++2G;i0;GsU<&~Ut_v=kBE zLQeYj#1o~+!FJlB=!O*^7)S*G|37%3NM$-MlEju@+!nR07GrO<>9bX#GlA;G>vFbX-#?NkcG}v^XVqz0;a#`*0x;(&%QH{p zieh;AexH2;t#^wgHRnu?y|YhPv{$M3VhlF30oAJIyxYKq?=#WP%gJ)7mVAhxo#BvN zvueeYq2=kZ;BBeqo|pD)N^Qp2JMSbS?}wnbRmSTF>Nb1Mr}INTV7%d9QKTkwnJ?sz zq$GA?&``w9*_1!@;k|^KxZ3?^-VpK1?O1!0)Cihi^mlo})6!@bP1i_w(PFN+Y;S9{ zMwBG8>2Ky+&$T$yJDT}n)E{5cx8?>e%PcR{fGeL-Q0|#Z@6qFzrzDo))8Dqf@%Ywn zFSyjyc6M{Xq_V`yHfC^SY;5|nBVfi2hFtEYEZ?2;OL-9X@brW$k>dw@>2K$4qNlm30{UbLDOE{t+1;q%*yE zI-cXKeQ|LC>K_=$k`8cJtMm|gx%vI4I8QC5)*zj$K&2({sRn{ky5Bw-eCc?M{Ml$k z4bxIa|I6XV@V+*oHZlUF5h3a2_se)bfhlI!)2{R4Z`W|hJT`pRZRfa-W&u%Y_Sfdj zJTEhGu1p1t);r832eaU*$Bp%MfhqUw`-c?o&HA%dpOd+ol&x3;^*S@#9!pB8q`^U1 zWu{DR?cNqPXd)u(bXQ&W-O;oHnG%L@0zMgaH%?FhT6ko9`sj-1>aKO0`zf#B_aEn1 zXVbs6gkKhXJX-00tQmXtgM$g|1G#r+!1(S9_uQBs37wIwJ%NS$LaMIFS|_T}TlNhW zJRUFkJW*w>E3teUChwPHSqVnzX(@IXq^Fk%#a-f@|mOEQ!F6YyZsi~M{_uHtH6iF>D!X~HF`|GR3EMV@J z&}Ti~<$96JrkiSzfWga}?}{-ui=eXo`<9Px>9^XZ## z=S0rjH%$)52WFIa2m2WGB;KC<9z4aQreROlITjR`G_Cs*LBG9r2){KP9uYTwo_-)w!Q1 zWkJDwrDm7Bxb4$p473>c`D*?rIw@%&-E;NQq%B~+Rv$~F)~c_kM`8fAr_kkg*{vs} zf8^22>G#Q9-RZ0|%v^Z`HonYozMidyFFnz%1~}wwdnmqVWT$thM5D}{i;azKlIgSc z056N_5;i?O{RW>}S7qEeb5jAFS8J=vw>FEUCL2e`*Qt!9S1D~zs7shFyT$3*XEIhT zH-Qrgo};!`F~w#5)u)oedcNIT2F#ORNJxm*ImyNB7=LNN@>FLXU&f|QHW6?#dkSNt z)ATX671-0IYeA%o;s^KKoYOZ$86Te13JXmwRvW6?KO-X}7eT+BXiyY08heDTzjIo> z+$BhLW`8+*c|-HnVEN%%3Ar%XGwwIr$TOdqIqSKYlxK0;YO zz74%a2Ir19#mY1+=1P6*Hj(L30*CRR7!ZF{8VOfQBwvH07be7!)h+>t`pVb z%#5GZb+EByZF_3Nb-}(wrhjtbKzWjJ`M^UBfEaACl6aXDN<(4jg03z_d%iWRDKkJ? zMOQF+z?ZB%z@)+uC@3gzfp07O`_s-~uiKj^NI7jD(^+{`lnF#&J^V7_mXqVfG&KP^ zO4K3;af)`mWR5L@rD|JxU?4OuEDAL{A0ksNB+l_25|`2t#it~`Nt2R znV1l0$3{mfF4B!?RjXBVXaFw$wgTW6lSTIz;PjcJ0rS^igMd`j8Lrus$Zh#RRGN^I zGW2sm(PVaC>p+BMrz7C8!W!%a5^a5fPHS=;i;#12VwKjYFxP?tUzqVc&~ak4Ay%Xe?VIgOpbS9VUTU!aIa@Lm zmDBe{S`uB)Z|=?vGvOhfJCpbm7bo?sR!8655%A_61>UX4y{m+=XWyc%~#gW zxp@UuF7tNKJgh#LBgqO?qK@g_JEjT>iu0}ZSdL~h4=kwept)9kN-eGQqlK1$rKNAc zwa!)8V_hHm=~wI}w*`L5f`jGHfN_^E)DzLdz5m$I@U|>~j10eH-R5kve-<{vLfFNC zbiwgJN=61LC@ARe5i8HkhGErmCDb(8Vx=+;#_fvu6Hizd92`EM?RPXvS=1Q@K`}|; zEmk|l7m}=y5CnQ;ci)p1x66q>BCPt6?ryyb2EDtGpHMJZ^(CtOAj}ZIUim0mZ5&x3 zuy49O(jC`_oNKh?TD4mF4*WV#B0g84Czw+mn1fHmuTPv_Klt574cjUi4GovK>wTqR z#r!u8yDh2;M#hBYTGJR43hAW5r3l_^lL?a8Pm2D({82p4w^dY&F##s%?dcKu_u0{Z ztPV02X=!vsXfBzxs+(e@3s17&`RuyjP;0T=+bf+C2sU8JH`NN2YOsTXdCRDOgP+W7 z6*^-^-e{|TbF|nus@Y^Zlid&=8~8;x%@?Ffi|NnHl4!~0gsIBwGL8lSgmQP8-bQTU zos0WavznrwMxPEgG;qE3PL}g^-h2SiLS_zY<`rTp#5FH*7b%q%laiCzrTmp;fEJyO z#!Z$4@&1%il4Scr3ksjO$VbUzQNF{42XrCIYgF-n)|CI)@+v#~r6a+n&4mNvxbIN@ zRc-&MmDjTT&nkM|<(})!E8?f*h$-@Ae;}7kpeUDkk9_48dCcWxVgRHS90_>K3>+Lu z;kPS86FGe@_14;gLgvx2vE56qmqB5cL)}4WCPY{TD44);b2H_w!*|Zsp*B=#cN>f| zvZN3HEUi{ip3}rnu{Sab1@H>l*?k7lBjL#`pSi`-Y9>z_4oTe7BvWy$hM+eyG@c-`QD@Y+_s$jQAY8p#-&rjD_#nctgkKxlG49ay#6 z`d#+f_~e^EGLh(0@b=uX*HtqZ;`8Uvpu1b|7wMUzuWIFMr1`QL{xfEIDyISc!^6|^ z=qL?}Z|pX<#DV>OY5x9WXkCVh`aLBDkMHG9|E2Pyz}NZ$akPbMtC41oDr%Kd{7s5b z7-DjAzoaUo%gJ)x>WGjWtL4UK9yexj@gR@KW9R!@`34EYY&^DnM=8Xd6_>Q`Zege6 zg_0a961xJZtucUcNI!o5>bdo7R z`KEdms&_U=s-2yJ2*oPd!a+l)^+P?H&YWqS!6YQkgNWULdO{*tsB$?+^}1URcvH8% zwRLur$Oz0=wb}eZ<>K!4c7@>(W)UL}wmULmy?%Ho`B?Ada6Bmj@L9tcy`LPOrrq9s4@CdS=|}#rkn=zA z;cqwk_m;mGUeEWx(B@wWDK{Nk<9h4!~KND@;pE(LCH9|LDo43j&}i zAu2k$vt2+|q0vBG%f*SRwbct>=1aR-1r^~d*Ty|xT?znYf_#_3i=bz$%LsBsY<6dSr zr_Vn$i3lsW0e>*u6k?y`7+oMWfAnU zNH~KH_PY+i@F!P3uiT1;VbanhW<}$&@5O))W4oUcA3{alQL@_lW6nF29(<#VV;*PnT z_f3KVm-ZnbOt2RH$9RKw3k77$0Rh74^o$i#Al=6-4QjnJBW-!$mU6g^ueQJw6YN9* z>}$p1F(4@b)xoBhOtI*ELPm4=MjDrm<(uCmQ>h6B{*R(K2F1z1UlJKUVH9AtO=fW16nhtB%zjto?CoK+AN>Ys^cq1S+iy0J@$oW% zlxIW~5|a|%l0ga_*^vOKBB!reNW$zRAjOoB;dGbWPZb)Ks3j6U_Sg#rFzElm-}$5( z`1>~v#LG)8wIT(W_vCoaHzI+SywsBR)cdg(Ys(4?L%#bNxOARPk^}O@1fruQ;#Ye9f8gu?K#aeC z^Y_AkY4Fz-e~Izeg@!K3O5n*NbUm`g6(?+ ztyQ#bpNj~;1bwqI$cc?bhemRXo+OvN=&TYtzrNnI5qzT@@-}3l>PN}|6|5f!{V3fs17C_S4dEZ(&fM-4L|0@3c5_QEU0ioocYTc!7 zarQJBEjL3lP4^{jo&0i>0R>z(^Nxng-GPx2!_F=0>O%+m>ulW1wXWy6I&Uz>ZO^(* zxy$}%Xzs}j&KfgD?+!t!so}O|X6blZZ5fLI8LZnpM_L*c&umh9k_+cyeu=n`K{ICC zF*W9eTA!d&Mw|vXvslb89{N%4?(WK6hm?DzQ-$T?J^~1#Gg6RYyK|%_5l;ot?yOP! z9uqgXAOPkx{Mn}_qhxcxLslW%#WsI5aUe#>zw&7Ft&6Lx<^{X9M-7S(Yl%9_+Ub~m zm%r`7v?*{!`fB=b^XB2k84IZA#&CRd$+%1*7>DqUwG}%{J=&tUZn)>1Y?f`9#sQu#Z?#WR> zQISzPhO@>T1s`45Ko~0Sqw;hV)~f`3Gfr3gF2fUbOz}s$&g#pv!_fmhg=|W?_rqRD z8SCWlu`XdYYw@94TfjPe;Nrq-T9$EH=JaT=CCxVljw(}GNjIKrONxpbzGlPjV!CDi zQ;d~_yAtJ?(~*LbGN8M=Tk>Xo_ea2;7Z|xZ#1hhH#E2BAo(zESot$pUn6hxEk&$$^?KdAQWJNTav?on6M#BRv#Ps zH4`zi-|mmf>F(`*THoZrNBUFxnCj*EIR2DQaX%zIwKXGeU1>M-F&kGD@DTpG@8#PF zQLYaecb+ReuFgqbk>nJ%|Afa~4TVV7Ww{aklfuvGYUUmKZ-GrsTpa=exdjFK$rOtD z(gj~bFjY&G0ZV*YcYAS_`!!@IG=n*b#EAnLew!!#Gkv z7KB+CR5e7WMtANpo<>F|2Nx7j&Ik!&->x*p(tQn{%#%1@8vihy$P(a+fVpvSAmP)- zXE+!;&=%p&<+Qd*E*WHw7t++^{&LarBfZ_Ku8PD91Fb-+r*AQ3XCxVQku#s4AIO-5 z!VYGrI z02Qcn&ElTP?VHdCZL6NQd)AF@2o5{ZCC zS8g_&DJe;duV-6nRJ5 z*69hrMlM4F>J0?l%VKTM{=pZx7P&g7<0nHvi@lBvB=?Z-)vKVdySiMrDkx2si^y*s zTiN)?;NZk;*zud0FIcp^uCJdSf!4wYMn-ut1whTfemU3cIXgRBYmeYtnNF*ixA3@I z;qqv5MF5JjU=b4eVlF3Q90-^a6M-m06wx~>a_xJ;Nbp;zy)VImPd!$9xUX0uos*;X zyk7v^#k(%YG#N^ea{_$?U~x6-tjF3u(bGo&(p5gsZu`mbUnsTN*D5x4vV6Cr54Sg8>I3lLfbAU%Hv(om37 zQ(CyK?Qkj+*6$e!paX!9g`b<3H&rWbj@UK+uPJ|nC96M@#28k{WK`*J4?mj969Nc8 zzb2aT=hjlt)#>H?vT(N;@}c<4Ewl)xv#1xK!^5Qi$0Ax$;g>?gXZ=;zl!KWf2!PFp z{{u*N_;%I=WC3_pLum^RQq14jJeIyRk`A&Y$N|vesptO+E3%syz-uc1zrYFrNn1CF zU#zU?fSh#q_;zI$aHID?TJhux6O%8Kqd)ujnkzblC?gU+&_3Rrw%rhvt5Ru~;*$qs zjcNaBmew#DODo6$dW3lP4HNICrkM7?bNcvvUf;bPj|FGebO52E*7`Yp#q*KzpeBmh za&jyA&F7sFc}`T|?V4De{-4x}U)b$p3(+VUGQIguf~=(aZfvE}*wfvvJ6$cOO@NS< zjw^>9up-wacol|+tf?}TfXEzs-0a1w2Q!{VkTW;)X02ZXz{mMleDMA+IB`2JsJ5Dk z{ul>|u(Sh^517~Ui@3Dm=4^_UOP|~IQAhOKOSMWJUio);2VVg5W@NR8{^#E)A$om~ z(9$BY%@0V3Hhf->E-uWqQ(2un2~I&E*))ZIEq8xgKMX|3F3@H$4UpLJeJ1V+!RP`s z+Vi7#{n0TDG9d{KO$rd5K^!OfaWlLrKQ}kG$$T-+?^&3Q7Lqf(zj`xMgY%iRC-j_Uo+dZUU!byU5At7q?!mn*V?Q zt(4_jm4D^6=GB5GDV!VGXbN$Db)|E4SZ24iC(mlV48#o?8y{Y~0!=_mTcOlKEvy(I z!GboJ|B-(D-M{~P0sf2bmQ5milX6Q0f48E|vx zqdxe2PEtTO1NaKP+#OxtU(f1zAJvHy2?>J~nHrmm(hw9K6U}b32GUwtsc&d7|JnP5P z)l>v~TE6JMdVxJAL0=y*m z-}CVAH2UwL=pS4DmNWklI{(<^?=62Xys9K;y4TxYsQd4{Ym5FI%x;*{^Fssl2YA^K OBrYN&Tq>yZ{eJ-;pA)(O literal 0 HcmV?d00001 diff --git a/image/menu_structure.png b/image/menu_structure.png new file mode 100644 index 0000000000000000000000000000000000000000..1442abdfff2f1e3c7b7a1df9305b75259eeaf7da GIT binary patch literal 25493 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 literal 0 HcmV?d00001 diff --git a/image/open.png b/image/open.png new file mode 100644 index 0000000000000000000000000000000000000000..8f6eccd4a93e838709b7e492a2b5f340cdeb9d3a GIT binary patch literal 45838 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 literal 0 HcmV?d00001 diff --git a/image/refcount.png b/image/refcount.png new file mode 100644 index 0000000000000000000000000000000000000000..407740aa1447b2a2ebece394c32e60c884391828 GIT binary patch literal 13128 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 X%XatHNi7C$fn)G=^>bP0l+XkK;4J^e literal 0 HcmV?d00001 diff --git a/image/screenshot_gtk_notebook.png b/image/screenshot_gtk_notebook.png new file mode 100644 index 0000000000000000000000000000000000000000..b61771ffda3363b09418f86886ef2299e8265a4a GIT binary patch literal 53033 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 U&MTR8rcg|_nx;HF;mZyG1)v|$4FCWD literal 0 HcmV?d00001 diff --git a/image/screenshot_lb1.png b/image/screenshot_lb1.png new file mode 100644 index 0000000000000000000000000000000000000000..7452b9436ece148804839bfa4ae152786fcbed1c GIT binary patch literal 3949 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 UmgVvlSj94Uy85}Sb4q9e0D8*WbZ;vznZhjsf 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 D%FZ81 literal 0 HcmV?d00001 diff --git a/image/screenshot_pr4.png b/image/screenshot_pr4.png new file mode 100644 index 0000000000000000000000000000000000000000..281ae5bd51edb712d397d27f1591b4660e02f1fe GIT binary patch literal 3265 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

H?5 zy3VCKX=czReNM3GvT*9J!Ge|$32_t!j*{}w>9eEua(5Yj(- zgPa~gWk^YCFD>m!Bkxg@|2w~;_G?C8tGRfd#JhoSA*h-|O(vF1WTVyJoHEsJkyKI4 z+?4NkBu#-=*8k|!b;XZU?p$%_V=0qQ9!xQ5IY_GC<%sZG4&KA~37O}&{{?n$JS5KB z;gOxNTUKwwzvDXFR@RNoioM`W076f&h*+=R7_QUv$H`mbm_T%x|_A9yT7^ z>AO22(Ga3NPDA+}l5f5ZFhf0S@ygz(q@Phg?fXXmp87PEwU6vfF$p*uYDt7bFb*kGTDMeUO1g- zP*PGq)STKN&>^)JSzwmc+-7lB9}DXa$0Di1JyK^cW*Dj+hNEmrn1s-Ph}5}QqtzkD zjHB9at=W6b#aYhi|95ba`6{qb<_aZZBzggoqI?oKt)e2Z*l~Qkat|U`US9xRGIE6H zJh1O|=xj17XqQjI!yjb=*f#DpqgTFdWL(i@_Xlv;2v$Zz%7OviC(+^!ezRT=O11}X zS=~fPj(!=S!)YFiTayZ|=j{&gv$!7gUZSJpf=~Y*RxI7R6y^_RwY$8MvfIj8*{Rsa z1dJg#$&5+Qp5*ONhH2&E4+4+w9pXPSb-+v^0?{+Y7nfPD*U$N`CW+ECLrKm`U{TfG!I7dRf^RZ~B@D5KX zxRxPCw{Si-GpZ5wcsP*e$y28W6Ep4&3~jhM_ard;5hfL|jXv(Kea2}MKs1nLuGV-f zrq@by^ULghcL@g^t*A(m6DT+$fN=$mkg)5q1~5K_XQ*N96CYL_#K5RNL``ieFvmoh z&|m#?sUzzt8ek-YfEl|3ms7RCi(j^C)hI$q0~uQ9F|m<+B9}8cz48t>d7!u`u(7$8 z;tZXxK!9N`Dl*R%_d#t{7oI~#ZtoAD#(&<iHB+BrSN>o8>36@W a#d7Znoh?=mI3dL!o!JYtB4@7s^Zx=ms=$N* literal 0 HcmV?d00001 diff --git a/image/screenshot_tfv1.png b/image/screenshot_tfv1.png new file mode 100644 index 0000000000000000000000000000000000000000..73fed0797ad520930709a0ae5ddf5c61846176ae GIT binary patch literal 22128 zcma%j1yohrw>PLLf`TZebPLiT9ZHv=v~-Asbc2Kv(%n)bARyf!CEeX2NOy-c-#que z_rEX4`|j`#<-j?6@3rQdbN*uD_fl5;F4`kBBqXG}k`f~FNJz+O@V`FlO?bsR#hn}e zx?v+EsfY^yxuCxBg|8plimKWwSiH4$(6u%|GBmd^GhndMw>B^^w=uG?-M(HY06)ZL ztf*=$Y;B-xYiwaos%UIx052jTu`;tVFIJW?KV3@jWn)>2Nhf9DT8i^vWnJ|B#KN(h z5iUe*z=(uIiXJ(ou^+SuN{T4`iq8N6_DZH%Og3K1f6(42=$$l87I)uCf} zI#cC-)oa0|`Pu%@)-M^PE0kwB1`@9&v5|<~xTxP+Io3F92KWcOl9#_0(SCz`>GZD) z-F@{K`z2jepAmbXaq019h#)JY){lexA1vxC9!s8lXPBFfjm5DO7Wy$=YjaC173*#B zYvtdFr^<4R?S6|NB!-QHml|B(C$hahdC(F>ppDdK$UWmzNUZJdekCsK;aN3Z`98*- zd=73jSlAcUVQX6SS7@mC#l?lf&hOgmuT<-b0*pq#b?cIwwBb=8maE{)%g6A?jmPfP z7L8a#&KhlmO&|B^#yXOO+yWf_c7yR`w4^FO1g*&b3*FDnM zaX|C%;3;J zv8$QX-<>jK!pQhOr+~M6J-K=RLCaS|VF6LNf!23;Y)oQh2blCNKPLuyA9(h1V6+k& zC>*@sbvobN#b!s36clwSDcyZ(i!Eel?%&BtoI1MESf6O2Yx&@E@n-8&A;q`n{F#{> z5ok2?zqU$epNpa@S2~<=34G@sz9V=LSBIy-V@yb_+m#fA{6L`I40D?6`_8r}r@fpg z%`jCCKF9rdH*43q(;+iIueYVIq#uSHv6L2Ev`!XnyUZyv2ER4rb*<6Y`#QN!sP~xh zeYeD{=Y+zH=x)sWm$8+lU4^IS!YP{v_q@9^}S@BVSMYsI6KEp1dZ z@#;VRZD@m*jz&j<(x%}rKj_)6BERPS;vE}#0$$lQ z_J5@)Q*D2aOqvy4xDoM2tUsm-i`g0Di+t+N@ApVZn&mXJg3cUUd5Pwlf%LX}Y?6a$bw$^WcAYVO1b6?laj%WEd@2dyTIU%*MS?I0=kj&9}U|kLE<8x;|&=Y=IadqZIIR4}Q69=uI zMAv=~BK^|B4{Dv{6p!%n_?4+wcdYEFucFF!@c?}aD_vt+f88=?9uD#tDX$Kg)1u@2dR$(g4+#gncl~R0XrjosF|<)8$9kG zbGqEPPE+=5@aOVw!>3MWI)aq>59Yr4DEQkmLT(?4-M+oAFy6CI;u?9FYD;p%ND9U2bDDi}R-ZbMzTZ`thb`Q48@xq~ zRPGX@Q3laix2EWrD~G%7GzYh3h=%Y@e)tEjriLAjGYq{aC(72^`VgDplQLgs%w<~X zHyPo)e605Sq+5Kax|?>Xz~|nY=M{s5{o~Yl3bE7= zCnHuH{4O}@NN(Jg_qgXLQX{nQeCCv&+c7vRMitYi{aMbrRN)s--I{D1ZBcQ} zw>NT05k+YYaE5|XmG{tN_qr%{>Kuqkm}Y`){-m<3EN1jiT( z{AK-ZzE6qm_xyDdBt;jLIQ5V@m3RxmuJYcw?+=msue4W`p6R}~xL)@lMgA3*L%Gt; zOZHRJ{Gp5~J4!fHC~)mO+Hoc+r*wgewQu?BNQi|X6v$M#A{*L6mYH$&51Krpkh4QK z({lWN?&0O~raRFye0ip+;O(#7j&;1<`D4r-g)N+O)d_Tl;hRQzZ*}&2NM7pP94cK; zv2RbVFu(cI1@n&-YM)PvqzJ>~%lCL_QD_GjP8xKpLH4D*Uo4~^%evb?ICMS~c^7p} z(efdl`y8HswWNWXC7%^%A_eNt{%cQ9Codl>&tBJTy#(0-Fw!(;!OZ^K3O9hwS5PTd6IObUvaHbq-No5ldJ3rQ2 z+1hUHbf5X~qUzJv!_ZHTwk;f#FX%r`^x~Od&sK$S%&+k8s+F1Nq_Om|5c`>m_uQmLN&Zwk(B<5mZg-$Pvfby^>>69Zf#Fh239P1UI13F_rfP&;6%F4|+$I4(vtsk#5ho!7Hw zyV~paJEn$<_(DsrhN;Jg^{0GQW+FFmDa7-0t5SrM;vFvEUMyikW2dHM!uW5L!-6O5@g~ zhG0FSS;8z}(+*(T%3?{gXW=<{*!jyfMrF+tUf6wAi_2O0B?NJWBuXg8Ps~>e_dXFr z#`Cyz=k(zl^i;2^*$qH}xP%JdiZ)xn9XVA>6pDSUY5!NZg1z&1X^*=0_m5=A|NN^o z&nluFdo;nvCP*Pe+C&s}+TZB+5nUS{N>`om52y8Ln)%;wbFz1RoSt`FY`gR0-$Z=- z`x7*jNrCC}C%nOw(M;OGW|L(~w)n$I?GZHkzkb+ZXmiGQtCkpH9c@l7H)rw*zaUXK za%C9#qo=r7SdW(`<=by0lC7M}tlQw_kC9FY|7;l5cGv9JReW#1JsmVPrQwqwFGF2@ zaWvW1-oC4+n3VD@g!Zf!cl|xf_r0;uYSLdd@A25)cKvL`6ugrt>k}G!k8ii>0hiNW z8qHkx5#K?du;YF=XD8qC{JiJ47x7=+E>3ZiYUfuJCeCVxjRM^&MiqF@?er{75N-pi4AQ*gqLcSE0`Wt~_q%yW(#Q z40KxpAL29XAc+Oyf6U3Dx80s5(r*nG)zTtH(m6lg^$iaGq?PZZl`pQRM;=TfXwK02 zhE;dE+R4|~_k(PPu%aS%FwuKbZ1zV%vGAc^Q&VTx*8>(7-X!qYNikEO)h*cA*rbfE zhebu9AjLB4Ui-{ph6azSR%(*+{?FEkv#EX@n<2)drzSVxRaj{XHn!p}7QM|vgT;<0 zRCIJtwOp|p=R;<@HN{vNY9FT;FJ5>HrF;-d`8krSuFD#CkAx&dMccJh=Hk_>S0ktJ znL$xcRLE&*Zk;ugv%{@<4-Cj7J+rc6X=rFDFdb)IXIUT37uV4tHJ_>7EMf9R%~r`5 zd-H~J$mD55V`HJ!yjZ=4?_pNtZawSt1}z<(kckPMkgzafDU$f#&qYV@YA*)jIh4LK zAwlkGjf`|r8alQ-a-%-H_(@z?NoHrNcq<$Y4ejyc$G)%~!a^>G!zyX=Sw@YY?uv+D zZ`qdd=y|I;NyaO5_!eTEoQ#Ky7~tM zq{0b{$-093%xLt%9E5w22_oS922VFQ*Br3gmm++y*U1zimHxF?@M_9AIFhfZ$-pmF zJcRh5ohG?&y5@bB&2o>y9;vdSh6W)#We5flkH{?y!Y^>TjiuuCKzIDapUG z8TN$2C)HhST8!w61rtjCs&b%-XkRE{vbMIC$Q~X@;I>&gSRE{}m=WM{zpT~~XgXEw zIM#V+QCL{WZqR{EPR<(N&HlCvAMMVaG|>RuS7Kr}yJJ~A51jeC6M0pbwYcY-HO(R? z#P#(3skE)v?MMIG+h~=^THMpR;z}|@Q^gxd;Zr|IHEUhsAY^jY%Vi51&i-siBqx)+ z_{{F-n>j_WmZgv(k=oxk+vu|jk^P1l|Hgypm>6+nWMqg_>UA5zt8+HvQniUH2aC%2 z*SM6ETxjU%S#Uq>ren+#f5z^N(Gj4_C1^3thlYXiZEjBQT@}QtaZdub2qiz9k=xC?hojo+`#7h2 zFE-0(B=ScGgNb;3eT{bKn&H+Sv$BRuNlCRCvCGTI1U|(q8~Y>r_ARwB`y(FbgG?iV zgeZz3M)7%1yXx^;TFpAQ#PjoWquB=Ukx^+WsmJ8x4XYlM2GteCLGov9i%l=)Y-&NbSjTdKsI-9=A zXN4vt1VT_Sm$oKpR@tXOwnN3h5QC#;b+TuGje}E3Sj7M_)mroZkLA^+>$|R$l$5sK z-dn#<_|yuzJ*Rlm6Yy|xKXI5%kWx@w7xC)ql97pJM&`7bZgQA$^??vPKNyr-8O*>$ zT6PVKjP%<2Rh4Skn{>P^cx6oVKuBU!L401g$Fa(K5e*hGG?MZvM5b_eu7^WvlfrOO zs#`@g5Yuqm(0b1#U~I~=bu3ecnMq=Hc6R5_9|y;~bLS`fk0HerzwN%Et&&ANC8*00 z-|1puhKW_*+IkCee@nVxn-ByCd7*^>56p7=lR-;L$r&0 zBqSsUo0E8uCq&%b1R%4pIPU1cdB=VD@FADu4(THfQ(s8A0Y~1-+0AfL3-wzu&QI6# z9T&pHcUlN6A_L@1lCK4~`Vi8)&Pu)3n{Q4uiyROa8Vjb)Qfz{gqeV`We`LTLPq2kg z5OsU0YQtpsyEjd;%l+-TD*-LXS#MU)b|ZGZk(}4e_;*%D^OKEU_xJbrnUr!_FQD?+ zu8mKM?{3y;X;Vi-CUQAhj4}H4T{kp80SU&}AOz5mQPnMb(8vADWj zwdZ7`xHmL5_Hnir%hb5ohnkS4P&UCDeu0FVl}~_racN)VUG88_jF>dq7hFrN_(5%QyM~Az@$`g*Z6_!(9iP(Y>occCFvL3^9;3$3a4PAvv|C8` z9z3{C-jMUUnAvvaWu_wCdZLI>iODb;qAE?4TVRq4Nl2jHzki={^qrigWx*idXBp}e z^Iwnr{QOjl-`-Ww(7UdcBP*W#BP|J!h$!gz*fA|5Lw~Nx?`4+a%1oW$H<`F=uuCZD zxJdW514!JCk$o^p#GvnbDKGEwSG;!%nI!W-+8NGLxb^z=>k2qx(2}s&Z>V-9^5P-& zRoWO%RXJb+y%vGvd2h><;^(xuURzx9G%-ofbg$~3$;{}{l>-OootvJmtzrh0?bcRn z(3Bh`U!D7We)>*KEjM~?C`%YpNd~NCRHd(hdkU+dV6rVw;^9_!c=&zzA>60tQ?ZJ4 zIK$a0AsiOdrmhSO3_+jSjfLo<{5?E8j374Nu*P+0(m$c6PqUhDd1YzIOdBPINXF1N z{ji+%cp6+$!R7DoPhP6_fQ7EVA(^EZu9ctR>x=5Vo?G5QBrakL`3w>ad61ZJeSLii^fBM!A3-HRJjLGLUXEEo zo$4BW2xQEmG|30fo28?%^Lp)`sx!BL4gIuE;(wx&M+tWTsf&u7JfdBsy}dm$HdZ1% zJzd7t>R{!S$w^m_5cR@d9$m_3v4W`=MQLPOOlE$XNCNO zgQ=sWMBUunut`Yds_ZxK2deZqS{V}fjh#v4XhgfT=T2(QH;$jhscLPWOqxBmt@fF86oL#btAKcq{?I2U)&-R;H8C?ZukRUTY?PiX9D_q?O4t0}+k za;=+=NIs6r5jSBmo3&*-D3(sY>fJT#bc?5&wXI<{_dSNvrSY=;e_o~xu3BzRJe6x% zwb#`UmD-si<312Ohvv57%X811E4=mV7EOu|7rYbp9Hmy;M8lqsJC@gUTusM|ynTt!rJRm7#)k@Yh1c^dFo}2+sq>&^f%<<3x)L;0)Gtt_ z(Y8M6^g@<``s8oRL$qqkv(}e#-N4XLUE45gG6`ydypGP7L%aoC=mN7WW@@n?J(A)y zpSsr_^YUD8*Z(ktpa1<)+Q;j+)ULKOF-`Y%2_nW#zbR!azjoKv%Gcu0X6hs!8S|Q8 zu;1!rs*{1lpEhiQXhwfP9LUm=Dt}TnPYlv7aGwQxRM6Mdqb^QEatWbg1W9lm@8=`*hT?NUM&D={C-)?(Sp72jP-fK3G`o zVT3##F{zv03C&ML2_-12NpBy1L^+F{qWx*3c&oFLK3q&?(YB{0UzM1TiYAhmb3tNe z0gb46kC9`E-mXGjYqi61r>P=lQr5wrN;5?Wmr|YZcCEaE!s@tTa{AbqYWAxz(LQR* zz=$WK#Z881F3+DMLm3Nzhc|E?bfBix&zh{2;SLv0ak<^hgqzQ=H}{Nu7DZBGV)-$( z1KJMZaJ_Y2Y}zZ?hh>#G1a&=oziGKsp4bQnAG`?e>nBdB4hZ5-;hAE{kL3AlDM|*1 z?JFLPptR>Yj2HT5Ldo`IP%qON{PqHX-E~rJY8sV1nx+7zT2#+^M0F`BUI#Uv(}fTyH;NqlCXbQTIbaut}ox@_3u}2j2Pgw2$Xbad!qRebNbPr z=}1Or^l}D?9P;l_%2NO`L(hPh<41AxdAvp#(US=37edO)xJ5-pmcM@@*K6KMlN#OV zG#x8QdDEWqvR1V)XjJJHK4}dmAFTSJhPq^Gwlz=T?m9gtz5WcxTa_k65`ZPlsp5f>&PG zUG4!+ZhcRx?WB9E{)^{>a)NeFd5-GmkG(QF|J*QF4^2a@B_}7}ne`$03iww-POcSB zxCn|_u$R?Vb@rsimGZP3o+g?595eXk1#q z5_e*(&JN%)+t^!j?YA|t5yNcVA-7iIeeZx`{T}DtIc^k9we>BhUfo zj0*)_iZz55#b|Ltt949bRkN}3cshwYb|6Z3#KCe}3f+KKwtgn?HpZQ%sv=N!Ff^=8} z6D@l?tBBi`ZlJ2f<-}TY;;vS{4PAsyU}G4XN~{W!Qv0exl-^>+O$SUXx<_sb!YD7J z5(JcJm4Txw)xGp$cRnye^hZ!pkv>2Q_VV`D9WOE%(I3gz4gpSLJ^v%1ia?-+Rt}vh zsj26Vcjrg+Ur;|->WcFe3wi{QCk3*1TUS>}t*nS@jq_9J15%W;v51L-VU^XiIsYpw zQ_nw_*1~{`ha?lvaToAy->NO@ojXkckJR&~C(A8T0TDq@tzG#-2`&TmHdo!xw{$pq zcfOT^jtm2qGlY6(2Rt~TL+9U;yHp`TwPa#IH$h=!!=Q$dp&E|B%7nYmLFE2 z=tN6QNd zUAy~`RYd+=-iBP6sZ&*lh-u3-e@xY?+(ssE(xACfAv)=l1-4w*_w(a5-o+@}*#yn`&oTln5#ptxL2Dme#nYYNL*<{@y zpU)XKpcP#>C%YW`L_eZ2%s*|i_7=b%ZMPHAzUDpPY}8?`$9|~MqgJZX%Z5Sx&8Ej_ z6`99dtg{tz`OqT*cigJDWib$!K@EYBRr0l(3v?TG*dN99*bFJF6xw|)c{hr&ySt0Q zuVg(}M#IW_Un>1Rz_X$rCPu~F9gar|h>t*J_3{g%KKA7W=;h&SjZycOx9 zzDOGajf&`o9|e7am$Lx5Ei!(Q4oaq?p+{UNOO{?`@(G9X)Fz>ga&o9}KqJ<*DW9e+ zdW~vFEVGG{=gP{_N*Ud=mL?d8mzm2fW-tH*!BtQpfyHuK5JT?I8I^>@C5{Tz_!Jt} zEaZu?A_H`wgKi263Z|u{>2!a73TGXMh#0i&rhlb5x+$Lp$*#9-uv1>JkxnH^pI2<> zhVE29^_fCW-hS#sS4kT84})#QKRmpuIPN0z^kYY~O(D1Kat{&TpD7yv;()*LS@gVO zD9%ZubZezI>pDhelu+8y2LMd6=(pVAJKt$UB%9l}>mSJRy&@}O3ue~SBH#|D*y=bT zv9^9STrCekQw%CIhw0b{3h`hB`;0>*?@eBM^k z`dzK3?syIzk>>&9X0E)XLyxLke1{NQJ#?0m zl%y^1-1~36b|xUVPnaaKR#sL9Zs$BUOEM;71!Pf?kz5xnDnMX9HR}7|;pwSq(wO-w zHPfIo`VIRd-~^#%MDTK}1L;r@a@7$`AoPw*YI&;Wjg5`BKO7dqkFxHfUW_T3$3Y2U ze}7~OADnXNlj4IxWF4y@enHuUXvSGt2OcTpYt(@Hpk4`nvu#v&!Di2OdZI9j*@=s1kSxDPnAbl3^?MAhrcV0 zklY+aAY9Y2m*2XBm#T&?BL-)vBmAaa_Fwo11|pE7-P%wJK-yEFe^4ehqdrs}K7jOv zjg2h==L9QfCp*8EJW9%7Q-{S6BfGcFlw&ZKMgK7~b11~42=Gbl5IBG?4Q^&q_;j6Z z*U7=2xScHGy>kN4^c6%8HFiHeSsFR+xTX%A&fL(^7F-A@aRaGCWWUOwjeVwJo2L6A zV+7x(G`QZyCnQL>#}^l=E{D2qi3j5An#}{tR}-$yU04)MiyIS}dcs(G#kYx-ZBpU- z{D;d4D^v-!a`QwT??2l!G;odp!{5i^c36_wefS?a&1JyY2u^brsq`1!66E}a?QJo%`Lmo%|Tnh)`16 zcBl7*+;2eP=*v~-+?c9-AmWvfKnP3zyI-8-P>mpsD{jH@o$0(a9zEjHl6C~+%jm zzb7YAkFq1DB@@fZP-A5*o$4&>xQ`7dDd~HGeJ2$KUOuvWf zzyvq>hRD=9Y~beaj}gYuZF$I2r^_4Lu}U(ipo(h|sNAC)9J%#ooP9VBQz9o>!~1Cx zG-(J%wniXsdT2^@O7l-90>Pw&~^f@kYlZ2Lcd+5M@V)we(*UTTrB;V^=$6 zsRo%>HAh}G7WWecf6TTBbBYhYDo9Dn zoNtxL28WxtaLqRjg_es8U)yCD1sGo+U={U&A;?t9#^teF^McAMY2m!T+$#?J7NVhj z$o7_$nfadQEzA~Z2Rdq2dtzCxKY#vQwbq4uU|=9;R0$e+WF+VdREyr+9vB=fH0mce zVt)i(F&U&VwHC;ZJ4cfi6l7%er={drDVdq5K+Ve!kY?Y7{sEMvR_HjH-?ZIBdIlh` zFHe&@daGCZekJ#e)xdYmB2l?h|>NF$lM;U{Cp<3niWtp2r?4E zhQs-(WK}(FS5lpG0)&95JLAQM^N@w1)EUjx^6zuq>u82##W%v?u<*hZqi`C!N}KTtZ+(J0Tfvr)Y7Nxax&le%;AUPjF-u*pg3>7BYv|{`$!w zTi^FhNJC%#Mn4KHitkAN($Bw>gyW{c`prUZI8vmK%F~kjNu{GiB7jLpqGX_@M8%>f zN^1OEt=7fK+cAXhyVmdeGC`=~E%5ZHiL%RiXR(sa zoKbL}Sg6vz9I43t>T+cuJ)n`K7p=R#!?&u%0O}jFQQsHqUJF<+oFFPP)kTie2~u)feWU*eB9x(A@Kf) zo|Tmq4%E$cdlC^ZSbapq8<;c9{H=6<0qs3D)_1-&gl!oU32+m<54@QLcIzY7EX9$! z&!yZEEu3#i2$O=cn%W~!;=O=*$s zX!inklJ$LP;X&?&wsU1=W#9T?TSvz=EWZ{D=@)Uggeq?)ggig9QMFz-y>&l@`>|KC z6BS1fy>Ihcj<&b8lA@y5(2%0nr%w%|qjbX zF1-iOAwuNf=Q0)nf%LnPoD@*X`(~~#9YBSSjEXWi)GF|80)|I*%>c_sGOC^XYg(Gu zBTjP}rs^G!!%A9(Z!hcIE)c?d?djT+bt_=kzd#m=HV$B0O;){ZT6j-yFh-s(n9z>V zykHnS_cjdc=s)Yt&qo8Z=eP=wH*J&^mOj4BOGhJZwmt(5QUNIHHo(72@hA@M?9F;n zS+f) zY~v}h=Q5AYxmksz<4uzte7I!k-3+<2d-i|!dr*oZ(MC@iCOLgNJ=#0dV_c^ zNY~1fn$}=weC^H^K_nHGj2ucuf!#pl`h>;}{izdi0co^45Q@Kl>y&eq)3-$#`#002 zYinXr*sl(t0MaxdHa0dM8BH%~C%-D*v{A7#sO4&0tlBV5SF;w;vrd0kcBp)VmX?W8dCDwfp25p)*C8Ib+54*eE6fGok}KL}OVk9;y{i<>>Sq`%$t@tOs;xhvnJ(%~*^K63xxcpl4C^3!eng#1BCz5)aTLID?i;B^e91(K-T_4fGX{(OX87Igz8 zDNubdAZfvT^k*THw~`t>+{y-jr%tAyg?#8-n$9|@7uil>4fvbChv(MIs} z5H{15YMU8&;*3*w7M8i12aHu)4$W9E2e47j9J%h!i9*AdQc!RYSn_A)=8S+3kbV|l z;{Z(U+o&2`X*GWnsJNXm{gBy2hiR)vA!4b|lLcH0fQAtf5h3N~9zUHZ?iC1t&IrgO zT>u(gW^dY)V_kX&@AHWl3A3EUrB-N0VO`t8YL$#CS6X%={iKMTrfLqD2jsPDh=)ab zBh5xcChELOubg$!K~504mqbzi0;qg^Zfi98mNq4+u9`L>7o!i0XezHwDUT{`uY(bN%_AN zHD8J2Ys}I$2rTw)gx;j@3o=L}QW6qhz`7&Z3bJh?BJ<3*1nK{H=>X*O-tI0!a;fRs zhYcPoF;*}cNb@@+FHJpKUS5V|S3I3X5nb0A!=wPk0?ZW%ECHA=DnL5tj^S>>K`W?F zQUD7P0@HfpEAYppgF+Z4l}=uxB?py`&So?^wE|(e_-_j2i1ll8lL9`Pkt+m-HJ{>w z&xRIP5*8^kAwdR6rF%g$(Q5*jP1Xz?H#d8+I?Y0e`7@!&0XWTq9EuP$^J|Vi>+l8N zi&xQ`@A6R1={X(luh6KlBoh@E2lo!Npo0D(AsG;RSYbQwWg$Np|Ni-LaiRhNTtN~j zYq#D2wKx+*P;fhCLiCn6?Y||r7GU!AI#cg(A=9hN`nY}69Tph65!z^VOXKrv{#g%! z;7KcL-UZ7kuiA@`=d(s;?MPhWL8r>ppw(^+>pKd zfl2IXj8yTYgTYRm;wOAAgE&4XR@nUIovWzZ4#)m<@%x#q%achRT<+QOmvq;=(8Du` z*rVzVqrv#fBgy2`}_CE=JZT_Md=QVvc%sWuwBae*X)#Gr#I*9BgjO#41> z`_*WjO2Owmn^`T_~5|<&$|R1 zI*5kPh#jBx4eHi(4LXt|=+Om`y{dOx2!P@Cs@M4mGN~m{PDnqOlih=XBlsO5Cr}St zn4(D6nXny%59q@a`Yadlwj2Ygk5K!+?bF+CPTK*`CJn)P`49V&sETIlW4$8p{dIoNn zC(8(L#nJXm$e$T^k{Q=OMAULgfpwRM`D4X~m`QG@#^>PosgKciqpdW@ecO}Z2OwD& zcqc9(o8gptQ@{AkoXo^dt$NlY1e*k3dO^4I1x%=pYgrjN>T?BUqpu#qOHH6Z=Tvb& zzzQbj_XihNbQPN!xCCS2d?RiR@RS}{tGL|Gx!|r0>nmVuXeAOokJ_A=3R|O2-UVdr ztGu$Q`4LLl8bFSSnZvlTWcRfpTAw5`i{@udOXr0*R<{T^07c<_M3ehL0Y z;HX0TjnZOcV_Aa<(T~)-B@Uyw=vs0A3Yw<1;Gm#%=%BdH>rmvlw9^g}U!MJ%l`LXF zL{IejxeF`)9fPuxAI^t#2;*9zzRz!5P9go6Hmlm#9hU63G+mjTR?}l1b8tilis{EK z|5_B;6T75q)c8Za^9i#(qU|saHBtK&3(`O}6*SdGgWv8#tNTm@qM->o8O!~p7cPH( zIUtBzIl+rJ7wi3T@uL3uUc*v zIeoW6ALB>18}}ut+*1D6C1-=ybQH;8AMZoLN`VLHbWt77ZlcXd68q86&3*x;8sTk% ziV>EW7*y|hD;2h>t*z}R{Ief08oR}`#!z>|+LN$3$FQ|$ST^SsYvx7Xe7{}7CYQ@9 z*8Xixa63y;Iteo$Cv-o5&o^ru&g)(iR_7nPu7n)J$_SgYOsM|HhnHjj;O!mxUIKQb zdx)?ppK&9AW?dAvTHB6$6)H2U{Q{$no2OCfv9hva zeO2CFT$RXV?eb!42a$KeAaVem&VkQU1kech2EkP12~C&U_DZ-%s!J6?%DK3>c&9bW zZ88I5=O^ydN$bP6>*F86?db_T5NE_uai!K_o8~C(>#LlnA!$S{9Zt=#6t*xowIicB2YTBbtDFI>yR=|Br12`@GII>DQ`D*n|VzS79XCLTV8t zGhT!Z)OjVvrwuFzknSYX<@M%icxIG*c zx(=TvS8Bpw!?5|(AC9}^6D7u;K#$btvvc>%p4bGTO>V}Y$#4<&k~WK%x}Mp?(jmOx zU^*x@$&5Q7tvE?}j{w};Tr^A{jdTg;IpITy!PHkwJ(M!*gy%n^$gg>`}-|uw1Rgw2r zPQul3-EGFh2c!e0<(I~KFwSNos5tCBp zQ@tkC>^oh1M1_j438e{|()8ui-r<7!0#2_EzKt2*H2=i~RP>A&@t-Pfmi55)Hdbyy zLhN>|%Xc)UAD-u0a1cLMp@&t~Zk)^@Pi6E}X=wR2OIm_GQiBbl4gr(UGEc|dPQFlz z{2V`KcLRs{mb>?`e%P*hfRC>L_9IMN^U(D7)x38=!n_QZ zm68g#a{)mDmq{xSN}k@{LOaq2L^QRw?m82ImlA4jq*ESrZ${%qR7j)(0>og#BZIMk zV45Vy23_u8y&^{^@XU7%>q|q!1X8rs&hO{v^CVZ#balyUFHhfPOtylxoWQxJc4}WO z7Z(YU#KFLZ1`R{0d2XHUsyq-K^Wg2lo*HO>l@NSd0&R?Hnd!sJ{p2ehD4$3l5W@w4 z6fJ5`s3F?tnBCC9S^jp7Q=Fw>Nmcf2qm{JtxZL392jmgXBCy`hLpeiy0327Of}p43 z2K29syo|dFmPV7{alQZ%_tgwrNGeHnIey9>wcF~0Sv42Wr~oG%HNB);K=70XkAwA; z7||BMi35@<6ohXeI}vv&Vr^YCIQE^bD>*bx>PuQjr3Ux3rVxXQft9t_o1B5C>WKB< z*w|nVDJfxJU(fSjRGom5H8Xp8ac1Dk(o}vUV+r8DX?3R+=b(OHb;&q zU(wTutG4;Gu_Pt96^DF$+G^cV)~s|}?FH7MlhB>j9(zZj8;@_XI2pVU9Wa~0y*&hR zu`?jeqziQ;$zS?@nGi$em{b8YsXh=oF^S|oY5HZ?Lqva2qo_Z8Eh8fn2cr;Q(zuBF zb6&FnqeaMV-E^v9Y)o5wz9$V7>cnXRT$}eah|1ofeP$up-SDfxNa51=%wD2`+Sf%3 zl2RB`;}{MBNUxWXeeNy^a?=&x=pYhep#93DOei_Ck**n>_6}TOp;V6}=ujdl=-Kh_ zIKpvfG3+5cJ~>Ho+Fx>nMYMvhht=X)Pm|-;3MV3E^b%*y*M0Lp4}kiq0D2^3Wm}-~-h23vmNyShCpkU+9R!i>i$#$$Lkn07$NlnzMmb;0jNg7J z^A+$(&p_=5Gw54atu3=JaP3wQyZk|LLO8(@L^L#V)T&9TT+OlEHq=^9i#Wi&r#fs; zS6I$oLrf2OdEHoN$*WQ`WcXx# zhbm{relGx6KZk_|JQi-_$-PLSJALV*d&kX=`kllh@^LiT=kK zLjq#ojS#CP{QI43*=(&!G2w(hfr^;ea2;n#EUd$g@rctu+j3B542XeNCI_Ca?&635 z3oHHGH+k@)uBL_veBIbEb>1j!%>-|n?b(qTIeABWdrGgsS)gnZpXBQ5YFfXM5m5Cd zP!|VQZ4dT)1=ZbOJ_VmW;$0w<21FD5uQNfke}oytSyU~Rqro@{%KJ;0S^_tkFLcgE zfEs|jFa{~aL+}ndCT0c@tvn7}gb>+1kM`f?*N9zSUY0oS>VdO04F*vnK&(jQvTAT< z>|_D)njLs?IyySU6xu6@?#1P0^p^W@BOq;kkrO!aI@27sTE2J6rP80EN3^Iazqh3(zs z!oq74BKe6o>Mhky`;WP}V!`9;w^A>Q0wNVVq%Lyuc72$Cbi6f!BDtqxzh#LC$s4zB zr9y=rt9j4qi;7UvfEDhqb9a9oOk(IpkR|YFvIx;C10zpKRav%DT%nkDto)yil={Jq zWoA+1>6D=VDI!*mS7JJ=er~RC5ft*G%Xm`_K3E_I8x3flwKiSJ*&Gql=YzY z;z+%ErvV*-XH7=)x^0tkZ%O1_Es(dSzX^#IZc!*ic#(e}<$9WG^7ZoV%T$gEUK}W7 z-%9^`!or{|V|z581S~PTTUFb02q+I@1Rza_bVhmP28ces$wH42i8vKb>&|4D0lCu6 zMQxK+imJhdeP2b<>D5Y5VOtQ+q5>E($s9IWvPYh~SjI>zkwlyJO@xKUC})z;V*G2>c*Kw!zWrJc~q#SA9j}Xv^TY`xKAg5nLg0m0^2Fh6&TfykHTF}L^ z$&xtC1zPeq3}}i#Llc&i6byiuxg6cnB8h00)+bPP!^z31=v*GL?2d12hC%zI08JED zvNiA_+dX`IUx0}EV+Fd(m{MRAhK}O~xZVm13RsCF-Jz#Jh@apM!2qK1n{|5itD+`S zIHhd&u(7>hx`~2;q1(BJoP$Go=NQow9`DQ|dR|ccn88H?jzB%orgshxMd70XhkODq zB*rGIfKXo=&L=`<1S#XIcAZ+9L49zfZ=7M0O`CO#3WP6<7T7S@>tX z)f|0*IECkbfDFp+cFhE?%V>E#=^Dn#<*v$LhAZ5p88!VQXyo+ZjDxDMv%CAT zUMKT6DmUSu`J?;|s61eP++EAgzvj3j+yn*=3P8ywrH^0?YplXbzj9wJgg6KuJ*A`s z8|kHnMj&{X>D9}+oV&nrfCbwQ`6D{(Iuab`-KBU7wJU!aIk{Uuw_3yGuV9=b@ibC( zlHNYyLVNKah3xm3G{Q~9ZZ?4p0w!X76++HxLv=hE2{rNEj6<^P(LY=&d;MwJsMhA2% zFng?}MI2!qtPo@fnK)LI_eUGg;W=JuXlxYl_gI^dJ$*Vn(dv47fJIM3O?{Jq!}KSN z1;K|S>;_Xc@5`sGzC*hY z{LVvJO!GhuQ2^5q?s8J{ugw8?5%oG>K%;<34zkpK32-_>*-5aryLX${IqldgZO9^| zM$WIaTd#GTHxe=a4b4SlT-<6ww@@!kG|Izr7(u4O2q`RSd=&?xb1JxV5qt%f-?DNr zTZaJdd-14H1*x3PGGgjV{fJWYlvsUzedCTuS`o^bQBabYUV+;9Fi32v%zxPKaBY}% ztMDHSR7{p|M|J4>KzKNw1Mi@(FE^eZcezhOncli@3% zl3t$lx<{W#|BQyi1w*hm!4gJF{^splJ;*o8?y{gRxt*@k__*VslQoA>l)4!TP>paD z6ED-j@qx%M>J)^Lz@^^g5Gv_tQrNZ+j^>M8scAglRV|mAti>LKKBe3(8U@Q$` ziGb$C!x!O|fScw!T}d_Qh-772D3j}O+Oq$KtkdJI+Jn5RA8TMfK|C*&ql8?37P`@I zQi^a4AvAaxbmH4|;2U{*Zfr|7X`#B)4)$HHev!IY*N1 z0ab~{(X6kn$-K;Z79B^B$|{YyTcT96uMv-LP7-?yeT3gC@C6Wu#ETcrP?c}cTmbiu zs5yvVW{?SXM=+ZAXULHt9A+Tu0^aaa%e8mzAH&UZBOEz>?IM+9W^bk6jjrXgiR znB9M4Xeh1L#UPU`Km<8tgg}hmcTxE}n?F^CkSwi=?j}vjkJmM7(anAFwbao+AdNy9 z`2c4h6QZFRF(GA9P*%``Ubz|JoJ5mgoKtD}iLm!k=TwQ{|7+*mzmmSgIIhW@X==5l zY8@BtH9FD2TtzCwZY+9c78s)4+rBgc z^tfy;_XJo!Ov&VaCake)0_FpZT!_`vF`EkvPS$>BC*mG}q~0>#m%f1n3XU zQ7%BAe-2>KJ944d;qT47kf93>Wk z><9UUTHf0O30i++e5`O^GdnofCYnE_Yk^8EJK2z~AA-95Qyk76a7bwHuBK2fL@E2f z%#97&_@x(C&c($n%%7q+CFz!1@X3qP(jw(n~=93E+8@bj&A(Uq1MV z@7Lr3*4<)|5xJ%3RK=Q7X_Kxz8a^TKT z$((|=C#o37^anrmAZZK7*X)$SOg5&gPc}Nf1hN^I6eYJzS_-pKF$<=QIF$EZh87uEEYzD+g)e-cFN!54pNQiw-JP zzNdnPP5;hNC<2mrV0J@^@8vd87J67xB1mbMzzn5!we3;Jk~0-<%dX7%#lGen^%^BI zrq3?Y4q)6CIapS-W;$!#$w)Qy#}6i+Kfz@g9gk5r$T6e$=~yQ@@tW_N8?Onq>k+*i zYAR1{*)L|8=gqNRzr5*opxtNf?@MuFB3p}H`Eh40wq%styD)k30=T}Rc-dua8?$}< zX_KE^E=RDTM~>7C)E}+hQx{cX8#jHu0QMwk;Eb`itE`_4BN5Cl)qpwfduE-UUGj#S zOiEV(2`iS#WE>c!;KQ8l5Cg;f8$1Yn-J5e1y2J_*M=xg$ESFkncJ^m>N1ZocA(AH4 zk324XOCE%6uYkH-@MbK_WbQK7*5Q z5_bevYW|TxBocSiXtY+5$OT^%e^3E^C|P%jr))qNVbeHhrNMIF$BZSUBZkKhvL4`z zX2|aA(vOdY^dUmhXyXCxUL=_pO=<2k=k-rtM)bIvn0uS%61NQ0b8Zp3uR7%1dx`BZKIm4HrD<))AsBq)? z`?c7_k2~{k?k#D&7sHZ|jI_b1fmVn;t#CZI0-xIkM@1W4Wg#ebnG(jpra`u~aw)(k`@_d+3j|cCi)33o@t%P|BJh;auGmGt|c49D`EBgC=HYL1? z!7b8ML6}!TvREU26<%I^rxvNIp=kIIi~0@_QmvI*^rwt^WLP)lUM+&qvT!yueJpAF z*|TRA&@zmQt7unPjvK#T(NTURa){q1bSE#6ObsGgBQx7IB6pJ$uHETw3>t%aH84E9 zipS^wQF7(2rRQw&cr8UKJ!5p>nWu?(L2gda&+QKjDLmD&;mR-i;^!UmPeC7ZP8zCi zn%|VImTKy%=CpXFnwi#8wI!H^iCRe*JB%#rFSy{GYijcP}c4<5I!IL_^#c f@20!{<7IMQ-I(jDJm?%=jlS#V?BT?B@K5>^+z0FI literal 0 HcmV?d00001 diff --git a/image/screenshot_tfv3.png b/image/screenshot_tfv3.png new file mode 100644 index 0000000000000000000000000000000000000000..0f59844cc2a6d0dbd8694f79b3bc23e0be428382 GIT binary patch literal 27385 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 other + if other.instance_of?(Sec_file) + self.num <=> other.num + else + nil + end + end + def is_i? + self.num == self.num.floor + end + def renum n + if n.instance_of?(String) + n = n.to_i if n =~ /^\d+$/ + n = n.to_f if n =~ /^\d+\.\d+/ + end + if n.instance_of?(Integer) || n.instance_of?(Float) + old = self + new = self.gsub(/\d+(\.\d+)?(\.(src\.md|md|html|tex)$)/, "#{n}\\2") + File.rename old, new + self.replace new + @name = File.basename self + @dirname = File.dirname self + end + end +end + +class Sec_files < Array + def initialize sec_files + if sec_files.instance_of? Array + sec_files.each do |sec_file| + unless sec_file.instance_of? Sec_file + raise "#{sec_file} is not an instance of Sec_file." + end + end + super(sec_files) + else + raise "#{sec_files} is not an array." + end + end + def renum + self.sort! + tbl = [] + n = 1.0 + self.each do |sec_file| + tbl << [ sec_file.num, n, sec_file.num == n ? true : false ] + n += 1.0 + end + while any_diff?(tbl) + unless try_renum(tbl) + break + end + end + if any_diff?(tbl) + raise "Renumbering failed." + end + end + +private + def any_diff? tbl + diff = false + tbl.each do |t| + diff = true if t[2] == false + end + diff + end + def try_renum tbl + changed = false + (self.size - 1).downto 0 do |i| + if tbl[i][2] == false + n = tbl[i][1] # number to substitute + found = false + tbl.each do |t| + if t[0] == n + found = true + break + end + end + unless found # OK to replace + self[i].renum n + tbl[i][0] = n.to_f + tbl[i][2] = true + changed = true + end + end + end + changed + end +end diff --git a/lib/lib_src2md.rb b/lib/lib_src2md.rb new file mode 100755 index 0000000..2720cc0 --- /dev/null +++ b/lib/lib_src2md.rb @@ -0,0 +1,70 @@ +# lib_src2md.rb + +def src2md srcmd, md + src_buf = IO.readlines srcmd + src_dir = File.dirname srcmd + md_buf = [] + comflag = false + src_buf.each do |line| + if comflag + if line == "$$$\n" + comflag = false + else + md_buf << " $ "+line + `cd #{src_dir}; #{line.chomp}`.each_line do |l| + md_buf << l.gsub(/^/," ") + end + end + elsif line == "$$$\n" + comflag = true + elsif line =~ /^@@@\s+(\S+)\s*(.*)\s*$/ + c_file = $1 + c_functions = $2.split(" ") + if c_file =~ /^\// # absolute path + c_file_buf = IO.readlines(c_file) + else #relative path + c_file_buf = IO.readlines(src_dir+"/"+c_file) + end + if c_functions.empty? # no functions are specified + tmp_buf = c_file_buf + else + tmp_buf = [] + spc = false + c_functions.each do |c_function| + from = c_file_buf.find_index { |line| line =~ /^#{c_function} *\(/ } + if ! from + warn "ERROR!!! --- Didn't find #{func} in #{filename}. ---" + break + end + to = from + while to < c_file_buf.size do + if c_file_buf[to] == "}\n" + break + end + to += 1 + end + n = from-1 + if spc + tmp_buf << "\n" + else + spc = true + end + while n <= to do + tmp_buf << c_file_buf[n] + n += 1 + end + end + end + width = tmp_buf.size.to_s.length + n = 1 + tmp_buf.each do |l| + md_buf << sprintf(" %#{width}d %s", n, l) + n += 1 + end + else + md_buf << line + end + end + IO.write(md,md_buf.join) +end + diff --git a/sec1.md b/sec1.md new file mode 100644 index 0000000..1ad9d4e --- /dev/null +++ b/sec1.md @@ -0,0 +1,284 @@ +Up: [Readme.md](src/Readme.md), Next: [Section 2}](src/sec2.src.md)# GtkApplication and GtkApplicationWindow + +## GtkApplication + +### GtkApplication and g\_application\_run + +Usually people write a programming code to make an application. +What are appications? +Applications are software that runs using libraries, which includes OS, frameworks and so on. +In Gtk4 programming, GtkApplication is an object that runs on GTK libraries. + +The basic way how to write GtkApplication is as follows. + +- Generate a GtkApplication object +- Run it + +That's all. +Very simple. +The following is the C code representing the scenario above. + + 1 #include + 2 + 3 int + 4 main (int argc, char **argv) { + 5 GtkApplication *app; + 6 int stat; + 7 + 8 app = gtk_application_new ("com.github.ToshioCP.pr1", G_APPLICATION_FLAGS_NONE); + 9 stat =g_application_run (G_APPLICATION (app), argc, argv); + 10 g_object_unref (app); + 11 return stat; + 12 } + 13 + +The first line says that this program includes the GTK header libraries. +The function `main` above is a startup function in C language. +The variable `app` is defined as a pointer to GtkApplication, which is actually a structure in which information about the application is stored. +The function `gtk_application_new` generates a GtkApplication and sets its pointer to `app`. +The meaning of the arguments will be explained later. +The function `g_application_run` invokes the GtkApplication pointed by `app`. +(We often say that the function invokes `app`. +Actually, `app` is not an object but an pointer to the object. +However, it is simple and short, and probably no confusion occurs.) + +To compile this, the following command needs to be run. +The string pr1.c is the filename of the C source code. + + $ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4` + +The C compiler gcc generates an executable file `a.out`. +Let's run it. + + $ ./a.out + + (a.out:13533): GLib-GIO-WARNING **: 15:30:17.449: Your application does not implement g_application_activate() and has no handlers connected to the "activate" signal. It should do one of these. + $ + +Oh, just an error message. +But this error message means that the GtkApplication object ran without a doubt. +Now, think about the message in the next section. + +### signal + +The message tells us that: + +1. The application GtkApplication doesn't implement `g_application_activate()`. +2. And it has no handlers connected to the activate signal. +3. You need to solve at least one of this. + +These two cause of the error are related to signals. +So, I will explain it to you first. + +Signal is emitted when something happens. +For example, a window is generated, a window is destroyed and so on. +The signal "activate" is emitted when the application is activated. +If the signal is connected to a function, which is called signal handler or simply handler, then the function invokes when the signal emits. +The flow is like this: + +1. Something happens. +2. If it's related to a certain signal, then the signal is emitted. +3. If the signal is connected to a handler in advance, then the handler is invoked. + +Signals are defined in objects. +For example, "activate" signal belongs to GApplication object, which is a parent object of GtkApplication object. +GApplication object is a child object of GObject object. +GObject is the top object in the hierarchy of all the objects. + + GObject -- GApplication -- GtkApplication + <---parent --->child + +A child object derives signals, functions, properties and so on from its parent object. +So, Gtkapplication also has the "activate" signal. + +Now we can solve the problem in `pr1.c`. +We need to connect the activate signal to a handler. +We use a function `g_signal_connect` which connects a signal to a handler. + + 1 #include + 2 + 3 static void + 4 on_activate (GApplication *app, gpointer *user_data) { + 5 g_print ("GtkApplication is activated.\n"); + 6 } + 7 + 8 int + 9 main (int argc, char **argv) { + 10 GtkApplication *app; + 11 int stat; + 12 + 13 app = gtk_application_new ("com.github.ToshioCP.pr2", G_APPLICATION_FLAGS_NONE); + 14 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 15 stat =g_application_run (G_APPLICATION (app), argc, argv); + 16 g_object_unref (app); + 17 return stat; + 18 } + 19 + +First, we define the handler `on_activate` which simply displays a message. +In the function `main`, we add `g_signal_connect` before `g_application_run`. +The function `g_signal_connect` has four arguments. + +1. An object to which the signal belongs. +2. The name of the signal. +3. A handler function (also called callback), which needs to be casted by `G_CALLBACK`. +4. Data to pass to the handler. If no data is necessary, NULL should be given. + +You can find the description of each signal in API reference. +For example, "activate" signal is in GApplication subsection in GIO API reference. +The handler function is described in that subsection. + +In addition, `g_signal_connect` is described in GObject API reference. +API reference is very important. +You should see and understand it to write GTK applications. + +Let's compile the source file `pr2.c` above and run it. + + $ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4` + $ ./a.out + GtkApplication is activated. + $ + +OK, well done. +However, you may have noticed that it's painful to type such a long line to compile. +It is a good idea to use shell script to solve this problem. +Make a text file which contains the following text. + + gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4` + +Then, save it in $HOME/bin, which is usually /home/(username)/bin. +(If your user name is James, then the directory is /home/james/bin). +And turn on the execute bit of the file. +Suppose the filename is comp, then the procedure is as follows. + + $ chmod 755 $HOME/bin/comp + $ ls -log $HOME/bin + ... ... ... + -rwxr-xr-x 1 62 May 23 08:21 comp + ... ... ... + +If this is the first time that you make a $HOME/bin directory and save a file in it, then you need to logout and login again. + + $ comp pr2 + $ ./a.out + GtkApplication is activated. + $ + +## GtkWindow and GtkApplicationWindow + +### GtkWindow + +A message "GtkApplication is activated." was printed out in the previous subsection. +It was good in terms of a test of GtkApplication. +However, it is insufficient because GTK is a framework for graphical user interface (GUI). +Now we go ahead with adding a window into this program. +What we need to do is: + +1. Generate a GtkWindow. +2. Connect it to GtkApplication. +3. Show the window. + +Now rewrite the function `on_activate`. + +#### Generate a GtkWindow + + 1 static void + 2 on_activate (GApplication *app, gpointer user_data) { + 3 GtkWidget *win; + 4 + 5 win = gtk_window_new (); + 6 gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + 7 gtk_widget_show (win); + 8 } + +Widget is an abstract concept that includes all the GUI interfaces such as windows, dialogs, buttons, multiline text, containers and so on. +And GtkWidget is a base object from which all the GUI objects derive. + + parent <-----> child + GtkWidget -- GtkWindow + +GtkWindow includes GtkWidget at the top of its object. + +![GtkWindow and GtkWidget](window_widget.png) + +The function `gtk_window_new` is defined as follows. + + GtkWidget * + gtk_window_new (void); + +By this definition, it returns a pointer to GtkWidget, not GtkWindow. +It actually generates a new GtkWindow object (not GtkWidget) but returns a pointer to GtkWidget. +However,the pointer points the GtkWidget and at the same time it also points GtkWindow that contains GtkWidget in it. + +If you want to use `win` as a pointer to the GtkWindow, you need to cast it. + + (GtkWindow *) win + +Or you can use `GTK_WINDOW` macro that performs a similar function. + + GTK_WINDOW (win) + +This is a recommended way. + +#### Connect it to GtkApplication. + +The function `gtk_window_set_application` is used to connect GtkWidow to GtkApplication. + + gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + +You need to cast `win` to GtkWindow and `app` to GtkApplication. +`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that. + +GtkApplication continues to run until the related window is destroyed. +If you didn't connect GtkWindow and GtkApplication, GtkApplication shutdowns soon. +Because no window is connected to GtkApplication, it doesn't need to wait anything. +As it shutdowns the generated window is also destroyed. + +#### Show the window. + +The function `gtk_widget_show` is used to show the window. + +Gtk4 changed the default widget visibility to on, so every widget doesn't need this function to show itself. +But, there's an exception. +Top window (this term will be explained later) isn't visible when it is generated. +So you need to use the function above and show the window. + +Save the program as `pr3.c` and compile and run it. + + $ comp pr3 + $ ./a.out + +A small window appears. + +![Screenshot of the window](screenshot_pr3.png) + +Click on the close button then the window disappears and the program finishes. + +### GtkApplicationWindow + +GtkApplicationWindow is a child object of GtkWindow. +It has some extra functionality for better integration with GtkApplication. +It is recommended to use it instead of GtkWindow when you use GtkApplication. + +Now rewrite the program and use GtkAppliction Window. + + 1 static void + 2 on_activate (GApplication *app, gpointer user_data) { + 3 GtkWidget *win; + 4 + 5 win = gtk_application_window_new (GTK_APPLICATION (app)); + 6 gtk_window_set_title (GTK_WINDOW (win), "pr4"); + 7 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 8 gtk_widget_show (win); + 9 } + +When you generate GtkApplicationWindow, you need to give GtkApplication object as an argument. +Then it automatically connect these two objects. +So you don't need to call `gtk_window_set_application` any more. + +The program sets the title and the default size of the window. +Compile it and run `a.out`, then you will see a bigger window with its title "pr4". + +![Screenshot of the window](screenshot_pr4.png) + +Up: [Readme.md](src/Readme.md), Next: [Section 2}](src/sec2.src.md) \ No newline at end of file diff --git a/sec10.md b/sec10.md new file mode 100644 index 0000000..311b014 --- /dev/null +++ b/sec10.md @@ -0,0 +1,345 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 9}](src/sec9.src.md), Next: [Section 11[(src/sec11.src.md)# Functions in TfeTextView + +In this section I will explain each function in TfeTextView object. + +### tfe.h and tfetextview.h + +`tfe.h` is a top header file and it includes `gtk.h` and all the header files. +Every C source files, which are `tfeapplication.c`, `tfenotebook.c` and `tfetextview.c`, include `tfe.h` at the beginning of each file. + + 1 #include + 2 + 3 #include "tfetextview.h" + 4 #include "tfenotebook.h" + +`tfetextview.h` is a header file which describes the public functions in `tfetextview.c`. + + 1 #define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () + 2 G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + 3 + 4 /* "open-response" signal response */ + 5 enum + 6 { + 7 TFE_OPEN_RESPONSE_SUCCESS, + 8 TFE_OPEN_RESPONSE_CANCEL, + 9 TFE_OPEN_RESPONSE_ERROR + 10 }; + 11 + 12 GFile * + 13 tfe_text_view_get_file (TfeTextView *tv); + 14 + 15 void + 16 tfe_text_view_open (TfeTextView *tv); + 17 + 18 void + 19 tfe_text_view_save (TfeTextView *tv); + 20 + 21 void + 22 tfe_text_view_saveas (TfeTextView *tv); + 23 + 24 GtkWidget * + 25 tfe_text_view_new_with_file (GFile *file); + 26 + 27 GtkWidget * + 28 tfe_text_view_new (void); + 29 + +- 1-2: These two lines are used to define TfeTextView. +- 4-10: Definitions of parameter used in the handler of "open-response" signal. +- 12-28: Public functions on GtkTextView. + +Each function will be explained later in this section. + +## Functions to generate TfeTextView object + +TfeTextView Object is generated by `tfe_text_view_new` or `tfe_text_view_new_with_file`. + + GtkWidget *tfe_text_view_new (void); + +`tfe_text_view_new` just generates a new TfeTextView object and returns the pointer to the new object. + + GtkWidget *tfe_text_view_new_with_file (GFile *file); + +`tfe_text_view_new_with_file` is given a Gfile object as the argument and it loads the file into the GtkTextBuffer object, then returns the pointer to the new object. + +Parameter: + +- `file`: a pointer to the GFile object. + +Return value: + +- A pointer to the generated TfeTextView object but it is casted to a pointer to GtkWidget. +If an error occures during the genration process, NULL is returned. + +Each function is defined as follows. + + 1 GtkWidget * + 2 tfe_text_view_new_with_file (GFile *file) { + 3 g_return_val_if_fail (G_IS_FILE (file), NULL); + 4 + 5 GtkWidget *tv; + 6 char *contents; + 7 gsize length; + 8 + 9 if (! g_file_load_contents (file, NULL, &contents, &length, NULL, NULL)) /* read error */ + 10 return NULL; + 11 + 12 tv = tfe_text_view_new(); + 13 gtk_text_buffer_set_text (TFE_TEXT_VIEW (tv)->tb, contents, length); + 14 g_free (contents); + 15 TFE_TEXT_VIEW (tv)->file = g_file_dup (file); + 16 return tv; + 17 } + 18 + 19 GtkWidget * + 20 tfe_text_view_new (void) { + 21 return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + 22 } + +- 18-21: `tfe_text_view_new`. +Just returns the value from the function `gtk_widget_new`. +Initialization is done in `tfe_text_view_init` which is called in the process of `gtk_widget_new` function. +- 1-16: `tfe_text_view_new_with_file` +- 3: `g_return_val_if_fail` is described in [Glib API reference](https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail). +It tests whether the argument `file` is a pointer to GFile. +If it's true, then the program goes on to the next line. +If it's false, then it returns NULL (the second argument) immediately. +And at the same time it logs out the error message (usually the log is outputted to stderr or stdout). +This function is used to check the programmer's error. +If an error occurs, the solution is usually to change the (caller) program and fix the bug. +You need to distinguish programmer's errors and runtime errors. +You shouldn't use this function to find runtime errors. +- 9-10: If an error occurs when reading the file, then return NULL. +- 11-15: Generate TfeTextView and set the pointer to it to `tv`. +Set the contents read from the file to GtkTextBuffer `tv->tb`. +Free the memories pointed by `contents`. +Duplicate `file` and set it to `tv->file`. +Return `tv`. + +## Save and saveas functions + +Save and saveas functions write the contents in GtkTextBuffer to a file. + + void tfe_text_view_save (TfeTextView *tv) + +`save` function writes the contents in GtkTextBuffer to a file specified by `tv->file`. +If `tv->file` is NULL, then it shows GtkFileChooserDialog and lets the user to give a file to the program. After that, it saves the contents to the specified file and set the file into `tv->file`. + + void tfe_text_view_saveas (TfeTextView *tv) + +`saveas` function uses GtkFileChooserDialog and lets the user to give a new file to the program. Then, the function changes `tv->file` and save the contents to the specified new file. + +If an error occures, it is shown to the user through the message dialog. +The error is managed only in the object and no information is notified to the caller. + + 1 static void + 2 saveas_dialog_response (GtkWidget *dialog, gint response, TfeTextView *tv) { + 3 GFile *file; + 4 + 5 if (response == GTK_RESPONSE_ACCEPT) { + 6 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); + 7 if (G_IS_FILE(file)) { + 8 tv->file = file; + 9 tv->changed = TRUE; + 10 g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + 11 tfe_text_view_save (TFE_TEXT_VIEW (tv)); + 12 } + 13 } + 14 gtk_window_destroy (GTK_WINDOW (dialog)); + 15 } + 16 + 17 void + 18 tfe_text_view_save (TfeTextView *tv) { + 19 g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + 20 + 21 GtkTextIter start_iter; + 22 GtkTextIter end_iter; + 23 gchar *contents; + 24 GtkWidget *message_dialog; + 25 GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW); + 26 GError *err = NULL; + 27 + 28 if (! tv->changed) + 29 return; /* no necessary to save it */ + 30 else if (tv->file == NULL) + 31 tfe_text_view_saveas (tv); + 32 else { + 33 gtk_text_buffer_get_bounds (tv->tb, &start_iter, &end_iter); + 34 contents = gtk_text_buffer_get_text (tv->tb, &start_iter, &end_iter, FALSE); + 35 if (g_file_replace_contents (tv->file, contents, strlen (contents), NULL, TRUE, G_FILE_CREATE_NONE, NULL, NULL, &err)) + 36 tv->changed = FALSE; + 37 else { + 38 /* It is possible that tv->file is broken. */ + 39 /* It is a good idea to set tv->file to NULL. */ + 40 if (G_IS_FILE (tv->file)) + 41 g_object_unref (tv->file); + 42 tv->file =NULL; + 43 g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + 44 tv->changed = TRUE; + 45 message_dialog = gtk_message_dialog_new (GTK_WINDOW (win), GTK_DIALOG_MODAL, + 46 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + 47 "%s.\n", err->message); + 48 g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL); + 49 gtk_widget_show (message_dialog); + 50 g_error_free (err); + 51 } + 52 } + 53 } + 54 + 55 void + 56 tfe_text_view_saveas (TfeTextView *tv) { + 57 g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + 58 + 59 GtkWidget *dialog; + 60 GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW); + 61 + 62 dialog = gtk_file_chooser_dialog_new ("Save file", GTK_WINDOW (win), GTK_FILE_CHOOSER_ACTION_SAVE, + 63 "_Cancel", GTK_RESPONSE_CANCEL, + 64 "_Save", GTK_RESPONSE_ACCEPT, + 65 NULL); + 66 g_signal_connect (dialog, "response", G_CALLBACK (saveas_dialog_response), tv); + 67 gtk_widget_show (dialog); + 68 } + +- 17-53: `Tfe_text_view_save` function. +- 19: If `tv` is not a pointer to TfeTextView, then it logs an error message and immediately returns. +This function is similar to `g_return_val_if_fail` function, but no value is returned because `tfe_text_view_save` doesn't return a value. +- 28-29: If the buffer hasn't modified, then it doesn't need to save it. +So the function returns. +- 30-31: If `tv->file` is NULL, no file has given yet. +It calls `tfe_text_view_save`, which lets the user to choose a file to save. +- 33-35: Save the buffer to the file. +If it succeeds, assigns FALSE to `tv->changed`. +- 38-50: If file writing fails, it assigns NULL to `tv->file`. +Emits "change-file" signal. +Shows the error message dialog (45-49). +Because the handler is `gtk_window_destroy`, the dialog disappears when user clicks on the button in the dialog. +- 55-68: `tfe_text_view_saveas` function. +It shows GtkFileChooserDialog and lets the user choose a file and give it to the signal handler. +- 62: Generate GtkFileChooserDialog. +The title is "Save file". +Transient parent of the dialog is `win`, which is the top level window. +The action is save mode. +The buttons are Cancel and Save. +- 63: connect the "response" signal of the dialog and `saveas_dialog_response` handler. +- 1-15: `saveas_dialog_response` signal handler. +- 5-13: If the response is `GTK_RESPONSE_ACCEPT`, which is set to the argument when the user has clicked on Save button, then gets a pointer to the GFile object, set it to `tv->file`, assign TRUE to `tv->changed`, emits "change-file" signal then call `tfe_text_view_save` to save the buffer to the file. + +![Saveas process](saveas.png) + +When you use GtkFileChooserDialog, you need to divide the program into two parts. +They are a function which generates GtkFileChooserDialog and the signal handler. +The function just generates and shows the dialog. +The rest is done by the handler. +It gets Gfile from GtkFileChooserDialog, save the buffer to the file and do some things necessary. + +## Open function + +Open function shows GtkFileChooserDialog to the user and let him/her choose a file. +Then read the file and set it to GtkTextBuffer. + + void tfe_text_view_open (TfeTextView *tv) + +TfeTextView object `tv` has to be generated in advance. +And it should be empty and `tv->file` is NULL. +If it is not empty, `tfe_text_view_open` doesn't treat it as an error. +If you want to revert the buffer, calling this function is apropreate. +Otherwise probably bad things will happen. + + 1 static void + 2 open_dialog_response(GtkWidget *dialog, gint response, TfeTextView *tv) { + 3 GFile *file; + 4 char *contents; + 5 gsize length; + 6 GtkWidget *message_dialog; + 7 GError *err = NULL; + 8 + 9 if (response != GTK_RESPONSE_ACCEPT) + 10 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL); + 11 else if (! G_IS_FILE (file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)))) + 12 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + 13 else if (! g_file_load_contents (file, NULL, &contents, &length, NULL, &err)) { /* read error */ + 14 if (G_IS_FILE (file)) + 15 g_object_unref (file); + 16 message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_MODAL, + 17 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + 18 "%s.\n", err->message); + 19 g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL); + 20 gtk_widget_show (message_dialog); + 21 g_error_free (err); + 22 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + 23 } else { + 24 gtk_text_buffer_set_text (tv->tb, contents, length); + 25 g_free (contents); + 26 tv->file = file; + 27 /* tv->changed = FALSE;*/ + 28 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS); + 29 } + 30 gtk_window_destroy (GTK_WINDOW (dialog)); + 31 } + 32 + 33 void + 34 tfe_text_view_open (TfeTextView *tv) { + 35 g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + 36 + 37 GtkWidget *dialog; + 38 + 39 dialog = gtk_file_chooser_dialog_new ("Open file", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, + 40 "Cancel", GTK_RESPONSE_CANCEL, + 41 "Open", GTK_RESPONSE_ACCEPT, + 42 NULL); + 43 g_signal_connect (dialog, "response", G_CALLBACK (open_dialog_response), tv); + 44 gtk_widget_show (dialog); + 45 } + +- 33-45: `tfe_text_view_open` function. +- 39: Generate GtkFileChooserDialog. +The title is "Open file". +No transient parent window. +The action is open mode. +The buttons are Cancel and Open. +- 43: connect the "reponse" signal of the dialog and `open_dialog_response` signal handler. +- 44: Show the dialog. +- 1-31: `open_dialog_response` signal handler. +- 9-10: If the response from GtkFileChooserDialog is not `GTK_RESPONSE_ACCEPT`, which means the user has clicked on the "Cancel" button or close button, then it emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_CANCEL`. +- 11-12: Get a pointer to Gfile by `gtk_file_chooser_get_file`. +If it is not GFile, maybe an error occured. +Then it emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_ERROR`. +- 13-22: If an error occurs when it has read the file, then it decreases the reference count of Gfile, shows a message dialog to report the error to the user and emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_ERROR`. +- 24-28: If the file has successfully read, then the text is set to GtkTextBuffer, free the temporary buffer pointed by `contents`, set file to `tv->file` (no duplication or unref is not necessary) and emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_SUCCESS`. +- 30: close GtkFileCooserDialog. + +Now let's think about the whole process between the other object (caller) and TfeTextView. +It is shown in the following diagram and you would think that it is really complicated. +Because signal is the only way for GtkFileChooserDialog to communicate with others. +In Gtk3, `gtk_dialog_run` function is available. +It simplifies the process. +However, in Gtk4, `gtk_dialog_run`is unavailable any more. + +![Caller and TfeTextView](open.png) + +1. A caller get a pointer `tv` to TfeTextView by calling `tfe_text_view_new`. +2. The caller connects the handler (left bottom in the diagram) and the signal "open-response". +3. It calls `tfe_text_view_open` to let the user select a file from GtkFileChooserDialog. +4. The dialog emits a signal and it invokes the handler `open_dialog_response`. +5. The handler read the file and set it into GtkTextBuffer and emits a signal to inform the response status. +6. The handler outside TfeTextView recieves the signal. + +## Get file function + +`gtk_text_view_get_file` is a simple function show as follows. + + 1 GFile * + 2 tfe_text_view_get_file (TfeTextView *tv) { + 3 g_return_val_if_fail (TFE_IS_TEXT_VIEW (tv), NULL); + 4 + 5 return g_file_dup (tv->file); + 6 } + +The important thing is duplicate `tv->file`. +Otherwise, if the caller free the GFile object, `tv->file` is no more guaranteed to point the GFile. + +## Source file of tfetextview.c + +All the source files are listed in [Section 13](ch13.html). +Up: [Readme.md](src/Readme.md), Prev: [Section 9}](src/sec9.src.md), Next: [Section 11[(src/sec11.src.md) \ No newline at end of file diff --git a/sec11.md b/sec11.md new file mode 100644 index 0000000..5a6e89d --- /dev/null +++ b/sec11.md @@ -0,0 +1,204 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 10}](src/sec10.src.md), Next: [Section 12[(src/sec12.src.md)# Functions with GtkNotebook + +GtkNotebook is a very important object in the text file editor `tfe`. +It connects the application and TfeTextView objects. +`tfenotebook.h` and `tfenotebook.c` describe a set of functions related to GtkTextbook. + + 1 void + 2 notebook_page_save(GtkNotebook *nb); + 3 + 4 void + 5 notebook_page_open (GtkNotebook *nb); + 6 + 7 void + 8 notebook_page_new_with_file (GtkNotebook *nb, GFile *file); + 9 + 10 void + 11 notebook_page_new (GtkNotebook *nb); + 12 + +This header file shows the public functions in `tfenotebook.c`. + +- `notebook_page_new` generates a new GtkNotebookPage and adds GtkScrolledWindow and TfeTextView under the page. +- `notebook_page_new_with_file` generates a new GtkNotebookPage and adds GtkScrolledWindow and TfeTextView under the page. `file` is set to the pointer to GFile in the TfeTextView object and the file is read and set into GtkTextBuffer. +- `notebook_page_open` lets the user select a file and sets it into GtkTextBuffer. +- `notebook_page_save` save the contents in GtkTextBuffer to a file, using the pointer `tv->file`. + +You probably find that the functions above are higher level functions of `tfe_text_view_new`, `tfe_text_view_new_with_file`, `tef_text_view_open` and `tfe_text_view_save` respectively. +There are two layers. +One of them is `tfe_text_view ...`, which is the lower level layer. +The other is `note_book ...`, which is the higher level layer. + +Now let's look at each program of the functions. + +## notebook\_page\_new + + 1 static gchar* + 2 get_untitled () { + 3 static int c = -1; + 4 if (++c == 0) + 5 return g_strdup_printf("Untitled"); + 6 else + 7 return g_strdup_printf ("Untitled%u", c); + 8 } + 9 + 10 static void + 11 notebook_page_build (GtkNotebook *nb, GtkWidget *tv, char *filename) { + 12 GtkWidget *scr; + 13 GtkNotebookPage *nbp; + 14 GtkWidget *lab; + 15 gint i; + 16 scr = gtk_scrolled_window_new (); + 17 + 18 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 19 lab = gtk_label_new (filename); + 20 i = gtk_notebook_append_page (nb, scr, lab); + 21 nbp = gtk_notebook_get_page (nb, scr); + 22 g_object_set (nbp, "tab-expand", TRUE, NULL); + 23 gtk_notebook_set_current_page (nb, i); + 24 g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb); + 25 } + 26 + 27 void + 28 notebook_page_new (GtkNotebook *nb) { + 29 g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + 30 + 31 GtkWidget *tv; + 32 char *filename; + 33 + 34 tv = tfe_text_view_new (); + 35 filename = get_untitled (); + 36 notebook_page_build (nb, tv, filename); + 37 } + +- 27-37: `notebook_page_new` function. +- 29: `g_return_if_fail` is used because `notebook_page_new` is a public function. +- 34: Generate TfeTextView object. +- 35: Generate filename, which is "Untitled", "Untitled2", ... . +- 1-8: `get_untitled` function. +- 3: Static variable `c` is initialized at the first call of this function. After that `c` keeps its value except it is changed explicitly. +- 4-7: Increase `c` by one and if it is zero then the name is "Untitled". If it is a positive integer then the name is "Untitled", for example, "Untitled1", "Untitled2", and so on. +It returns the name. +`g_strdup_printf` generates a string and it should be freed by `g_free` function. +The caller of `get_untitled` is in charge of freeing the memories of the string. +- 36: call `notebook_page_build` to build the contents of the page. +- 10- 25: `notebook_page_build` function. +- 17-18: Generate GtkScrolledWindow and set `tv` to its child. +- 19-20: Generate GtkLabel, then GtkNotebookPage. +- 21-22: Set "tab-expand" property to TRUE. +- 23: Set the page to the current page. +- 24: Connect "change-file" signal and `file_changed` handler. + +## notebook\_page\_new\_with\_file + + 1 void + 2 notebook_page_new_with_file (GtkNotebook *nb, GFile *file) { + 3 g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + 4 g_return_if_fail(G_IS_FILE (file)); + 5 + 6 GtkWidget *tv; + 7 char *filename; + 8 + 9 if ((tv = tfe_text_view_new_with_file (file)) == NULL) + 10 return; /* read error */ + 11 filename = g_file_get_basename (file); + 12 notebook_page_build (nb, tv, filename); + 13 } + +- 9-10: Call `tfe_text_view_new_with_file`. +If it returns NULL, then do nothing and return because of an error. +-11-13: Get the filename , build the contents of the page, then free `filename`. + +## notebook\_page\_open + + 1 static void + 2 open_response (TfeTextView *tv, gint response, GtkNotebook *nb) { + 3 GFile *file; + 4 char *filename; + 5 + 6 if (response != TFE_OPEN_RESPONSE_SUCCESS) + 7 g_object_unref (tv); + 8 else if (! G_IS_FILE (file = tfe_text_view_get_file (tv))) + 9 g_object_unref (tv); + 10 else { + 11 filename = g_file_get_basename (file); + 12 g_object_unref (file); + 13 notebook_page_build (nb, GTK_WIDGET (tv), filename); + 14 } + 15 } + 16 + 17 void + 18 notebook_page_open (GtkNotebook *nb) { + 19 g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + 20 + 21 GtkWidget *tv; + 22 + 23 tv = tfe_text_view_new (); + 24 g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb); + 25 tfe_text_view_open (TFE_TEXT_VIEW (tv)); + 26 } + +- 18-27: `notebook_page_open` function. +- 24: Generate TfeTextView object. +- 25: Connect the signal "open-response" and the handler `open_response`. +- 26: Call `tfe_text_view_open`. +It emits "open-response" signal to inform the status after the series of functions run. +- 1-16: `open_response` handler. +This is the postfunction of `notebook_page_open`. +- 6-7: It the status is NOT `TFE_OPEN_RESPONSE_SUCCESS`, cancel what we did in `notebook_page_open`. +Unref `tv`. +- 8-9: If `tfe_text_view_get_file` returns a pointer not to point GFile, then something bad happens. Cancel what we did. Unref `tv`. +- 10-14: Otherwise, everything was okay. +Get the filename, build the contents of the page, free `filename` and unref `tv` + +## notebook\_page\_save + + 1 void + 2 notebook_page_save(GtkNotebook *nb) { + 3 gint i; + 4 GtkWidget *scr; + 5 GtkWidget *tv; + 6 + 7 i = gtk_notebook_get_current_page (nb); + 8 scr = gtk_notebook_get_nth_page (nb, i); + 9 tv = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scr)); + 10 tfe_text_view_save (TFE_TEXT_VIEW (tv)); + 11 } + +- 7-9: Get TfeTextView belongs to the current notebook page. +- 10: Call `tfe_text_view_save`. + +## file\_changed handler + +`file_changed` is a handler connected to "change-file" signal. +If `tv->file` is changed, TfeTextView emits this signal. +This handler changes the label of GtkNotebookPage. + + 1 static void + 2 file_changed (TfeTextView *tv, GtkNotebook *nb) { + 3 GFile *file; + 4 char *filename; + 5 GtkWidget *scr; + 6 GtkWidget *label; + 7 + 8 file = tfe_text_view_get_file (tv); + 9 scr = gtk_widget_get_parent (GTK_WIDGET (tv)); + 10 if (G_IS_FILE (file)) + 11 filename = g_file_get_basename (file); + 12 else + 13 filename = get_untitled (); + 14 label = gtk_label_new (filename); + 15 gtk_notebook_set_tab_label (nb, scr, label); + 16 g_object_unref (file); + 17 g_free (filename); + 18 } + +- 8: Get GFile from TfeTextView. +- 9: Get the parent (GkScrolledWindow) of `tv`. +- 10-13: If `file` points GFile, then assign the filename of the GFile into `filename`. +Otherwise (this is the case file is NULL), assign untitled string to `filename`. +- 14-15: Generate a label with the filename and set it into GtkNotebookPage. +- 16-17: Free `filename and unref `file`. + + +Up: [Readme.md](src/Readme.md), Prev: [Section 10}](src/sec10.src.md), Next: [Section 12[(src/sec12.src.md) \ No newline at end of file diff --git a/sec12.md b/sec12.md new file mode 100644 index 0000000..0508c4f --- /dev/null +++ b/sec12.md @@ -0,0 +1,269 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 11}](src/sec11.src.md), Next: [Section 13[(src/sec13.src.md)# tfeapplication.c + +`tfeapplication.c` includes all the code other than `tfetxtview.c` and `tfenotebook.c`. +It does following things. + +- Application support, mainly handling command line arguments. +- Build widgets using ui file. +- Connect button signals and their handlers. +- Manage CSS. + +## main + +Th function `main` is the first invoked function in C language. +It connects the command line given by the user and GTK application. + + 1 int + 2 main (int argc, char **argv) { + 3 GtkApplication *app; + 4 int stat; + 5 + 6 app = gtk_application_new ("com.github.ToshioCP.tfe", G_APPLICATION_HANDLES_OPEN); + 7 + 8 g_signal_connect (app, "startup", G_CALLBACK (tfe_startup), NULL); + 9 g_signal_connect (app, "activate", G_CALLBACK (tfe_activate), NULL); + 10 g_signal_connect (app, "open", G_CALLBACK (tfe_open), NULL); + 11 + 12 stat =g_application_run (G_APPLICATION (app), argc, argv); + 13 g_object_unref (app); + 14 return stat; + 15 } + +- 6: Generate GtkApplication object. +- 8-10: Connect "startup", "activate" and "open signals to their handlers. +- 12: Run the application. +- 13-14: release the reference to the application and return the status. + +## statup signal handler + +"startup" signal is emitted just after the application is generated. +What the signal handler needs to do is initialization of the application. + +- Build the widgets using ui file. +- Connect button signals and their handlers. +- Set CSS. + +The handler is as follows. + + 1 static void + 2 tfe_startup (GApplication *application) { + 3 GtkApplication *app = GTK_APPLICATION (application); + 4 GtkApplicationWindow *win; + 5 GtkNotebook *nb; + 6 GtkBuilder *build; + 7 GtkButton *btno; + 8 GtkButton *btnn; + 9 GtkButton *btns; + 10 GtkButton *btnc; + 11 + 12 build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe/tfe.ui"); + 13 win = GTK_APPLICATION_WINDOW (gtk_builder_get_object (build, "win")); + 14 nb = GTK_NOTEBOOK (gtk_builder_get_object (build, "nb")); + 15 gtk_window_set_application (GTK_WINDOW (win), app); + 16 btno = GTK_BUTTON (gtk_builder_get_object (build, "btno")); + 17 btnn = GTK_BUTTON (gtk_builder_get_object (build, "btnn")); + 18 btns = GTK_BUTTON (gtk_builder_get_object (build, "btns")); + 19 btnc = GTK_BUTTON (gtk_builder_get_object (build, "btnc")); + 20 g_signal_connect (btno, "clicked", G_CALLBACK (open_clicked), nb); + 21 g_signal_connect (btnn, "clicked", G_CALLBACK (new_clicked), nb); + 22 g_signal_connect (btns, "clicked", G_CALLBACK (save_clicked), nb); + 23 g_signal_connect (btnc, "clicked", G_CALLBACK (close_clicked), nb); + 24 g_object_unref(build); + 25 + 26 GdkDisplay *display; + 27 + 28 display = gtk_widget_get_display (GTK_WIDGET (win)); + 29 GtkCssProvider *provider = gtk_css_provider_new (); + 30 gtk_css_provider_load_from_data (provider, "textview {padding: 10px; font-family: monospace; font-size: 12pt;}", -1); + 31 gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER); + 32 } + +- 12-15: Build widgets using ui file (resource). +Connect the top window and the application using `gtk_window_set_application`. +- 16-23: Get buttons and connect their signals and handlers. +- 24: Release the reference to GtkBuilder. +- 26-31: Set CSS. +CSS in GTK is similar to CSS in HTML. +You can set margin, border, padding, color, font and so on with CSS. +In this program CSS is in line 30. +It sets padding, font-family and font size of GtkTextView. +- 26-28: GdkDisplay is used to set CSS. +CSS will be explained in the next subsection. + +## CSS in GTK + +CSS is an abbretiation of Cascading Style Sheet. +It is originally used with HTML to describe the presentation semantics of a document. +You might have found that the widgets in GTK is simialr to the window in a browser. +It implies that CSS can also be apllied to GTK windowing system. + +### CSS nodes, selectors + +The syntax of CSS is as follws. + + selector { color: yellow; padding-top: 10px; ...} + +Every widget has CSS node. +For example GtkTextView has `textview` node. +If you want to set style to GtkTextView, set "textview" to the selector. + + textview {color: yeallow; ...} + +Class, ID and some other things can be applied to the selector like Web CSS. Refer GTK4 API reference for further information. + +In line 30, the CSS is a string. + + textview {padding: 10px; font-family: monospace; font-size: 12pt;} + +- padding is a space between the border and contents. +This space makes the text easier to read. +- font-family is a name of font. +"monospace" is one of the generic family font keywords. +- font-size is set to 12pt. +It is a bit large, but easy on the eyes especially for elderly people. + +### GtkStyleContext, GtkCSSProvider and GdkDisplay + +GtkStyleContext is an object that stores styling information affecting a widget. +Each widget is connected to the corresponding GtkStyleContext. +You can get the context by `gtk_widget_get_style_context`. + +GtkCssProvider is an object which parses CSS in order to style widgets. + +To apply your CSS to wodgets, you need to add GtkStyleProvider (the interface of GtkCSSProvider) to GtkStyleContext. +However, instead, you can add it to GdkDisplay of the window (usually top level window). + +Look at the source file of `startup` handler again. + +- 28: The display is obtained by `gtk_widget_get_display`. +- 29: Generate GtkCssProvider. +- 30: Set the CSS into the provider. +- 31: Add the provider to the display. + +It is possible to add the provider to the context of GtkTextView instead of GdkDiplay. +To do so, rewrite `tfe_text_view_new`. + + GtkWidget * + tfe_text_view_new (void) { + GtkWidget *tv; + + tv = gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + + GtkStyleContext *context; + + context = gtk_widget_get_style_context (GTK_WIDGET (tv)); + GtkCssProvider *provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, "textview {padding: 10px; font-family: monospace; font-size: 12pt;}", -1); + gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER); + + return tv; + } + +CSS set to the context takes precedence over the one set to the display. + +## activate and open handler + +The handler of "activate" and "open" signal are `tfe_activate` and `tfe_open` respectively. +They just generate a new GtkNotebookPage. + + 1 static void + 2 tfe_activate (GApplication *application) { + 3 GtkApplication *app = GTK_APPLICATION (application); + 4 GtkWidget *win; + 5 GtkWidget *boxv; + 6 GtkNotebook *nb; + 7 + 8 win = GTK_WIDGET (gtk_application_get_active_window (app)); + 9 boxv = gtk_window_get_child (GTK_WINDOW (win)); + 10 nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv)); + 11 + 12 notebook_page_new (nb); + 13 gtk_widget_show (GTK_WIDGET (win)); + 14 } + 15 + 16 static void + 17 tfe_open (GApplication *application, GFile ** files, gint n_files, const gchar *hint) { + 18 GtkApplication *app = GTK_APPLICATION (application); + 19 GtkWidget *win; + 20 GtkWidget *boxv; + 21 GtkNotebook *nb; + 22 int i; + 23 + 24 win = GTK_WIDGET (gtk_application_get_active_window (app)); + 25 boxv = gtk_window_get_child (GTK_WINDOW (win)); + 26 nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv)); + 27 + 28 for (i = 0; i < n_files; i++) + 29 notebook_page_new_with_file (nb, files[i]); + 30 if (gtk_notebook_get_n_pages (nb) == 0) + 31 notebook_page_new (nb); + 32 gtk_widget_show (win); + 33 } + +- 1-14: `tfe_activate`. +- 8-10: Get GtkNotebook object. +- 12-13: Generate a new GtkNotebookPage and show the window. +- 16-33: `tfe_open`. +- 24-26: Get GtkNotebook object. +- 28-29: Generate GtkNotebookPage with files. +- 30-31: If opening and reading file failed and no GtkNotebookPage has generated, then generate a empty page. +- 32: Show the window. + +These codes have become really simple thanks to tfenotebook.c and tfetextview.c. + +## a series of handlers correspond to the button signals + + 1 static void + 2 open_clicked (GtkWidget *btno, GtkNotebook *nb) { + 3 notebook_page_open (nb); + 4 } + 5 + 6 static void + 7 new_clicked (GtkWidget *btnn, GtkNotebook *nb) { + 8 notebook_page_new (nb); + 9 } + 10 + 11 static void + 12 save_clicked (GtkWidget *btns, GtkNotebook *nb) { + 13 notebook_page_save (nb); + 14 } + 15 + 16 static void + 17 close_clicked (GtkWidget *btnc, GtkNotebook *nb) { + 18 GtkWidget *win; + 19 GtkWidget *boxv; + 20 gint i; + 21 + 22 if (gtk_notebook_get_n_pages (nb) == 1) { + 23 boxv = gtk_widget_get_parent (GTK_WIDGET (nb)); + 24 win = gtk_widget_get_parent (boxv); + 25 gtk_window_destroy (GTK_WINDOW (win)); + 26 } else { + 27 i = gtk_notebook_get_current_page (nb); + 28 gtk_notebook_remove_page (GTK_NOTEBOOK (nb), i); + 29 } + 30 } + +`open_clicked`, `new_clicked` and `save_clicked` just call corresponding notebook page functions. +`close_clicked` is a bit complicated. + +- 22-25: If there's only one page, closing the last page is considered that it also close the top level window and quit the application. +Therefore, it gets the top level window and call `gtk_window_destroy`. +- 26-28: Otherwise, it removes the current page. + +## meson.build + + 1 project('tfe', 'c') + 2 + 3 gtkdep = dependency('gtk4') + 4 + 5 gnome=import('gnome') + 6 resources = gnome.compile_resources('resources','tfe.gresource.xml') + 7 + 8 sourcefiles=files('tfeapplication.c', 'tfenotebook.c', 'tfetextview.c') + 9 + 10 executable('tfe', sourcefiles, resources, dependencies: gtkdep) + +This file is just modified the source file names. + +Up: [Readme.md](src/Readme.md), Prev: [Section 11}](src/sec11.src.md), Next: [Section 13[(src/sec13.src.md) \ No newline at end of file diff --git a/sec13.md b/sec13.md new file mode 100644 index 0000000..e4eeab1 --- /dev/null +++ b/sec13.md @@ -0,0 +1,619 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 12}](src/sec12.src.md), Next: [Section 14[(src/sec14.src.md)# tfe5 source files + +The followings are the source files of tfe5. + +## meson.buld + + 1 project('tfe', 'c') + 2 + 3 gtkdep = dependency('gtk4') + 4 + 5 gnome=import('gnome') + 6 resources = gnome.compile_resources('resources','tfe.gresource.xml') + 7 + 8 sourcefiles=files('tfeapplication.c', 'tfenotebook.c', 'tfetextview.c') + 9 + 10 executable('tfe', sourcefiles, resources, dependencies: gtkdep) + +## tfe.gresource.xml + + 1 + 2 + 3 + 4 tfe.ui + 5 + 6 + +## tfe.ui + + 1 + 2 + 3 file editor + 4 600 + 5 400 + 6 + 7 + 8 GTK_ORIENTATION_VERTICAL + 9 + 10 + 11 GTK_ORIENTATION_HORIZONTAL + 12 + 13 + 14 10 + 15 + 16 + 17 + 18 + 19 _New + 20 TRUE + 21 + 22 + 23 + 24 + 25 _Open + 26 TRUE + 27 + 28 + 29 + 30 + 31 TRUE + 32 + 33 + 34 + 35 + 36 _Save + 37 TRUE + 38 + 39 + 40 + 41 + 42 _Close + 43 TRUE + 44 + 45 + 46 + 47 + 48 10 + 49 + 50 + 51 + 52 + 53 + 54 + 55 TRUE + 56 TRUE + 57 TRUE + 58 + 59 + 60 + 61 + 62 + 63 + 64 + +## tfe.h + + 1 #include + 2 + 3 #include "tfetextview.h" + 4 #include "tfenotebook.h" + +## tfeapplication.c + + 1 #include "tfe.h" + 2 + 3 static void + 4 open_clicked (GtkWidget *btno, GtkNotebook *nb) { + 5 notebook_page_open (nb); + 6 } + 7 + 8 static void + 9 new_clicked (GtkWidget *btnn, GtkNotebook *nb) { + 10 notebook_page_new (nb); + 11 } + 12 + 13 static void + 14 save_clicked (GtkWidget *btns, GtkNotebook *nb) { + 15 notebook_page_save (nb); + 16 } + 17 + 18 static void + 19 close_clicked (GtkWidget *btnc, GtkNotebook *nb) { + 20 GtkWidget *win; + 21 GtkWidget *boxv; + 22 gint i; + 23 + 24 if (gtk_notebook_get_n_pages (nb) == 1) { + 25 boxv = gtk_widget_get_parent (GTK_WIDGET (nb)); + 26 win = gtk_widget_get_parent (boxv); + 27 gtk_window_destroy (GTK_WINDOW (win)); + 28 } else { + 29 i = gtk_notebook_get_current_page (nb); + 30 gtk_notebook_remove_page (GTK_NOTEBOOK (nb), i); + 31 } + 32 } + 33 + 34 static void + 35 tfe_activate (GApplication *application) { + 36 GtkApplication *app = GTK_APPLICATION (application); + 37 GtkWidget *win; + 38 GtkWidget *boxv; + 39 GtkNotebook *nb; + 40 + 41 win = GTK_WIDGET (gtk_application_get_active_window (app)); + 42 boxv = gtk_window_get_child (GTK_WINDOW (win)); + 43 nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv)); + 44 + 45 notebook_page_new (nb); + 46 gtk_widget_show (GTK_WIDGET (win)); + 47 } + 48 + 49 static void + 50 tfe_open (GApplication *application, GFile ** files, gint n_files, const gchar *hint) { + 51 GtkApplication *app = GTK_APPLICATION (application); + 52 GtkWidget *win; + 53 GtkWidget *boxv; + 54 GtkNotebook *nb; + 55 int i; + 56 + 57 win = GTK_WIDGET (gtk_application_get_active_window (app)); + 58 boxv = gtk_window_get_child (GTK_WINDOW (win)); + 59 nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv)); + 60 + 61 for (i = 0; i < n_files; i++) + 62 notebook_page_new_with_file (nb, files[i]); + 63 if (gtk_notebook_get_n_pages (nb) == 0) + 64 notebook_page_new (nb); + 65 gtk_widget_show (win); + 66 } + 67 + 68 + 69 static void + 70 tfe_startup (GApplication *application) { + 71 GtkApplication *app = GTK_APPLICATION (application); + 72 GtkApplicationWindow *win; + 73 GtkNotebook *nb; + 74 GtkBuilder *build; + 75 GtkButton *btno; + 76 GtkButton *btnn; + 77 GtkButton *btns; + 78 GtkButton *btnc; + 79 + 80 build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe/tfe.ui"); + 81 win = GTK_APPLICATION_WINDOW (gtk_builder_get_object (build, "win")); + 82 nb = GTK_NOTEBOOK (gtk_builder_get_object (build, "nb")); + 83 gtk_window_set_application (GTK_WINDOW (win), app); + 84 btno = GTK_BUTTON (gtk_builder_get_object (build, "btno")); + 85 btnn = GTK_BUTTON (gtk_builder_get_object (build, "btnn")); + 86 btns = GTK_BUTTON (gtk_builder_get_object (build, "btns")); + 87 btnc = GTK_BUTTON (gtk_builder_get_object (build, "btnc")); + 88 g_signal_connect (btno, "clicked", G_CALLBACK (open_clicked), nb); + 89 g_signal_connect (btnn, "clicked", G_CALLBACK (new_clicked), nb); + 90 g_signal_connect (btns, "clicked", G_CALLBACK (save_clicked), nb); + 91 g_signal_connect (btnc, "clicked", G_CALLBACK (close_clicked), nb); + 92 g_object_unref(build); + 93 + 94 GdkDisplay *display; + 95 + 96 display = gtk_widget_get_display (GTK_WIDGET (win)); + 97 GtkCssProvider *provider = gtk_css_provider_new (); + 98 gtk_css_provider_load_from_data (provider, "textview {padding: 10px; font-family: monospace; font-size: 12pt;}", -1); + 99 gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER); + 100 } + 101 + 102 int + 103 main (int argc, char **argv) { + 104 GtkApplication *app; + 105 int stat; + 106 + 107 app = gtk_application_new ("com.github.ToshioCP.tfe", G_APPLICATION_HANDLES_OPEN); + 108 + 109 g_signal_connect (app, "startup", G_CALLBACK (tfe_startup), NULL); + 110 g_signal_connect (app, "activate", G_CALLBACK (tfe_activate), NULL); + 111 g_signal_connect (app, "open", G_CALLBACK (tfe_open), NULL); + 112 + 113 stat =g_application_run (G_APPLICATION (app), argc, argv); + 114 g_object_unref (app); + 115 return stat; + 116 } + 117 + +### tfenotebook.h + + 1 void + 2 notebook_page_save(GtkNotebook *nb); + 3 + 4 void + 5 notebook_page_open (GtkNotebook *nb); + 6 + 7 void + 8 notebook_page_new_with_file (GtkNotebook *nb, GFile *file); + 9 + 10 void + 11 notebook_page_new (GtkNotebook *nb); + 12 + +## tfenotebook.c + + 1 #include "tfe.h" + 2 + 3 /* The returned string should be freed with g_free() when no longer needed. */ + 4 static gchar* + 5 get_untitled () { + 6 static int c = -1; + 7 if (++c == 0) + 8 return g_strdup_printf("Untitled"); + 9 else + 10 return g_strdup_printf ("Untitled%u", c); + 11 } + 12 + 13 static void + 14 file_changed (TfeTextView *tv, GtkNotebook *nb) { + 15 GFile *file; + 16 char *filename; + 17 GtkWidget *scr; + 18 GtkWidget *label; + 19 + 20 file = tfe_text_view_get_file (tv); + 21 scr = gtk_widget_get_parent (GTK_WIDGET (tv)); + 22 if (G_IS_FILE (file)) + 23 filename = g_file_get_basename (file); + 24 else + 25 filename = get_untitled (); + 26 label = gtk_label_new (filename); + 27 gtk_notebook_set_tab_label (nb, scr, label); + 28 g_object_unref (file); + 29 g_free (filename); + 30 } + 31 + 32 /* Save the contents in the current page */ + 33 void + 34 notebook_page_save(GtkNotebook *nb) { + 35 gint i; + 36 GtkWidget *scr; + 37 GtkWidget *tv; + 38 + 39 i = gtk_notebook_get_current_page (nb); + 40 scr = gtk_notebook_get_nth_page (nb, i); + 41 tv = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scr)); + 42 tfe_text_view_save (TFE_TEXT_VIEW (tv)); + 43 } + 44 + 45 static void + 46 notebook_page_build (GtkNotebook *nb, GtkWidget *tv, char *filename) { + 47 GtkWidget *scr; + 48 GtkNotebookPage *nbp; + 49 GtkWidget *lab; + 50 gint i; + 51 scr = gtk_scrolled_window_new (); + 52 + 53 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 54 lab = gtk_label_new (filename); + 55 i = gtk_notebook_append_page (nb, scr, lab); + 56 nbp = gtk_notebook_get_page (nb, scr); + 57 g_object_set (nbp, "tab-expand", TRUE, NULL); + 58 gtk_notebook_set_current_page (nb, i); + 59 g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb); + 60 } + 61 + 62 static void + 63 open_response (TfeTextView *tv, gint response, GtkNotebook *nb) { + 64 GFile *file; + 65 char *filename; + 66 + 67 if (response != TFE_OPEN_RESPONSE_SUCCESS) + 68 g_object_unref (tv); + 69 else if (! G_IS_FILE (file = tfe_text_view_get_file (tv))) + 70 g_object_unref (tv); + 71 else { + 72 filename = g_file_get_basename (file); + 73 g_object_unref (file); + 74 notebook_page_build (nb, GTK_WIDGET (tv), filename); + 75 } + 76 } + 77 + 78 void + 79 notebook_page_open (GtkNotebook *nb) { + 80 g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + 81 + 82 GtkWidget *tv; + 83 + 84 tv = tfe_text_view_new (); + 85 g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb); + 86 tfe_text_view_open (TFE_TEXT_VIEW (tv)); + 87 } + 88 + 89 void + 90 notebook_page_new_with_file (GtkNotebook *nb, GFile *file) { + 91 g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + 92 g_return_if_fail(G_IS_FILE (file)); + 93 + 94 GtkWidget *tv; + 95 char *filename; + 96 + 97 if ((tv = tfe_text_view_new_with_file (file)) == NULL) + 98 return; /* read error */ + 99 filename = g_file_get_basename (file); + 100 notebook_page_build (nb, tv, filename); + 101 } + 102 + 103 void + 104 notebook_page_new (GtkNotebook *nb) { + 105 g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + 106 + 107 GtkWidget *tv; + 108 char *filename; + 109 + 110 tv = tfe_text_view_new (); + 111 filename = get_untitled (); + 112 notebook_page_build (nb, tv, filename); + 113 } + 114 + +## tfetextview.h + + 1 #define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () + 2 G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + 3 + 4 /* "open-response" signal response */ + 5 enum + 6 { + 7 TFE_OPEN_RESPONSE_SUCCESS, + 8 TFE_OPEN_RESPONSE_CANCEL, + 9 TFE_OPEN_RESPONSE_ERROR + 10 }; + 11 + 12 GFile * + 13 tfe_text_view_get_file (TfeTextView *tv); + 14 + 15 void + 16 tfe_text_view_open (TfeTextView *tv); + 17 + 18 void + 19 tfe_text_view_save (TfeTextView *tv); + 20 + 21 void + 22 tfe_text_view_saveas (TfeTextView *tv); + 23 + 24 GtkWidget * + 25 tfe_text_view_new_with_file (GFile *file); + 26 + 27 GtkWidget * + 28 tfe_text_view_new (void); + 29 + +## tfetextview.c + + 1 #include "tfe.h" + 2 + 3 struct _TfeTextView + 4 { + 5 GtkTextView parent; + 6 GtkTextBuffer *tb; + 7 GFile *file; + 8 gboolean changed; + 9 }; + 10 + 11 G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + 12 + 13 enum { + 14 CHANGE_FILE, + 15 OPEN_RESPONSE, + 16 NUMBER_OF_SIGNALS + 17 }; + 18 + 19 static guint tfe_text_view_signals[NUMBER_OF_SIGNALS]; + 20 + 21 /* Signal handler */ + 22 static void + 23 on_changed (GtkTextBuffer *tb, TfeTextView *tv) { + 24 tv->changed=TRUE; + 25 } + 26 + 27 static void + 28 tfe_text_view_dispose (GObject *gobject) { + 29 TfeTextView *tv = TFE_TEXT_VIEW (gobject); + 30 + 31 if (G_IS_FILE (tv->file)) + 32 g_clear_object (&tv->file); + 33 + 34 G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject); + 35 } + 36 + 37 static void + 38 tfe_text_view_init (TfeTextView *tv) { + 39 tv->tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 40 tv->file = NULL; + 41 tv->changed = FALSE; + 42 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 43 g_signal_connect (tv->tb, "changed", G_CALLBACK (on_changed), tv); + 44 } + 45 + 46 static void + 47 tfe_text_view_class_init (TfeTextViewClass *class) { + 48 GObjectClass *object_class = G_OBJECT_CLASS (class); + 49 + 50 object_class->dispose = tfe_text_view_dispose; + 51 tfe_text_view_signals[CHANGE_FILE] = g_signal_newv ("change-file", + 52 G_TYPE_FROM_CLASS (class), + 53 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 54 NULL /* closure */, + 55 NULL /* accumulator */, + 56 NULL /* accumulator data */, + 57 NULL /* C marshaller */, + 58 G_TYPE_NONE /* return_type */, + 59 0 /* n_params */, + 60 NULL /* param_types */); + 61 GType param_types[] = {G_TYPE_INT}; + 62 tfe_text_view_signals[OPEN_RESPONSE] = g_signal_newv ("open-response", + 63 G_TYPE_FROM_CLASS (class), + 64 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 65 NULL /* closure */, + 66 NULL /* accumulator */, + 67 NULL /* accumulator data */, + 68 NULL /* C marshaller */, + 69 G_TYPE_NONE /* return_type */, + 70 1 /* n_params */, + 71 param_types); + 72 } + 73 + 74 GFile * + 75 tfe_text_view_get_file (TfeTextView *tv) { + 76 g_return_val_if_fail (TFE_IS_TEXT_VIEW (tv), NULL); + 77 + 78 return g_file_dup (tv->file); + 79 } + 80 + 81 static void + 82 open_dialog_response(GtkWidget *dialog, gint response, TfeTextView *tv) { + 83 GFile *file; + 84 char *contents; + 85 gsize length; + 86 GtkWidget *message_dialog; + 87 GError *err = NULL; + 88 + 89 if (response != GTK_RESPONSE_ACCEPT) + 90 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL); + 91 else if (! G_IS_FILE (file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)))) + 92 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + 93 else if (! g_file_load_contents (file, NULL, &contents, &length, NULL, &err)) { /* read error */ + 94 if (G_IS_FILE (file)) + 95 g_object_unref (file); + 96 message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_MODAL, + 97 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + 98 "%s.\n", err->message); + 99 g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL); + 100 gtk_widget_show (message_dialog); + 101 g_error_free (err); + 102 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + 103 } else { + 104 gtk_text_buffer_set_text (tv->tb, contents, length); + 105 g_free (contents); + 106 tv->file = file; + 107 /* tv->changed = FALSE;*/ + 108 g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS); + 109 } + 110 gtk_window_destroy (GTK_WINDOW (dialog)); + 111 } + 112 + 113 void + 114 tfe_text_view_open (TfeTextView *tv) { + 115 g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + 116 + 117 GtkWidget *dialog; + 118 + 119 dialog = gtk_file_chooser_dialog_new ("Open file", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, + 120 "Cancel", GTK_RESPONSE_CANCEL, + 121 "Open", GTK_RESPONSE_ACCEPT, + 122 NULL); + 123 g_signal_connect (dialog, "response", G_CALLBACK (open_dialog_response), tv); + 124 gtk_widget_show (dialog); + 125 } + 126 + 127 static void + 128 saveas_dialog_response (GtkWidget *dialog, gint response, TfeTextView *tv) { + 129 GFile *file; + 130 + 131 if (response == GTK_RESPONSE_ACCEPT) { + 132 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); + 133 if (G_IS_FILE(file)) { + 134 tv->file = file; + 135 tv->changed = TRUE; + 136 g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + 137 tfe_text_view_save (TFE_TEXT_VIEW (tv)); + 138 } + 139 } + 140 gtk_window_destroy (GTK_WINDOW (dialog)); + 141 } + 142 + 143 void + 144 tfe_text_view_save (TfeTextView *tv) { + 145 g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + 146 + 147 GtkTextIter start_iter; + 148 GtkTextIter end_iter; + 149 gchar *contents; + 150 GtkWidget *message_dialog; + 151 GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW); + 152 GError *err = NULL; + 153 + 154 if (! tv->changed) + 155 return; /* no necessary to save it */ + 156 else if (tv->file == NULL) + 157 tfe_text_view_saveas (tv); + 158 else { + 159 gtk_text_buffer_get_bounds (tv->tb, &start_iter, &end_iter); + 160 contents = gtk_text_buffer_get_text (tv->tb, &start_iter, &end_iter, FALSE); + 161 if (g_file_replace_contents (tv->file, contents, strlen (contents), NULL, TRUE, G_FILE_CREATE_NONE, NULL, NULL, &err)) + 162 tv->changed = FALSE; + 163 else { + 164 /* It is possible that tv->file is broken. */ + 165 /* It is a good idea to set tv->file to NULL. */ + 166 if (G_IS_FILE (tv->file)) + 167 g_object_unref (tv->file); + 168 tv->file =NULL; + 169 g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + 170 tv->changed = TRUE; + 171 message_dialog = gtk_message_dialog_new (GTK_WINDOW (win), GTK_DIALOG_MODAL, + 172 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + 173 "%s.\n", err->message); + 174 g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL); + 175 gtk_widget_show (message_dialog); + 176 g_error_free (err); + 177 } + 178 } + 179 } + 180 + 181 void + 182 tfe_text_view_saveas (TfeTextView *tv) { + 183 g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + 184 + 185 GtkWidget *dialog; + 186 GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW); + 187 + 188 dialog = gtk_file_chooser_dialog_new ("Save file", GTK_WINDOW (win), GTK_FILE_CHOOSER_ACTION_SAVE, + 189 "_Cancel", GTK_RESPONSE_CANCEL, + 190 "_Save", GTK_RESPONSE_ACCEPT, + 191 NULL); + 192 g_signal_connect (dialog, "response", G_CALLBACK (saveas_dialog_response), tv); + 193 gtk_widget_show (dialog); + 194 } + 195 + 196 GtkWidget * + 197 tfe_text_view_new_with_file (GFile *file) { + 198 g_return_val_if_fail (G_IS_FILE (file), NULL); + 199 + 200 GtkWidget *tv; + 201 char *contents; + 202 gsize length; + 203 + 204 if (! g_file_load_contents (file, NULL, &contents, &length, NULL, NULL)) /* read error */ + 205 return NULL; + 206 + 207 tv = tfe_text_view_new(); + 208 gtk_text_buffer_set_text (TFE_TEXT_VIEW (tv)->tb, contents, length); + 209 g_free (contents); + 210 TFE_TEXT_VIEW (tv)->file = g_file_dup (file); + 211 return tv; + 212 } + 213 + 214 GtkWidget * + 215 tfe_text_view_new (void) { + 216 return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + 217 } + 218 + +## Total number of lines, words and charcters + + $ wc tfe5/meson.build tfe5/tfeapplication.c tfe5/tfe.gresource.xml tfe5/tfe.h tfe5/tfenotebook.c tfe5/tfenotebook.h tfe5/tfetextview.c tfe5/tfetextview.h tfe5/tfe.ui + 10 17 279 tfe5/meson.build + 117 348 3576 tfe5/tfeapplication.c + 6 9 153 tfe5/tfe.gresource.xml + 4 6 72 tfe5/tfe.h + 114 311 2870 tfe5/tfenotebook.c + 12 17 196 tfe5/tfenotebook.h + 218 622 7454 tfe5/tfetextview.c + 29 47 545 tfe5/tfetextview.h + 64 105 2266 tfe5/tfe.ui + 574 1482 17411 合計 +Up: [Readme.md](src/Readme.md), Prev: [Section 12}](src/sec12.src.md), Next: [Section 14[(src/sec14.src.md) \ No newline at end of file diff --git a/sec14.md b/sec14.md new file mode 100644 index 0000000..2d6c08f --- /dev/null +++ b/sec14.md @@ -0,0 +1,215 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 13}](src/sec13.src.md), Next: [Section 15[(src/sec15.src.md)# Menu and action + +## Menu + +Users often use menus to tell the command to the computer. +It is like this: + +![Menu](menu.png) + +Now let's analyze the menu above. +There are two types of object. + +- "File", "Edit", "View", "Cut", "Copy", "Paste" and "Select All". +They are called "menu item" or simply "item". +When the user clicks one of these items, then something will happen. +- Menubar, submenu referenced by "Edit" item and two sections. +They are called "menu". +Menu is an ordered list of items. +They are similar to arrays. + +![Menu structure](menu_structure.png) + +- Menubar is a menu which has three items, which are "File", "Edit" and "View". +- The menu item labeled "Edit" has a link to the submenu which has two items. +These two items don't have labels. +Each item refers to a section. +- The first section is a menu which has three items -- "Cut", "Copy" and "Paste". +- The second section is a menu which has one item -- "Select All". + +Menus can build a complicated structure thanks to the links of menu items. + +## GMenuModel, GMenu and GMenuItem + +GMenuModel is an abstact object which represents a menu. +GMenu is a simple implementation of GMenuModel and a child object of GMenuModel. + + GObjct -- GMenuModel -- GMenu + +Because GMenuModel is an abstract object, it doesn't have any functions to generate it. +Therefore, if you want to generate a menu, use `g_menu_new` function to generate GMenu object. +GMenu inherits all the functions of GMenuModel because of the child object. + +GMenuItem is an object directly derived from GObject. +GMenuItem and Gmenu (or GMenuModel) don't have a parent-child relationship. + + GObject -- GMenuModel -- GMenu + GObject -- GMenuItem + +Usually, GMenuItem has attributes. +One of the attributes is label. +For example, there is a menu item which has "Edit" label in the first diagram in this section. +"Cut", "Copy", "Paste" and "Select All" are also the lables of menu items. +Other attributes will be explained later. + +Some menu items have a link to another GMenu. +There are two types of links, submenu and section. + +GMenuItem can be inserted, appended or prepended to GMenu. +When it is inserted, all of the attribute and link values of the item are copied and used to form a new item within the menu. +The GMenuItem itself is not really inserted. +Therefore, after the insertion, GMenuItem is useless and it should be freed. +The same goes for appending or prepending. + +The following code shows how to append GMenuItem to GMenu. + + GMenu *menu = g_menu_new (); + GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + g_menu_append_item (menu, menu_item_quit); + g_object_unref (menu_item_quit); + +## Menu and action + +One of the attributes of menu items is an action. +This attribute points an action object. + +There are two action objects, GSimpleAction and GPropertyAction. +GSimpleAction is often used. +And it is used with a menu item. +Only GSimpleAction is described in this section. + +An action corresponds to a menu item will be activated when the menu item is clicked. +Then the action emits an activate signal. + +1. menu item is clicked. +2. The corresponding action is activated. +3. The action emits a signal. +4. The connected handler is invoked. + + +The following code is an example. + + static void + quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app) { ... ... ...} + + GSimpleAction *act_quit = g_simple_action_new ("quit", NULL); + g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), app); + GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + +1. `menu_item_quit` is a menu item. +It has a label "Quit" and is connected to an action "app.quit". +"app" is a prefix and "quit" is the name of an action. +The prefix means that the action belongs to GtkApplication. +If the menu is clicked, then the corresponding action "quit" which belongs to GtkApplication will be activated. +2. `act_quit` is an action. +It has a name "quit". +It belongs to GtkApplication, but it is not obvious in the code above. +The function `g_simple_action_new` generates a stateless action. +So, `act_quit` is stateless. +The meaning of stateless will be explained later. +The argument `NULL` means that the action doesn't have an parameter. +Generally, most of the actions are stateless and have no parameter. +When `act_quit` is activated, it will emit "activate" signal. +3. "activate" signal of the action is connected to the handler `quit_activated`. +So, if the action is activated, the handler will be invoked. + +## Simple example + +The following is a simple example of menus and actions. + + 1 #include + 2 + 3 static void + 4 quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app) + 5 { + 6 g_application_quit (G_APPLICATION(app)); + 7 } + 8 + 9 static void + 10 on_activate (GApplication *app, gpointer user_data) { + 11 GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + 12 gtk_window_set_title (GTK_WINDOW (win), "menu1"); + 13 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 14 + 15 GSimpleAction *act_quit = g_simple_action_new ("quit", NULL); + 16 g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit)); + 17 g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), app); + 18 + 19 GMenu *menubar = g_menu_new (); + 20 GMenuItem *menu_item_menu = g_menu_item_new ("Menu", NULL); + 21 GMenu *menu = g_menu_new (); + 22 GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + 23 g_menu_append_item (menu, menu_item_quit); + 24 g_object_unref (menu_item_quit); + 25 g_menu_item_set_submenu (menu_item_menu, G_MENU_MODEL (menu)); + 26 g_menu_append_item (menubar, menu_item_menu); + 27 g_object_unref (menu_item_menu); + 28 + 29 gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar)); + 30 gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE); + 31 gtk_window_present (GTK_WINDOW (win)); + 32 /* gtk_widget_show (win); is also OKay instead of gtk_window_present. */ + 33 } + 34 + 35 int + 36 main (int argc, char **argv) { + 37 GtkApplication *app; + 38 int stat; + 39 + 40 app = gtk_application_new ("com.github.ToshioCP.menu1", G_APPLICATION_FLAGS_NONE); + 41 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 42 + 43 stat =g_application_run (G_APPLICATION (app), argc, argv); + 44 g_object_unref (app); + 45 return stat; + 46 } + 47 + +- 3-7: `quit_activated` is a handler of an action `act_quit`. +Handlers of actions have three parameters. + 1. The action object which has emitted the signal. + 2. Parameter. +In this example it is `NULL` because the second argument of `g_simple_action_new` (line 15) is `NULL`. +You don' t need to care about it. + 3. User data. +It is the fourth parameter in the `g_signal_connect` (line 17) that has connected the action and the handler. +- 6: A function `g_application_quit` immediately quits the application. +- 9-33: `on_activate` is a handler of "activate" signal on GtkApplication. +- 11-13: Generate a GtkApplicationWindow and set a pointer to it to `win`. And set the title and default size. +- 15: Generate GSimpleAction `act_quit`. +It is stateless. +The first argument of `g_simple_action_new` is a name of the action and the second argument is a parameter. +If you don't need the parameter, set it `NULL`. +THerefore, `act_quit` has a name "quit" and no parameter. +- 16: Add the action to GtkApplication `app`. +GtkApplication implements an interface GActionMap and GActionGroup. +And GtkApplication can have a group of actions and actions are added by the function `g_action_map_add_action`. +This function is described in GMenuModel section in GIO API reference. +- 17: Connect "activate" signal of the action and the handler `quit_activated`. +- 19-22: Generate GMenu and GMenuItem. +`menubar` and `menu` are GMenu. +`menu_item_menu` and `menu_item_quit` are GMenuItem. +`menu_item_menu` has a label "Menu" and no action. +`menu_item_quit` has a label "Quit". +The second argument "app.quit" is a combination of "app" and "quit". +"app" is a prefix and it means that the action belongs to GtkApplication. "quit" is the name of the action. +Therefore, it points the action which belongs to GtkApplication and has the name "quit" -- it is `act_quit`. +- 23-24: Append `act_quit` to `menu`. +As I mentioned before, all the attribute and link values are copied and used to form a new item within `menu`. +Therefore after the appending, `menu` has a copy of `act_quit` in itself and `act_quit` is no longer needed. +It is freed by `g_object_unref`. +- 25: Set a submenu link to `menu_item_menu`. +And the link points the GMenu `menu`. +- 26-27: Append `menu_item_menu` to `menubar`. +Then free `menu_item_menu`. +GMenu and GMenuItem are connected and finally a menu is made up. +The structure of the menu is shown in the diagram below. +- 29: The menu is set to GtkApplication. +- 30: Set GtkApplicationWindow to show the menubar. +- 31: Show the window. + +![menu and action](menu1.png) + +![Screenshot of menu1](menu1_screenshot.png) + +Up: [Readme.md](src/Readme.md), Prev: [Section 13}](src/sec13.src.md), Next: [Section 15[(src/sec15.src.md) \ No newline at end of file diff --git a/sec15.md b/sec15.md new file mode 100644 index 0000000..d72d6b3 --- /dev/null +++ b/sec15.md @@ -0,0 +1,369 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 14}](src/sec14.src.md), Next: [Section 16[(src/sec16.src.md)# Stateful action + +Some actions have states. +The values of states can be boolean or string. +Actions which have states are called stateful. + +## Stateful action without a parameter + +Some menus are called toggle menu. +For example, fullscreen menu has a state which has two values -- fullscreen and non-fullscreen. +The value of the state is changed every time the menu is clicked. +An action corresponds to the fullscreen menu also have a state. +Its value is TRUE or FALSE and it is called boolean value. +TRUE corresponds to fullscreen and FALSE to non-fullscreen. + +The following is an example code to implement a fullscreen menu except the signal handler. +The signal handler will be described after the explanation of this code. + + static void + on_activate (GApplication *app, gpointer user_data) { + ... ... ... + GSimpleAction *act_fullscreen = g_simple_action_new_stateful ("fullscreen", NULL, g_variant_new_boolean (FALSE)); + GMenuItem *menu_item_fullscreen = g_menu_item_new ("Full Screen", "win.fullscreen"); + g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win); + ... ... ... + } + +- `act_fullscreen` is GSimpleAction. +It is generated by `g_simple_action_new_stateful`. +The function has three arguments. +The first argument "fullscreen" is the name of the action. +The second argument is a parameter type. +`NULL` means the action doesn't have a parameter. +The third argument is the initial state of the action. +It is a GVariant value. +GVariant will be explained in the next subsection. +The function `g_variant_new_boolean (FALSE)` returns a GVariant value which is the boolean value `FALSE`. +- `menu_item_fullscreen` is GMenuItem. +There are two arguments. +The first argument "Full Screen" is a label which is one of the attributes of GMenuItem. +The second argument is called detailed action. +Detailed action has three parts, prefix, action name and target. +"win.fullscreen" means that the prefix is "win", the action name is "fullscreen" and there's no target. +The prefix says that the action belongs to the window. +- connect the action `act_fullscreen` and the "change-state" signal handler `fullscreen_`value2`changed`. +If the fullscreen menu is clicked, then the corresponding action `act_fullscreen` is activated. +But no handler is connected to "activate" signal. +Then, the default behaviour for boolean-stated actions with a NULL parameter type like `act_fullscreen` is to toggle them via the “change-state” signal. + +The following is the "change-state" signal handler. + + static void + fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) { + if (g_variant_get_boolean (value)) + gtk_window_maximize (GTK_WINDOW (win)); + else + gtk_window_unmaximize (GTK_WINDOW (win)); + g_simple_action_set_state (action, value); + } + +- There are three parameters. +The first parameter is the action which emits the "change-state" signal. +The second parameter is the value of the state of the action. +But it is toggled because of no "activate" signal handler. +Ther third parameter is a user data which is set in `g_signal_connect`. +- If the value is boolean type and `TRUE`, then maximize the window. +Otherwise unmaximize. +- Set `value` to the state of the action. +Note: the second argument was the toggled state value, but at this stage the state of the action has the original value. +So, you need to set the new value by `g_simple_action_set_state`. + +You can use "activate" signal instead ot "change-state" signal, or both signals. +But the way above is the simplest and best. + +### GVariant + +GVarient can contain boolean, string or other simple type values. +For example, the following program set TRUE to `value` whose type is GVariant. + + GVariant *value = g_variant_new_boolean (TRUE); + +Another example is: + + GVariant *value2 = g_variant_new_string ("Hello"); + +`value2` is a GVariant and it has a string type value "Hello". +GVariant can contain other types like int16, int32, int64, double and so on. + +If you want to get the boolean value, use g\_variant\_get series functions. + + gboolean bool = g_variant_get_boolean (value); + +Because `value` has been generated as a boolean type GVariant and `TRUE` value, `bool` equals `TRUE`. +In the same way, you can get a string from `value2` + + const gchar *str = g_variant_get_string (value2, NULL); + +The second parameter is a pointer to gsize type variable (gsize is defined as unsigned long). +If it isn't NULL, then the length of the string will be set by the function. +If it is NULL, nothing happens. +The returned string `str` can't be changed. + +## Stateful action with a parameter + +Another example of stateful actions is an action corresponds to color select menus. +For example, there are three menus and each menu has red, green or blue color respectively. +They determine the background color of a certain widget. +One action is connected to the three menus. +The action has a state which values are "red", "green" and "blue". +The values are string. +Those colors are given to the signal handler as a parameter. + + static void + on_activate (GApplication *app, gpointer user_data) { + ... ... ... + GSimpleAction *act_color = g_simple_action_new_stateful ("color", g_variant_type_new("s"), g_variant_new_string ("red")); + GMenuItem *menu_item_red = g_menu_item_new ("Red", "win.color::red"); + GMenuItem *menu_item_green = g_menu_item_new ("Green", "win.color::green"); + GMenuItem *menu_item_blue = g_menu_item_new ("Blue", "win.color::blue"); + g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win); + ... ... ... + } + +- `act_color` is GSimpleAction. +It is generated by `g_simple_action_new_stateful`. +The function has three arguments. +The first argument "color" is the name of the action. +The second argument is a parameter type which is GVariantType. +`g_variant_type_new("s")` generates GVariantType which is a string type (G\_VARIANT\_TYPE\_STRING). +The third argument is the initial state of the action. +It is a GVariant. +GVariantType will be explained in the next subsection. +The function `g_variant_new_string ("red")` returns a GVariant value which has the string value "red". +- `menu_item_red` is GMenuItem. +There are two arguments. +The first argument "Red" is a label which is one of the attributes of GMenuItem. +The second argument is a detailed action. +Its prefix is "win", action name is "color" and target is "red". +Target is sent to the action as a parameter. +The same goes for `menu_item_green` and `menu_item_blue`. +- connect the action `act_color` and the "activate" signal handler `color_activate`. +If one of the three menus is clicked, then the action `act_color` is activated with a parameter to which the menu item gives its target. +No handler is connected to "change-state" signal. +Then the default behaviour is to call `g_simple_action_set_state()` to set the state to the requested value. + +The following is the "activate" signal handler. + + static void + color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) { + gchar *color = g_strdup_printf ("label#lb {background-color: %s;}", g_variant_get_string (parameter, NULL)); + gtk_css_provider_load_from_data (provider, color, -1); + g_free (color); + g_action_change_state (G_ACTION (action), parameter); + } + +- There are three parameters. +The first parameter is the action which emits the "activate" signal. +The second parameter is the parameter given to the action. +It is a color specified by the menu. +The third parameter is a user data which is set in `g_signal_connect`. +- `color` is a CSS string generated by `g_strdup_printf`. +The parameter of `g_str_dup` is the same as printf C standard function. +`g_variant_get_string` get the string contained in `parameter`. +- Set the color to the css provider. +- Free the string `color`. +- Change the state by `g_action_change_state`. +The function just set the parameter to the state of the action by `g_simple_action_set_state`. +Therefore, you can use `g_simple_action_set_state` instead of `g_action_change_state`. + +Note: If you have set a "change-state" signal handler, `g_action_change_state` will emit "change-state" signal instead of calling `g_simple_action_set_state`. + +### GVariantType + +GVariantType gives a type of GVariant. +GVariant can contain many kinds of types. +And the type often needs to be recognized at runtime. +GVariantType provides such functionality. + +When GVariantType is generated, the type is expressed by the string. + +- "b" means boolean type. +- "s" means string type. + +The following program is a simple example. +It finally output the string "s". + + 1 #include + 2 + 3 int + 4 main (int argc, char **argv) { + 5 GVariantType *vtype = g_variant_type_new ("s"); + 6 const gchar *type_string = g_variant_type_peek_string (vtype); + 7 g_print ("%s\n",type_string); + 8 } + +- `g_variant_tpe_new` generates GVariantType. +It uses a type string "s" which means string. +- `g_variant_type_peek_string` takes a peek at `vtype`. +It is the string "s" given at the generation time. +- print the string to the terminal. + +## Example code +The following code includes stateful actions above. +This program has menus like this: + +![menu2](menu2.png) + +- Fullscreen menu toggles the size of the window between maximum and non-maximum. +If the window is maximum size, which is called full screen, then a check mark is put before "fullscreen" label. +- Red, green and blue menu determines the back ground color of the label, which is the child widget of the window. +The menus have radio buttons on the left of each of the menus. +And the radio button of the selected menu turns on. +- Quit menu quits the application. + +The code is as follows. + + 1 #include + 2 + 3 static GtkCssProvider *provider; + 4 + 5 static void + 6 fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) { + 7 if (g_variant_get_boolean (value)) + 8 gtk_window_maximize (GTK_WINDOW (win)); + 9 else + 10 gtk_window_unmaximize (GTK_WINDOW (win)); + 11 g_simple_action_set_state (action, value); + 12 } + 13 + 14 static void + 15 color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) { + 16 gchar *color = g_strdup_printf ("label#lb {background-color: %s;}", g_variant_get_string (parameter, NULL)); + 17 gtk_css_provider_load_from_data (provider, color, -1); + 18 g_free (color); + 19 g_action_change_state (G_ACTION (action), parameter); + 20 } + 21 + 22 static void + 23 quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app) + 24 { + 25 g_application_quit (G_APPLICATION(app)); + 26 } + 27 + 28 static void + 29 on_activate (GApplication *app, gpointer user_data) { + 30 GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + 31 gtk_window_set_title (GTK_WINDOW (win), "menu2"); + 32 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 33 + 34 GtkWidget *lb = gtk_label_new (NULL); + 35 gtk_widget_set_name (lb, "lb"); /* the name is used by CSS Selector */ + 36 gtk_window_set_child (GTK_WINDOW (win), lb); + 37 + 38 GSimpleAction *act_fullscreen + 39 = g_simple_action_new_stateful ("fullscreen", NULL, g_variant_new_boolean (FALSE)); + 40 GSimpleAction *act_color + 41 = g_simple_action_new_stateful ("color", g_variant_type_new("s"), g_variant_new_string ("red")); + 42 GSimpleAction *act_quit + 43 = g_simple_action_new ("quit", NULL); + 44 + 45 GMenu *menubar = g_menu_new (); + 46 GMenu *menu = g_menu_new (); + 47 GMenu *section1 = g_menu_new (); + 48 GMenu *section2 = g_menu_new (); + 49 GMenu *section3 = g_menu_new (); + 50 GMenuItem *menu_item_fullscreen = g_menu_item_new ("Full Screen", "win.fullscreen"); + 51 GMenuItem *menu_item_red = g_menu_item_new ("Red", "win.color::red"); + 52 GMenuItem *menu_item_green = g_menu_item_new ("Green", "win.color::green"); + 53 GMenuItem *menu_item_blue = g_menu_item_new ("Blue", "win.color::blue"); + 54 GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + 55 + 56 g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win); + 57 g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win); + 58 g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), app); + 59 g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_fullscreen)); + 60 g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_color)); + 61 g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit)); + 62 + 63 g_menu_append_item (section1, menu_item_fullscreen); + 64 g_menu_append_item (section2, menu_item_red); + 65 g_menu_append_item (section2, menu_item_green); + 66 g_menu_append_item (section2, menu_item_blue); + 67 g_menu_append_item (section3, menu_item_quit); + 68 g_object_unref (menu_item_red); + 69 g_object_unref (menu_item_green); + 70 g_object_unref (menu_item_blue); + 71 g_object_unref (menu_item_fullscreen); + 72 g_object_unref (menu_item_quit); + 73 + 74 g_menu_append_section (menu, NULL, G_MENU_MODEL (section1)); + 75 g_menu_append_section (menu, "Color", G_MENU_MODEL (section2)); + 76 g_menu_append_section (menu, NULL, G_MENU_MODEL (section3)); + 77 g_menu_append_submenu (menubar, "Menu", G_MENU_MODEL (menu)); + 78 + 79 gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar)); + 80 gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE); + 81 + 82 /* GtkCssProvider *provider = gtk_css_provider_new ();*/ + 83 provider = gtk_css_provider_new (); + 84 GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (win)); + 85 gtk_css_provider_load_from_data (provider, "label#lb {background-color: red;}", -1); + 86 gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider), + 87 GTK_STYLE_PROVIDER_PRIORITY_USER); + 88 + 89 /* gtk_widget_show (win);*/ + 90 gtk_window_present (GTK_WINDOW (win)); + 91 } + 92 + 93 int + 94 main (int argc, char **argv) { + 95 GtkApplication *app; + 96 int stat; + 97 + 98 app = gtk_application_new ("com.github.ToshioCP.menu2", G_APPLICATION_FLAGS_NONE); + 99 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 100 + 101 stat =g_application_run (G_APPLICATION (app), argc, argv); + 102 g_object_unref (app); + 103 return stat; + 104 } + 105 + +- 5-26: Signal handlers. +They have been explained in this section. +- 30-36: `win` and `lb` are GtkApplicationWindow and GtkLabel respectively. +`win` has a title "menu2" and its defaust size is 400x300. +`lb` is named as "lb". +The name is used in CSS. +`lb` is set to `win` as a child. +- 38-43: Three actions are defined. +They are: + - stateful and has no parameter. +It has a toggle state. + - stateful and has a parameter. +Parameter is a string type. + - stateless and has no parameter. +- 45-54: Generate GMenu and GMenuItem. +There are three sections. +- 56-61: Signals are connected to handlers. +And actions are added to GActionMap. +Because `act_fullscreen` and `act_color` have "win" prefix and belong to GtkApplicationWindow, +they are added to `win`. +GtkApplicationWindow implements GActionModel interface like GtkApplication. +`act_quit` has "app" prefix and belongs to GtkApplication, +it is added to `app`. +- 63-77: Connect and build the menus. +Useless GMenuItem are freed. +- 79-80: GMenuModel `menubar` is set to `app`. +Set show menubar property to `TRUE` in `win`. +Note: `gtk_application_window_set_show_menubar` generates GtkPopoverMenubar from GMenuModel. +This is a different point between Gtk3 and Gtk4. +And you can use GtkPopoverMenubar directly and set it as a descendant widget of the window. +You may use GtkBox as a child widget of the window and set GtkPopoverMenubar as the first child of the box. +- 82-87: Set CSS. +`provider` is GtkCssProvider which is defined in line three as a static variable. +Its CSS data is: +`label#lb {background-color: red;}`. +"label#lb" is called selector. +"label" is the node of GtkLabel. +"#" precedes an ID which is an identiable name of the widget. +"lb" is the name of GtkLabel `lb`. +(See line 35). +The style is surrounded by open and close braces. +The style is applied to GtkLabel which has a name "lb". +Other GtkLabel have no effect from this. +The provider is added to GdkDisplay. +- 90: Show the window. + +Up: [Readme.md](src/Readme.md), Prev: [Section 14}](src/sec14.src.md), Next: [Section 16[(src/sec16.src.md) \ No newline at end of file diff --git a/sec16.md b/sec16.md new file mode 100644 index 0000000..4e94dd6 --- /dev/null +++ b/sec16.md @@ -0,0 +1,336 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 15}](src/sec15.src.md), Next: [Section 17[(src/sec17.src.md)# Ui file for menu and action entries + +## Ui file for menu + +You might have thought that building menus is really bothersome. +Yes, the program was complicated and it needs lots of time to code it. +The situation is similar to building widgets. +When we built widgets, using ui file was a good way to avoid such complicated coding. +The same goes for menus. + +The ui file for menus has interface, menu tags. +The file starts and ends with interface tag. + + +

+ + + +`menu` tag corresponds to GMenu object. +`id` attribute defines the name of the object. +It will be refered by GtkBuilder. + + + File + + New + win.new + + + +`item` tag corresponds to item in GMenu which has the same structure as GMenuItem. +The item above has a label attribute. +Its value is "New". +The item also has an action attribute and its value is "win.new". +"win" is a prefix and "new" is an action name. +`submenu` tag corresponds to both GMenuItem and GMenu. +The GMenuItem has a link to GMenu. + +The ui file above can be described as follows. + + + File + + + New + win.new + + + + +`link` tag expresses the link to submenu. +And at the same time it also expresses the submenu itself. +This file illustrates the relationship between the menus and items better than the prior ui file. +But `submenu` tag is simple and easy to understand. +So, we usually prefer the former ui file style. + +The following is a screenshot of the sample program in this section. +Its name is `menu3`. + +![menu3](menu3.png) + +The following is the ui file of the menu in `menu3`. + + 1 + 2 + 3 + 4 + 5 File + 6
+ 7 + 8 New + 9 win.new + 10 + 11 + 12 Open + 13 win.open + 14 + 15
+ 16
+ 17 + 18 Save + 19 win.save + 20 + 21 + 22 Save As… + 23 win.saveas + 24 + 25
+ 26
+ 27 + 28 Close + 29 win.close + 30 + 31
+ 32
+ 33 + 34 Quit + 35 app.quit + 36 + 37
+ 38
+ 39 + 40 Edit + 41
+ 42 + 43 Cut + 44 win.cut + 45 + 46 + 47 Copy + 48 win.copy + 49 + 50 + 51 Paste + 52 win.paste + 53 + 54
+ 55
+ 56 + 57 Select All + 58 win.selectall + 59 + 60
+ 61
+ 62 + 63 View + 64
+ 65 + 66 Full Screen + 67 win.fullscreen + 68 + 69
+ 70
+ 71
+ 72
+ +The ui file is converted to the resource by the resouce compiler `glib-compile-resouces` with xml file below. + + 1 + 2 + 3 + 4 menu3.ui + 5 + 6 + +GtkBuilder builds menus from the resource. + + GtkBuilder *builder = gtk_builder_new_from_resource ("/com/github/ToshioCP/menu3/menu3.ui"); + GMenuModel *menubar = G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")); + + gtk_application_set_menubar (GTK_APPLICATION (app), menubar); + g_object_unref (builder); + +It is important that `builder` is unreferred after the GMenuModel `menubar` is set to the application. +If you do it before setting, bad thing will happen -- your computer might freeze. + +## Action entry + +The coding for building actions and signal handlers is always the same. +Therefore, it can be automated. +You can implement them easily with GActionEntry `g_action_map_add_action_entries`. + +GActionEntry is a strutcure. +It contains action name, signal handlers, parameter and state. + + typedef struct _GActionEntry GActionEntry; + + struct _GActionEntry + { + const gchar *name; /* action name */ + void (* activate) (GSimpleAction *action, GVariant *parameter, gpointer user_data); /* activate handler */ + const gchar *parameter_type; /* the type of the parameter given as a single GVariant type string */ + const gchar *state; /* initial state given in GVariant text format */ + void (* change_state) (GSimpleAction *action, GVariant *value, gpointer user_data); /* change-state handler */ + /*< private >*/ + gsize padding[3]; + }; + +For example, the actions in the previous section are: + + { "fullscreen", NULL, NULL, "false", fullscreen_changed } + { "color", color_activated, "s", "red", NULL } + { "quit", quit_activated, NULL, NULL, NULL }, + +And `g_action_map_add_action_entries` does all the process instead of the functions you have needed. + + const GActionEntry app_entries[] = { + { "quit", quit_activated, NULL, NULL, NULL } + }; + g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, G_N_ELEMENTS (app_entries), app); + +The code above does: + +- Build the "quit" action +- Connect the action and the "activate" signal handler `quit_activate` +- Add the action to the action map `app`. + + const GActionEntry win_entries[] = { + { "fullscreen", NULL, NULL, "false", fullscreen_changed }, + { "color", color_activated, "s", "red", NULL } + }; + g_action_map_add_action_entries (G_ACTION_MAP (win), win_entries, G_N_ELEMENTS (win_entries), win); + +The code above does: + +- Build the "fullscreen" action and "color" action. +- Connect the "fullscreen" action and the "change-state" signal handler `fullscreen_changed` +- Its initial state is set to FALSE. +- Connect the "color" action and the "activate" signal handler `color_activate` +- Its parameter type is string and the initial value is "red". +- Add the action to the action map `win`. + +## Example code + +The C source code of `menu3` and `meson.build` is as follows. + + 1 #include + 2 + 3 static void + 4 new_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 5 } + 6 + 7 static void + 8 open_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 9 } + 10 + 11 static void + 12 save_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 13 } + 14 + 15 static void + 16 saveas_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 17 } + 18 + 19 static void + 20 close_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 21 } + 22 + 23 static void + 24 cut_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 25 } + 26 + 27 static void + 28 copy_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 29 } + 30 + 31 static void + 32 paste_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 33 } + 34 + 35 static void + 36 selectall_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { + 37 } + 38 + 39 static void + 40 fullscreen_changed (GSimpleAction *action, GVariant *state, gpointer win) { + 41 if (g_variant_get_boolean (state)) + 42 gtk_window_maximize (GTK_WINDOW (win)); + 43 else + 44 gtk_window_unmaximize (GTK_WINDOW (win)); + 45 g_simple_action_set_state (action, state); + 46 } + 47 + 48 static void + 49 quit_activated (GSimpleAction *action, GVariant *parameter, gpointer app) + 50 { + 51 g_application_quit (G_APPLICATION(app)); + 52 } + 53 + 54 static void + 55 on_activate (GApplication *app, gpointer user_data) { + 56 GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + 57 + 58 const GActionEntry win_entries[] = { + 59 { "new", new_activated, NULL, NULL, NULL }, + 60 { "open", open_activated, NULL, NULL, NULL }, + 61 { "save", save_activated, NULL, NULL, NULL }, + 62 { "saveas", saveas_activated, NULL, NULL, NULL }, + 63 { "close", close_activated, NULL, NULL, NULL }, + 64 { "cut", cut_activated, NULL, NULL, NULL }, + 65 { "copy", copy_activated, NULL, NULL, NULL }, + 66 { "paste", paste_activated, NULL, NULL, NULL }, + 67 { "selectall", selectall_activated, NULL, NULL, NULL }, + 68 { "fullscreen", NULL, NULL, "false", fullscreen_changed } + 69 }; + 70 g_action_map_add_action_entries (G_ACTION_MAP (win), win_entries, G_N_ELEMENTS (win_entries), win); + 71 + 72 gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE); + 73 + 74 gtk_window_set_title (GTK_WINDOW (win), "menu3"); + 75 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 76 gtk_widget_show (win); + 77 } + 78 + 79 static void + 80 on_startup (GApplication *app, gpointer user_data) { + 81 GtkBuilder *builder = gtk_builder_new_from_resource ("/com/github/ToshioCP/menu3/menu3.ui"); + 82 GMenuModel *menubar = G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")); + 83 + 84 gtk_application_set_menubar (GTK_APPLICATION (app), menubar); + 85 g_object_unref (builder); + 86 + 87 const GActionEntry app_entries[] = { + 88 { "quit", quit_activated, NULL, NULL, NULL } + 89 }; + 90 g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, G_N_ELEMENTS (app_entries), app); + 91 } + 92 + 93 int + 94 main (int argc, char **argv) { + 95 GtkApplication *app; + 96 int stat; + 97 + 98 app = gtk_application_new ("com.github.ToshioCP.menu3", G_APPLICATION_FLAGS_NONE); + 99 g_signal_connect (app, "startup", G_CALLBACK (on_startup), NULL); + 100 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 101 + 102 stat =g_application_run (G_APPLICATION (app), argc, argv); + 103 g_object_unref (app); + 104 return stat; + 105 } + 106 + +meson.build + + 1 project('menu3', 'c') + 2 + 3 gtkdep = dependency('gtk4') + 4 + 5 gnome=import('gnome') + 6 resources = gnome.compile_resources('resources','menu3.gresource.xml') + 7 + 8 sourcefiles=files('menu3.c') + 9 + 10 executable('menu3', sourcefiles, resources, dependencies: gtkdep) +Up: [Readme.md](src/Readme.md), Prev: [Section 15}](src/sec15.src.md), Next: [Section 17[(src/sec17.src.md) \ No newline at end of file diff --git a/sec17.md b/sec17.md new file mode 100644 index 0000000..7a91618 --- /dev/null +++ b/sec17.md @@ -0,0 +1,5 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 16}](src/sec16.src.md)# GtkMenuButton + +before close + +Up: [Readme.md](src/Readme.md), Prev: [Section 16}](src/sec16.src.md) \ No newline at end of file diff --git a/sec2.md b/sec2.md new file mode 100644 index 0000000..ad37e11 --- /dev/null +++ b/sec2.md @@ -0,0 +1,309 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 1}](src/sec1.src.md), Next: [Section 3[(src/sec3.src.md)# Widgets (1) + +## GtkLabel, GtkButton and Gtkbox + +### GtkLabel + +We made an window and show it on the screen in the previous chapter. +Now we go on to the next topic, widgets in the window. +The simplest widget is GtkLabel. +It is a widget with a string in it. + + 1 #include + 2 + 3 static void + 4 on_activate (GApplication *app, gpointer user_data) { + 5 GtkWidget *win; + 6 GtkWidget *lab; + 7 + 8 win = gtk_application_window_new (GTK_APPLICATION (app)); + 9 gtk_window_set_title (GTK_WINDOW (win), "lb4"); + 10 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 11 + 12 lab = gtk_label_new ("Hello."); + 13 gtk_window_set_child (GTK_WINDOW (win), lab); + 14 + 15 gtk_widget_show (win); + 16 } + 17 + 18 int + 19 main (int argc, char **argv) { + 20 GtkApplication *app; + 21 int stat; + 22 + 23 app = gtk_application_new ("com.github.ToshioCP.lb1", G_APPLICATION_FLAGS_NONE); + 24 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 25 stat =g_application_run (G_APPLICATION (app), argc, argv); + 26 g_object_unref (app); + 27 return stat; + 28 } + 29 + +Save this program to a file `lb1.c`. +Then compile and run it. + + $ comp lb1 + $ ./a.out + +A window with a message "Hello." appears. + +![Screenshot of the label](screenshot_lb1.png) + +There's only a little change between `pr4.c` and `lb1.c`. +Diff is a good program to know the difference between two files. + + $ diff misc/pr4.c lb1.c + 5a6 + > GtkWidget *lab; + 8c9 + < gtk_window_set_title (GTK_WINDOW (win), "pr4"); + --- + > gtk_window_set_title (GTK_WINDOW (win), "lb4"); + 9a11,14 + > + > lab = gtk_label_new ("Hello."); + > gtk_window_set_child (GTK_WINDOW (win), lab); + > + 18c23 + < app = gtk_application_new ("com.github.ToshioCP.pr4", G_APPLICATION_FLAGS_NONE); + --- + > app = gtk_application_new ("com.github.ToshioCP.lb1", G_APPLICATION_FLAGS_NONE); + +This tells us: + +- The definition of a variable lab is added. +- The title of the window is changed. +- A label is generated and connected to the window. + +The function `gtk_window_set_child (GTK_WINDOW (win), lab)` makes the label `lab` a child widget of the window `win`. +Be careful. +A child widget is different from a child object. +Objects have parent-child relationship and Widgets also have parent-child relationship. +But these two relationships are totally different. +Don't be confused. +In the program `lb1.c`, `lab` is a child widget of `win`. +Child widgets are always located inside its parent widget in the screen. +See the window appeared on the screen. +The window includes the label. + +The window `win` dosen't have any parents. +We call such a window top-level window. +One application can have two or more top-level windows. + +### GtkButton + +Next widget is GtkButton. +It has a label or icon on it. +In this subsection, we will make a button with a label. +When a button is clicked on, it emits a "clicked" signal. +The following program shows how to catch the signal and do something. + + 1 #include + 2 + 3 static void + 4 on_clicked (GtkButton *btn, gpointer user_data) { + 5 g_print ("Clicked.\n"); + 6 } + 7 + 8 static void + 9 on_activate (GApplication *app, gpointer user_data) { + 10 GtkWidget *win; + 11 GtkWidget *btn; + 12 + 13 win = gtk_application_window_new (GTK_APPLICATION (app)); + 14 gtk_window_set_title (GTK_WINDOW (win), "lb4"); + 15 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 16 + 17 btn = gtk_button_new_with_label ("Click me"); + 18 gtk_window_set_child (GTK_WINDOW (win), btn); + 19 g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), NULL); + 20 + 21 gtk_widget_show (win); + 22 } + 23 + 24 int + 25 main (int argc, char **argv) { + 26 GtkApplication *app; + 27 int stat; + 28 + 29 app = gtk_application_new ("com.github.ToshioCP.lb2", G_APPLICATION_FLAGS_NONE); + 30 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 31 stat =g_application_run (G_APPLICATION (app), argc, argv); + 32 g_object_unref (app); + 33 return stat; + 34 } + 35 + +Look at the line 17 to 19. +First, generate a GtkButton widget `btn` with a label "Click me". +Then, set it to the window `win` as a child. +Finally, connect a "clicked" signal of the button to a handler (function) `on_click`. +So, if `btn` is clicked, the function `on_click` is invoked. + +Name the program `lb2.c` and save it. +Now compile and run it. + +![Screenshot of the label](screenshot_lb2.png) + +A window with the button appears. +Click the button (it is a large button, you can click everywhere inside the window), then a string "Clicked." appears on the shell terminal. +It shows the handler was invoked by clicking the button. + +It's fairly good for us to make sure that the clicked signal was caught and the handler was invoked. +However, using g_print is out of harmony with GTK which is a GUI library. +So, we will change the handler. +The following code is `lb3.c`. + + 1 static void + 2 on_clicked (GtkButton *btn, gpointer user_data) { + 3 GtkWindow *win = GTK_WINDOW (user_data); + 4 gtk_window_destroy (win); + 5 } + 6 + 7 static void + 8 on_activate (GApplication *app, gpointer user_data) { + 9 GtkWidget *win; + 10 GtkWidget *btn; + 11 + 12 win = gtk_application_window_new (GTK_APPLICATION (app)); + 13 gtk_window_set_title (GTK_WINDOW (win), "lb4"); + 14 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 15 + 16 btn = gtk_button_new_with_label ("Quit"); + 17 gtk_window_set_child (GTK_WINDOW (win), btn); + 18 g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), win); + 19 + 20 gtk_widget_show (win); + 21 } + +And the difference between `lb2.c` and `lb3.c` is as follows. + + $ diff lb2.c lb3.c + 5c5,6 + < g_print ("Clicked.\n"); + --- + > GtkWindow *win = GTK_WINDOW (user_data); + > gtk_window_destroy (win); + 17c18 + < btn = gtk_button_new_with_label ("Click me"); + --- + > btn = gtk_button_new_with_label ("Quit"); + 19c20 + < g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), NULL); + --- + > g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), win); + 29c30 + < app = gtk_application_new ("com.github.ToshioCP.lb2", G_APPLICATION_FLAGS_NONE); + --- + > app = gtk_application_new ("com.github.ToshioCP.lb3", G_APPLICATION_FLAGS_NONE); + +The change is: + +- The function `g_print` in `lb2.c` was deleted and two lines above are inserted instead. +- The label of `btn` is changed from "Click me" to "Quit". +- The fourth argument of `g_signal_connect` is changed from `NULL` to `win`. + +Most important is the fourth argument of `g_signal_connect`. +It is described as "data to pass to handler" in the definition of g\_signal\_connect in GObject API reference. +Therefore, `win` which is a pointer to GtkApplicationWindow is passed to the handler as a second parameter user_data. +Then, the handler cast it to a pointer to GtkWindow and call `gtk_window_destroy` and destroy the top window. +Then, the application quits. + +### GtkBox + +GtkWindow and GtkApplicationWindow can have only one child. +If you want to add two or more widgets inside a window, you need a container widget. +GtkBox is one of the containers. +It arranges two or more child widgets into a single row or column. +The following procedure shows the way to add two buttons in a window. + +- Generate GtkApplicationWindow. +- Generate GtkBox and set it a child of GtkApplicationWindow. +- Generate GtkButton and append it to GtkBox. +- Generate another GtkButton and append it to GtkBox. + +After this, the Widgets are connected as following diagram. + +![Parent-child relationship](box.png) + +Now, code it. + + 1 #include + 2 + 3 static void + 4 on_clicked1 (GtkButton *btn, gpointer user_data) { + 5 const gchar *s; + 6 + 7 s = gtk_button_get_label (btn); + 8 if (g_strcmp0 (s, "Hello.") == 0) + 9 gtk_button_set_label (btn, "Good-bye."); + 10 else + 11 gtk_button_set_label (btn, "Hello."); + 12 } + 13 + 14 static void + 15 on_clicked2 (GtkButton *btn, gpointer user_data) { + 16 GtkWindow *win = GTK_WINDOW (user_data); + 17 gtk_window_destroy (win); + 18 } + 19 + 20 static void + 21 on_activate (GApplication *app, gpointer user_data) { + 22 GtkWidget *win; + 23 GtkWidget *box; + 24 GtkWidget *btn1; + 25 GtkWidget *btn2; + 26 + 27 win = gtk_application_window_new (GTK_APPLICATION (app)); + 28 gtk_window_set_title (GTK_WINDOW (win), "lb4"); + 29 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 30 + 31 box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); + 32 gtk_box_set_homogeneous (GTK_BOX (box), TRUE); + 33 gtk_window_set_child (GTK_WINDOW (win), box); + 34 + 35 btn1 = gtk_button_new_with_label ("Hello."); + 36 g_signal_connect (btn1, "clicked", G_CALLBACK (on_clicked1), NULL); + 37 + 38 btn2 = gtk_button_new_with_label ("Quit"); + 39 g_signal_connect (btn2, "clicked", G_CALLBACK (on_clicked2), win); + 40 + 41 gtk_box_append (GTK_BOX (box), btn1); + 42 gtk_box_append (GTK_BOX (box), btn2); + 43 + 44 gtk_widget_show (win); + 45 } + 46 + 47 int + 48 main (int argc, char **argv) { + 49 GtkApplication *app; + 50 int stat; + 51 + 52 app = gtk_application_new ("com.github.ToshioCP.lb4", G_APPLICATION_FLAGS_NONE); + 53 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 54 stat =g_application_run (G_APPLICATION (app), argc, argv); + 55 g_object_unref (app); + 56 return stat; + 57 } + 58 + +Look at the function `on_activate`. + +After the generation of GtkApplicationWindow, GtkBox is generated. + + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); + gtk_box_set_homogeneous (GTK_BOX (box), TRUE); + +The first argument arranges children vertically. +The second argument is sizes between children. +The next function fills a box with children, giving them equal space. + +After that, two buttons `btn1` and `btn2` are generated and the signal handlers are set. +Then, these two buttons are appended to the box. + +![Screenshot of the box](screenshot_lb4.png) + +The handler corresponds to `btn1` changes its label. +The handler corresponds to `btn2` destroys the top-level window and the application quits. + +Up: [Readme.md](src/Readme.md), Prev: [Section 1}](src/sec1.src.md), Next: [Section 3[(src/sec3.src.md) \ No newline at end of file diff --git a/sec3.md b/sec3.md new file mode 100644 index 0000000..1f9755b --- /dev/null +++ b/sec3.md @@ -0,0 +1,164 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 2}](src/sec2.src.md), Next: [Section 4[(src/sec4.src.md)# Widgets (2) + +## GtkTextView, GtkTextbuffer and GtkScrolledWindow + +### GtkTextView and GtkTextBuffer + +GtkTextview is a widget for multiline text editing. +GtkTextBuffer is a text buffer which is connected to GtkTextView. +See a sample program `tfv1.c` below. + + 1 #include + 2 + 3 static void + 4 on_activate (GApplication *app, gpointer user_data) { + 5 GtkWidget *win; + 6 GtkWidget *tv; + 7 GtkTextBuffer *tb; + 8 gchar *text; + 9 + 10 text = + 11 "Once upon a time, there was an old man who was called Taketori-no-Okina." + 12 "It is a japanese word that means a man whose work is making bamboo baskets.\n" + 13 "One day, he went into a mountain and found a shining bamboo." + 14 "\"What a mysterious bamboo it is!,\" he said." + 15 "He cuts it, then there was a small cute baby girl in it." + 16 "The girl was shining faintly." + 17 "He thought this baby girl is a gift from Heaven and took her home.\n" + 18 "His wife was surprized at his tale." + 19 "They were very happy because they had no children." + 20 ; + 21 win = gtk_application_window_new (GTK_APPLICATION (app)); + 22 gtk_window_set_title (GTK_WINDOW (win), "Taketori"); + 23 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 24 + 25 tv = gtk_text_view_new (); + 26 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 27 gtk_text_buffer_set_text (tb, text, -1); + 28 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 29 + 30 gtk_window_set_child (GTK_WINDOW (win), tv); + 31 + 32 gtk_widget_show (win); + 33 } + 34 + 35 int + 36 main (int argc, char **argv) { + 37 GtkApplication *app; + 38 int stat; + 39 + 40 app = gtk_application_new ("com.github.ToshioCP.tfv1", G_APPLICATION_FLAGS_NONE); + 41 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 42 stat =g_application_run (G_APPLICATION (app), argc, argv); + 43 g_object_unref (app); + 44 return stat; + 45 } + 46 + +Look at line 25. +GtkTextView is generated and its pointer is assigned to `tv`. +When GtkTextView is generated, the connected GtkTextBuffer is also generated automatically. +In the next line, the pointer to the buffer is got and assigned to `tb`. +Then, the text from line 10 to 20 is assigned to the buffer. + +GtkTextView has a wrap mode. +When `GTK_WRAP_WORD_CHAR` is set, text wraps in between words, or if that is not enough, also between graphemes. + +In line 30, `tv` is set to `win` as a child. + +Now compile and run it. + +![GtkTextView](screenshot_tfv1.png) + +There's an I-beam pointer in the window. +You can add or delete any character on GtkTextview. +And your change is kept in GtkTextBuffer. +If you add more characters than the limit of the window, the height of the window extends. +If the height gets bigger than the height of the display screen, you won't be able to control the size of the window back to the original size. +It's a problem. +You can solve it by putting GtkScrolledWindow between GtkApplicationWindow and GtkTextView. + +### GtkScrolledWindow + +What we need to do is: + +- Generate GtkScrolledWindow and set it as a child of GtkApplicationWindow. +- Set GtkTextVies as a child of GtkScrolledWindow. + +Modify `tfv1.c` and save it as `tfv2.c`. +The difference between these two files is very little. + + $ diff tfv1.c tfv2.c + 5a6 + > GtkWidget *scr; + 24a26,28 + > scr = gtk_scrolled_window_new (); + > gtk_window_set_child (GTK_WINDOW (win), scr); + > + 30c34 + < gtk_window_set_child (GTK_WINDOW (win), tv); + --- + > gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 40c44 + < app = gtk_application_new ("com.github.ToshioCP.tfv1", G_APPLICATION_FLAGS_NONE); + --- + > app = gtk_application_new ("com.github.ToshioCP.tfv2", G_APPLICATION_FLAGS_NONE); + +Though you can modify the source file by this diff output, It's good for you to show `tfv2.c`. + + 1 #include + 2 + 3 static void + 4 on_activate (GApplication *app, gpointer user_data) { + 5 GtkWidget *win; + 6 GtkWidget *scr; + 7 GtkWidget *tv; + 8 GtkTextBuffer *tb; + 9 gchar *text; + 10 + 11 text = + 12 "Once upon a time, there was an old man who was called Taketori-no-Okina." + 13 "It is a japanese word that means a man whose work is making bamboo baskets.\n" + 14 "One day, he went into a mountain and found a shining bamboo." + 15 "\"What a mysterious bamboo it is!,\" he said." + 16 "He cuts it, then there was a small cute baby girl in it." + 17 "The girl was shining faintly." + 18 "He thought this baby girl is a gift from Heaven and took her home.\n" + 19 "His wife was surprized at his tale." + 20 "They were very happy because they had no children." + 21 ; + 22 win = gtk_application_window_new (GTK_APPLICATION (app)); + 23 gtk_window_set_title (GTK_WINDOW (win), "Taketori"); + 24 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 25 + 26 scr = gtk_scrolled_window_new (); + 27 gtk_window_set_child (GTK_WINDOW (win), scr); + 28 + 29 tv = gtk_text_view_new (); + 30 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 31 gtk_text_buffer_set_text (tb, text, -1); + 32 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 33 + 34 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 35 + 36 gtk_widget_show (win); + 37 } + 38 + 39 int + 40 main (int argc, char **argv) { + 41 GtkApplication *app; + 42 int stat; + 43 + 44 app = gtk_application_new ("com.github.ToshioCP.tfv2", G_APPLICATION_FLAGS_NONE); + 45 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 46 stat =g_application_run (G_APPLICATION (app), argc, argv); + 47 g_object_unref (app); + 48 return stat; + 49 } + 50 + +Now compile and run it. +This time the window doesn't extend even if you type a lot of characters. +It just scrolls. + +Up: [Readme.md](src/Readme.md), Prev: [Section 2}](src/sec2.src.md), Next: [Section 4[(src/sec4.src.md) \ No newline at end of file diff --git a/sec4.md b/sec4.md new file mode 100644 index 0000000..844bdf9 --- /dev/null +++ b/sec4.md @@ -0,0 +1,304 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 3}](src/sec3.src.md), Next: [Section 5[(src/sec5.src.md)# Widgets (3) + +## Open signal + +### G\_APPLICATION\_HANDLES\_OPEN flag + +GtkTextView, GtkTextBuffer and GtkScrolledWindow have given us a minimum editor in the previous section. +Next, we will add a read function to this program and remake it into a file viewer. +There are many way to implement the function. +However, because this is a tutorial for beginners, we take the simplest way. + +When the program starts, we give a filename as an argument. + + $ ./a.out filename + +Then it opens the file and set it into GtkTextBuffer. + +At the beginning of the implementation, we need to know how GtkApplication (or GApplication) recognizes arguments. +It is described in the GIO API reference. + +When GtkApplication is generated, a flag (its type is GApplicationFlags) is given as an argument. + + GtkApplication * + gtk_application_new (const gchar *application_id, GApplicationFlags flags); + +This flag is described in the GApplication section in GIO API reference. + + GApplicationFlags' Members + + G_APPLICATION_FLAGS_NONE Default. (No argument allowed) + ... ... ... + G_APPLICATION_HANDLES_OPEN This application handles opening files (in the primary instance). + ... ... ... + +There are ten flags. +But we only need two of them so far. +We've already used `G_APPLICATION_FLAGS_NONE`. +It is the simplest option. +No argument is allowed. +If you give arguments and run the application, then error occurs. + +`G_APPLICATION_HANDLES_OPEN` is the second simplest option. +It allows arguments but only files. +The application assumes all the arguments are filenames. + +Now we use this flag when generating GtkApplication. + + app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN); + +### open signal + +When the application starts, two signals are possible. + +- activate signal --- This signal is emitted when there's no argument. +- open signal --- This signal is emitted when there is at least one argument. + +The handler of open signal is called as follows. + + void user_function (GApplication *application, + gpointer files, + gint n_files, + gchar *hint, + gpointer user_data) + +The parameters are as follows: + +- application --- the application (usually GtkApplication) +- files --- an array of GFiles. [array length=n_files] [element-type GFile] +- n_files --- the length of files +- hint --- a hint provided by the calling instance (usually it can be ignored) +- user_data --- user data set when the signal handler was connected. + +The way how to read a file using GFiles will be described in the next section. + +## Coding a file viewer + +### What is a file viewer? + +A file viewer is a program that shows a text file given as an argument. +It works as follows. + +- If it is given arguments, it recognizes the first argument as a filename and open it. +- If opening the file succeeds, read and set it to GtkTextBuffer and show the window. +- If it fails to open the file, show an error message and quit. +- If there's no argument, show an error message and quit. +- If there are two or more arguments, the second one and after are ignored. + +The program is as follows. + + 1 #include + 2 + 3 static void + 4 on_activate (GApplication *app, gpointer user_data) { + 5 g_print ("You need a filename argument.\n"); + 6 } + 7 + 8 static void + 9 on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + 10 GtkWidget *win; + 11 GtkWidget *scr; + 12 GtkWidget *tv; + 13 GtkTextBuffer *tb; + 14 char *contents; + 15 gsize length; + 16 char *filename; + 17 + 18 win = gtk_application_window_new (GTK_APPLICATION (app)); + 19 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 20 + 21 scr = gtk_scrolled_window_new (); + 22 gtk_window_set_child (GTK_WINDOW (win), scr); + 23 + 24 tv = gtk_text_view_new (); + 25 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 26 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 27 gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE); + 28 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 29 + 30 if (g_file_load_contents (files[0], NULL, &contents, &length, NULL, NULL)) { + 31 gtk_text_buffer_set_text (tb, contents, length); + 32 g_free (contents); + 33 filename = g_file_get_basename (files[0]); + 34 gtk_window_set_title (GTK_WINDOW (win), filename); + 35 g_free (filename); + 36 gtk_widget_show (win); + 37 } else { + 38 filename = g_file_get_path (files[0]); + 39 g_print ("No such file: %s.\n", filename); + 40 gtk_window_destroy (GTK_WINDOW (win)); + 41 } + 42 } + 43 + 44 int + 45 main (int argc, char **argv) { + 46 GtkApplication *app; + 47 int stat; + 48 + 49 app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN); + 50 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 51 g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + 52 stat =g_application_run (G_APPLICATION (app), argc, argv); + 53 g_object_unref (app); + 54 return stat; + 55 } + 56 + +Save it as `tfv3.c`. +Then compile and run it. + + $ comp tfv3 + $ ./a.out tfv3.c + +![File viewer](screenshot_tfv3.png) + +Now I want to explain the program `tfv3.c`. +First, the function `main` changes in only two lines. + +- `G_APPLICATION_FLAGS_NONE` is replaced with `G_APPLICATION_HANDLES_OPEN`. +- `g_signal_connect (app, "open", G_CALLBACK (on_open), NULL)` is added. + +Next, the handler `on_activate` is now very simple. +Just output the error message. +The application quits immediately because no window is generated. + +The point is the handler `on_open`. + +- It generates GtkApplicationWindow, GtkScrolledWindow, GtkTextView and GtkTextBuffer and connect them. +- Set wrap mode to `GTK_WRAP_WORD_CHAR` in GtktextView. +- Set non-editable to GtkTextView because the program isn't an editor but only a viewer. +- Read the file and set it to GtkTextBuffer (this will be explained in detail later). +- If the file is not opened then output an error message and destroy the window. It makes the application quit. + +The file reading part of the program is shown again below. + + if (g_file_load_contents(files[0], NULL, &contents, &length, NULL, NULL)) { + gtk_text_buffer_set_text(tb, contents, length); + g_free(contents); + filename = g_file_get_basename(files[0]); + gtk_window_set_title (GTK_WINDOW (win), filename); + g_free(filename); + gtk_widget_show (win); + } else { + filename = g_file_get_path(files[0]); + g_print ("No such file: %s.\n", filename); + gtk_window_destroy (GTK_WINDOW (win)); + } + +The function `g_file_load_contents` loads the file contents into a buffer, which is automatically allocated, and set the pointer to the buffer into `contents`. +And the length of the buffer is set to `length`. +It returns `TRUE` if the file's contents were successfully loaded. `FALSE` if there were errors. + +If the function succeeds, set the contents into GtkTextBuffer, free the buffer memories pointed by `contents`, set the filename to the title of the window, +free the memories pointed by `filename` and show the window. +If it fails, it outputs an error message and destroy the window. + +## GtkNotebook + +GtkNotebook is a container widget that contains multiple children with tabs in it. + +![GtkNotebook](screenshot_gtk_notebook.png) + +Look at the screenshots above. +The left one is a window at the startup. +It shows the file `pr1.c`. +The filename is in the left tab. +After clicking on the right tab, then the contents of `tfv1.c` appears. +It is shown in the right screenshot. + +GtkNotebook widget is between GtkApplicationWindow and GtkScrolledWindow. +Now I want to show you the program `tfv4.c`. + + 1 #include + 2 + 3 static void + 4 on_activate (GApplication *app, gpointer user_data) { + 5 g_print ("You need a filename argument.\n"); + 6 } + 7 + 8 static void + 9 on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + 10 GtkWidget *win; + 11 GtkWidget *nb; + 12 GtkWidget *lab; + 13 GtkNotebookPage *nbp; + 14 GtkWidget *scr; + 15 GtkWidget *tv; + 16 GtkTextBuffer *tb; + 17 char *contents; + 18 gsize length; + 19 char *filename; + 20 int i; + 21 + 22 win = gtk_application_window_new (GTK_APPLICATION (app)); + 23 gtk_window_set_title (GTK_WINDOW (win), "file viewer"); + 24 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 25 gtk_window_maximize (GTK_WINDOW (win)); + 26 + 27 nb = gtk_notebook_new (); + 28 gtk_window_set_child (GTK_WINDOW (win), nb); + 29 + 30 for (i = 0; i < n_files; i++) { + 31 if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + 32 scr = gtk_scrolled_window_new (); + 33 tv = gtk_text_view_new (); + 34 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 35 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 36 gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE); + 37 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 38 + 39 gtk_text_buffer_set_text (tb, contents, length); + 40 g_free (contents); + 41 filename = g_file_get_basename (files[i]); + 42 lab = gtk_label_new (filename); + 43 gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + 44 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + 45 g_object_set (nbp, "tab-expand", TRUE, NULL); + 46 g_free (filename); + 47 } else { + 48 filename = g_file_get_path (files[i]); + 49 g_print ("No such file: %s.\n", filename); + 50 g_free (filename); + 51 } + 52 } + 53 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) + 54 gtk_widget_show (win); + 55 else + 56 gtk_window_destroy (GTK_WINDOW (win)); + 57 } + 58 + 59 int + 60 main (int argc, char **argv) { + 61 GtkApplication *app; + 62 int stat; + 63 + 64 app = gtk_application_new ("com.github.ToshioCP.tfv4", G_APPLICATION_HANDLES_OPEN); + 65 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 66 g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + 67 stat =g_application_run (G_APPLICATION (app), argc, argv); + 68 g_object_unref (app); + 69 return stat; + 70 } + 71 + +Most of the change is in the function `on_open`. +The numbers at the left of the following items are line numbers in the source code. + +- 11-13: Variables `nb`, `lab` and `nbp` are defined and point GtkNotebook, GtkLabel and GtkNotebookPage respectively. +- 23: The window's title is set to "file viewer". +- 25: The size of the window is set to maximum because a big window is appropriate for file viewers. +- 27-28 GtkNotebook is generated and set it as a child of GtkApplicationWindow. +- 30-52 For-loop. Each loop corresponds to an argument. And files[i] is GFile object with respect to the i-th argument. +- 32-37 GtkScrollledWindow, GtkTextView and GtkTextBuffer are generated and GtkTextView is connected to GtkScrolledWindow as a child. + They corresponds to each file, so they are generated inside the for-loop. +- 39-42 Set the contents of the file into GtkTextBuffer and free the memory pointed by `contents`. Get the filename and generate GtkLabel with the filename. +- 43: Append GtkScrolledWindow and GtkLabel to GtkNotebook. The appended objects are children of automatically generated GtkNotebookPage object. Therefore, the structure is like this: + + GtkNotebook -- GtkNotebookPage -- (GtkScrolledWindow and GtkLabel) + +- 44: Get GtkNotebookPage object and set its pointer to `nbp`. +- 45: GtkNotebookPage has a property "tab-expand". If it is set to TRUE then the tab expand horizontally as long as possible. If FALSE, then the width of the tab is determined by the size of the label. `g_object_set` is a general function to set properties in any objects. +- 46: free the memory pointed by `filename` +- 53-56: If at least one file was read, then the number of GtkNotebookPage is greater than zero. If it's true, then show the window. If it's false, then destroy the window. + +Up: [Readme.md](src/Readme.md), Prev: [Section 3}](src/sec3.src.md), Next: [Section 5[(src/sec5.src.md) \ No newline at end of file diff --git a/sec5.md b/sec5.md new file mode 100644 index 0000000..796613e --- /dev/null +++ b/sec5.md @@ -0,0 +1,347 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 4}](src/sec4.src.md), Next: [Section 6[(src/sec6.src.md)# Define Child object + +## Very simple editor + +We made a very simple file viewer in the previous section. +Now we go on to rewrite it and make a very simple editor. +Its source file name is tfe1.c (text file editor 1). + +GtkTextView originally has a feature of multi line editing. +Therefore, we don't need to rewrite the program from scratch. +We just add two things to the file viewer. + +- Static memory is needed to store a pointer to GFile. +- We need to implement file write function. + +A couple of ways are possible to get memories to keep GFile. + +- Use global variables. +- make a child widget object and extend the memories allocated to the widget. + +Using global variables is easy to implement. +Define a sufficient size array of pointers to GFile. +For example, + + GFile *f[20]; + +And `f[i]` corresponds to i-th GtkNotebookPage. +However, there are two problems. +One is the size of the array. +If a user gives arguments more than that, bad thing may happen. +The other is the difficulty of maintenance of the program. +It is a small program so far. +However, if you continue developing it, then its size grows bigger and bigger. +Generally speaking, the bigger the program size, the more difficult to maintain global variables. + +Making child widget object is a good idea in terms of maintenance. +However, one thing you need to be careful is the difference between "child object" and "child widget". +What we are thinking about now is "child object". +A child object includes its parent object. +And a child widget object derives everything from the parent widget object. + +![Child widget of GtkTwxtView](child.png) + +We will define TfeTextView as a child widget object of GtkTextView. +It has everything that GtkTextView has. +For example, TfeTextView has GtkTextbuffer correspods to GtkTextView inside TfeTextView. +And important thing is that TfeTextView can have a memory to keep a pointer to GFile. + +However, to understand the general theory about gobjects is very hard especially for beginners. +So, I will just show you the way how to write the code and avoid the theoretical side in the next section. + +## How to define a child widget of GtkTextView + + +Let's define TfeTextView widget object which is a child object of GtkTextView. +First, look at the program below. + + #define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () + G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + + struct _TfeTextView + { + GtkTextView parent; + GFile *file; + }; + + G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + + static void + tfe_text_view_init (TfeTextView *tv) { + } + + static void + tfe_text_view_class_init (TfeTextViewClass *class) { + } + + void + tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + tv -> file = f; + } + + GFile * + tfe_text_view_get_file (TfeTextView *tv) { + return tv -> file; + } + + GtkWidget * + tfe_text_view_new (void) { + return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + } + +If you are curious about the background theory of this program, It's very good for you. +Because to know the theory is very important for you to program GTK applications. +Look at GObject API reference. +All you need is described in it. +However, it's a tough journey especially for beginners. +For now, you don't need to know such difficult theory. +Just remember the instructions below. + +- TfeTextView is divided into two parts. +Tfe and TextView. +Tfe is called prefix, namespace or module. +TextView is called object. +- There are three patterns. +TfeTextView (camel case), tfe\_text\_view (this is used to write functions) and TFE\_TEXT\_VIEW (This is used to write casts). +- First, define TFE\_TYPE\_TEXT\_VIEW as tfe\_text\_view\_get\_type (). +The name is always (prefix)\_TYPE\_(object) and the letters are upper case. +And the replacement text is always (prefix)\_(object)\_get\_type () and the letters are lower case. +- Next, use G\_DECLARE\_FINAL\_TYPE macro. +The arguments are the child object name in camel case, lower case with underscore, prefix, object and parent object name. +- Declare the structure \_TfeTextView. +The underscore is necessary. +The first member is the parent object. +Notice this is not a pointer but the object itself. +The second member and after are members of the child object. +TfeTextView structure has a pointer to GFile as a member. +- Use G\_DEFINE\_TYPE macro. +The arguments are the child object name in camel case, lower case with underscore and parent object type (prefix)\_TYPE\_(module). +- Define instance init function (tfe\_text\_view\_init). +Usually you don't need to do anything. +- Define class init function (tfe\_text\_view\_class\_init). +You don't need to do anything in this widget. +- Write function codes you want to add (tfe\_text\_view\_set\_file and tfe\_text\_view\_get\_file). +`tv` is a pointer to TfeTextView object instance which is a C-struture declared with the tag \_TfeTextView. +So, the structure has a member `file` as a pointer to GFile. +`tv->file = f` is an assignment of `f` to a member `file` of the structure pointed by `tv`. +This is an example how to use the extended memory in a child widget. +- Write object generation function. +Its name is (prefix)\_(object)\_new. +If the parent object function needs parameters, this function also need them. +You sometimes might want to add some parameters. +It's your choice. +Use gtk\_widget\_new function to generate the child widget. +The arguments are (prefix)\_TYPE\_(object), a list to initialize properties and NULL. +In this code no property needs to be initialized. + +This program is not perfect. +It has some problem. +But I don't discuss it now. +It will be modified later. + +## Close-request signal + +As a first step, `tfe1.c` writes files just before the window closes. +GtkWindow emits "close-request" signal before it closes. +We connect the signal and the handler `before_close`. +A handler is a C function. +When a function is connected to a certain signal, we call the function handler. +Then, the function `before_close` is invoked when the signal "close-request" is emittd. + + g_signal_connect (win, "close-request", G_CALLBACK (before_close), NULL); + +The argument win is GtkApplicationWindow, in which the signal "close-request" is defined, and before\_close is the handler. +`G_CALLBACK` cast is necessary before the handler. +The program of before\_close is as follows. + + 1 static gboolean + 2 before_close (GtkWindow *win, GtkWidget *nb) { + 3 GtkWidget *scr; + 4 GtkWidget *tv; + 5 GFile *file; + 6 GtkTextBuffer *tb; + 7 GtkTextIter start_iter; + 8 GtkTextIter end_iter; + 9 gchar *contents; /* gchar is the same as char ... typedef char gchar;*/ + 10 guint n; + 11 guint i; + 12 + 13 n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)); + 14 for (i = 0; i < n; ++i) { + 15 scr = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), i); + 16 tv = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scr)); + 17 file = tfe_text_view_get_file (TFE_TEXT_VIEW (tv)); + 18 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 19 gtk_text_buffer_get_bounds (tb, &start_iter, &end_iter); + 20 contents = gtk_text_buffer_get_text (tb, &start_iter, &end_iter, FALSE); + 21 if (! g_file_replace_contents (file, contents, strlen (contents), NULL, TRUE, G_FILE_CREATE_NONE, NULL, NULL, NULL)) + 22 g_print ("ERROR : Can't save %s.", g_file_get_path (file)); + 23 } + 24 return FALSE; + 25 } + +The numbers on the left of items are line numbers in the source code. + +- 13: Get the number of pages `nb` has. +- 14-23: For loop with regard to the index to each pages. +- 15-17: Get GtkScrolledWindow, TfeTextView and a pointer to GFile. The pointer was stored when `on_open` handler ran. It will be shown later. +- 18-20: Get GtkTextBuffer and contents. start\_iter and end\_iter is iterators of the buffer. I don't want to explain them now because it would take a lot of time. Just remember these lines for the present. +- 21: Write the file. + +## Source code of tfe1.c + +Now I will show you all the source code of `tfe1`.c. + + 1 #include + 2 + 3 /* Define TfeTextView Widget which is the child object of GtkTextView */ + 4 + 5 #define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () + 6 G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + 7 + 8 struct _TfeTextView + 9 { + 10 GtkTextView parent; + 11 GFile *file; + 12 }; + 13 + 14 G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + 15 + 16 static void + 17 tfe_text_view_init (TfeTextView *tv) { + 18 } + 19 + 20 static void + 21 tfe_text_view_class_init (TfeTextViewClass *class) { + 22 } + 23 + 24 void + 25 tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + 26 tv -> file = f; + 27 } + 28 + 29 GFile * + 30 tfe_text_view_get_file (TfeTextView *tv) { + 31 return tv -> file; + 32 } + 33 + 34 GtkWidget * + 35 tfe_text_view_new (void) { + 36 return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + 37 } + 38 + 39 /* ---------- end of the definition of TfeTextView ---------- */ + 40 + 41 static gboolean + 42 before_close (GtkWindow *win, GtkWidget *nb) { + 43 GtkWidget *scr; + 44 GtkWidget *tv; + 45 GFile *file; + 46 GtkTextBuffer *tb; + 47 GtkTextIter start_iter; + 48 GtkTextIter end_iter; + 49 gchar *contents; /* gchar is the same as char ... typedef char gchar;*/ + 50 guint n; + 51 guint i; + 52 + 53 n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)); + 54 for (i = 0; i < n; ++i) { + 55 scr = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), i); + 56 tv = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scr)); + 57 file = tfe_text_view_get_file (TFE_TEXT_VIEW (tv)); + 58 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 59 gtk_text_buffer_get_bounds (tb, &start_iter, &end_iter); + 60 contents = gtk_text_buffer_get_text (tb, &start_iter, &end_iter, FALSE); + 61 if (! g_file_replace_contents (file, contents, strlen (contents), NULL, TRUE, G_FILE_CREATE_NONE, NULL, NULL, NULL)) + 62 g_print ("ERROR : Can't save %s.", g_file_get_path (file)); + 63 } + 64 return FALSE; + 65 } + 66 + 67 static void + 68 on_activate (GApplication *app, gpointer user_data) { + 69 g_print ("You need a filename argument.\n"); + 70 } + 71 + 72 static void + 73 on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + 74 GtkWidget *win; + 75 GtkWidget *nb; + 76 GtkWidget *lab; + 77 GtkNotebookPage *nbp; + 78 GtkWidget *scr; + 79 GtkWidget *tv; + 80 GtkTextBuffer *tb; + 81 char *contents; + 82 gsize length; + 83 char *filename; + 84 int i; + 85 + 86 win = gtk_application_window_new (GTK_APPLICATION (app)); + 87 gtk_window_set_title (GTK_WINDOW (win), "file editor"); + 88 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + 89 gtk_window_maximize (GTK_WINDOW (win)); + 90 + 91 nb = gtk_notebook_new (); + 92 gtk_window_set_child (GTK_WINDOW (win), nb); + 93 + 94 for (i = 0; i < n_files; i++) { + 95 if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + 96 scr = gtk_scrolled_window_new (); + 97 tv = tfe_text_view_new (); + 98 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 99 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 100 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 101 + 102 tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + 103 gtk_text_buffer_set_text (tb, contents, length); + 104 g_free (contents); + 105 filename = g_file_get_basename (files[i]); + 106 lab = gtk_label_new (filename); + 107 gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + 108 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + 109 g_object_set (nbp, "tab-expand", TRUE, NULL); + 110 g_free (filename); + 111 } else { + 112 filename = g_file_get_path (files[i]); + 113 g_print ("No such file: %s.\n", filename); + 114 g_free (filename); + 115 } + 116 } + 117 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + 118 g_signal_connect (win, "close-request", G_CALLBACK (before_close), nb); + 119 gtk_widget_show (win); + 120 } else + 121 gtk_window_destroy (GTK_WINDOW (win)); + 122 } + 123 + 124 int + 125 main (int argc, char **argv) { + 126 GtkApplication *app; + 127 int stat; + 128 + 129 app = gtk_application_new ("com.github.ToshioCP.tfe1", G_APPLICATION_HANDLES_OPEN); + 130 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 131 g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + 132 stat =g_application_run (G_APPLICATION (app), argc, argv); + 133 g_object_unref (app); + 134 return stat; + 135 } + 136 + +- 102: set the pointer to GFile into TfeTextView. +`files[i]` is a pointer to GFile structure. +It will be freed by the system. So you need to copy it. +`g_file_dup` duplicate the given GFile structure. +- 118: connect "close-request" signal and `before_close` handler. +The fourth argument is called user data and it is given to the signal handler. +So, `nb` is given to `before_close` as the second argument. + +Now compile and run it. +Type `./a.out somefile` and make sure that the file is modified. + +Now we got a very simple editor. +It's not smart. +We need more features like open, save, saveas, change font and so on. +We will add them in the next section and after. +Up: [Readme.md](src/Readme.md), Prev: [Section 4}](src/sec4.src.md), Next: [Section 6[(src/sec6.src.md) \ No newline at end of file diff --git a/sec6.md b/sec6.md new file mode 100644 index 0000000..6e9c082 --- /dev/null +++ b/sec6.md @@ -0,0 +1,450 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 5}](src/sec5.src.md), Next: [Section 7[(src/sec7.src.md)# Ui file and GtkBuiler + +## New, open and save button + +We made the simplest editor in the previous section. +It reads the files in `on_open` funciton at start-up and writes it at closing window. +It works but is not good. +It is better to make "New", "Open", "Save" and "Close" buttons. +This section describes how to put those buttons into the window. +Signals and handlers will be explained later. + +![Screenshot of the file editor](screenshot_tfe2.png) + +The screenshot above shows the layout. +The function `on_open` in the source code `tfe2.c` is as follows. + + 1 static void + 2 on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + 3 GtkWidget *win; + 4 GtkWidget *nb; + 5 GtkWidget *lab; + 6 GtkNotebookPage *nbp; + 7 GtkWidget *scr; + 8 GtkWidget *tv; + 9 GtkTextBuffer *tb; + 10 char *contents; + 11 gsize length; + 12 char *filename; + 13 int i; + 14 + 15 GtkWidget *boxv; + 16 GtkWidget *boxh; + 17 GtkWidget *dmy1; + 18 GtkWidget *dmy2; + 19 GtkWidget *dmy3; + 20 GtkWidget *btnn; /* button for new */ + 21 GtkWidget *btno; /* button for open */ + 22 GtkWidget *btns; /* button for save */ + 23 GtkWidget *btnc; /* button for close */ + 24 + 25 + 26 win = gtk_application_window_new (GTK_APPLICATION (app)); + 27 gtk_window_set_title (GTK_WINDOW (win), "file editor"); + 28 gtk_window_set_default_size (GTK_WINDOW (win), 600, 400); + 29 + 30 boxv = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + 31 gtk_window_set_child (GTK_WINDOW (win), boxv); + 32 + 33 boxh = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + 34 gtk_box_append (GTK_BOX (boxv), boxh); + 35 + 36 dmy1 = gtk_label_new(NULL); /* dummy label for left space */ + 37 gtk_label_set_width_chars (GTK_LABEL (dmy1), 10); + 38 dmy2 = gtk_label_new(NULL); /* dummy label for center space */ + 39 gtk_widget_set_hexpand (dmy2, TRUE); + 40 dmy3 = gtk_label_new(NULL); /* dummy label for right space */ + 41 gtk_label_set_width_chars (GTK_LABEL (dmy3), 10); + 42 btnn = gtk_button_new_with_label ("New"); + 43 btno = gtk_button_new_with_label ("Open"); + 44 btns = gtk_button_new_with_label ("Save"); + 45 btnc = gtk_button_new_with_label ("Close"); + 46 + 47 gtk_box_append (GTK_BOX (boxh), dmy1); + 48 gtk_box_append (GTK_BOX (boxh), btnn); + 49 gtk_box_append (GTK_BOX (boxh), btno); + 50 gtk_box_append (GTK_BOX (boxh), dmy2); + 51 gtk_box_append (GTK_BOX (boxh), btns); + 52 gtk_box_append (GTK_BOX (boxh), btnc); + 53 gtk_box_append (GTK_BOX (boxh), dmy3); + 54 + 55 nb = gtk_notebook_new (); + 56 gtk_widget_set_hexpand (nb, TRUE); + 57 gtk_widget_set_vexpand (nb, TRUE); + 58 gtk_box_append (GTK_BOX (boxv), nb); + 59 + 60 for (i = 0; i < n_files; i++) { + 61 if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + 62 scr = gtk_scrolled_window_new (); + 63 tv = tfe_text_view_new (); + 64 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 65 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 66 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 67 + 68 tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + 69 gtk_text_buffer_set_text (tb, contents, length); + 70 g_free (contents); + 71 filename = g_file_get_basename (files[i]); + 72 lab = gtk_label_new (filename); + 73 gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + 74 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + 75 g_object_set (nbp, "tab-expand", TRUE, NULL); + 76 g_free (filename); + 77 } else { + 78 filename = g_file_get_path (files[i]); + 79 g_print ("No such file: %s.\n", filename); + 80 g_free (filename); + 81 } + 82 } + 83 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + 84 gtk_widget_show (win); + 85 } else + 86 gtk_window_destroy (GTK_WINDOW (win)); + 87 } + +The point is how to build the window. + +- 26-28: Generate GtkApplicationWindow and set its title and default size. +- 30-31: Generate GtkBox `boxv`. +It is a vertical box and a child of GtkApplicationWindow. +It has two children. +The first child is a horizontal box includes buttons. +The second child is GtkNotebook. +- 33-34: Generate GtkBox `boxh` and append it to 'boxv' as a first child. +- 36-41: Generate three dummy labels. +The labels `dmy1` and `dmy3` has a character width of ten. +The other label `dmy2` is set hexpand property TRUE. +This makes the label expands horizontally as long as possible. +- 42-45: Generate four buttons. +- 47-53: Append these GtkLabel and GtkButton to `boxh`. +- 55-58: Generate GtkNotebook and set hexpand and vexpand properties TRUE. +This makes it expands horizontally and vertically as big as possible. +It is appended to `boxv` as the second child. + +The number of lines is 33(=58-26+1) to build the widgets. +And we needed many variables (boxv, boxh, dmy1 ...). +Most of them aren't necessary except building the widgets. +Are there any good solution to reduce these work? + +Gtk provides GtkBuilder. +It reads ui data and builds a window. +It reduces the cumbersom work. + +## Ui file + +First, let's look at the ui file `tfe3.ui` that defines a structure of the widgets. + + 1 + 2 + 3 file editor + 4 600 + 5 400 + 6 + 7 + 8 GTK_ORIENTATION_VERTICAL + 9 + 10 + 11 GTK_ORIENTATION_HORIZONTAL + 12 + 13 + 14 10 + 15 + 16 + 17 + 18 + 19 New + 20 + 21 + 22 + 23 + 24 Open + 25 + 26 + 27 + 28 + 29 TRUE + 30 + 31 + 32 + 33 + 34 Save + 35 + 36 + 37 + 38 + 39 Close + 40 + 41 + 42 + 43 + 44 10 + 45 + 46 + 47 + 48 + 49 + 50 + 51 TRUE + 52 TRUE + 53 + 54 + 55 + 56 + 57 + 58 + 59 + +This is coded with XML structure. +Constructs begin with `<` and end with `>` is called tags. +And it is divided into two parts, start tag and end tag. +For example, `` is a start tag and `` is an end tag. +Ui file begins and ends with interface tags. +Some tags, for example, object tags can have a class and id attributes inside the start tag. + +- 2-5: An object with `GtkApplicationWindow` class and `win` id is defined. +This is the top level window. +And the three properties of the window are defined. +`title` property is "file editor", `default-width` property is 400 and `default-height` property is 300. +- 6: child tag means a child of the object above. +For example, line 7 tells us that GtkBox object which id is "boxv" is a child of `win`. + +Compare this ui file and the lines 26-58 in the source code of `on_open`. +Those two decribe the same structure of widgets. + +## GtkBuilder + +GtkBuilder builds widgets based on the ui file. + + GtkBuilder *build; + + build = gtk_builder_new_from_file ("tfe3.ui"); + win = GTK_WIDGET (gtk_builder_get_object (build, "win")); + gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + nb = GTK_WIDGET (gtk_builder_get_object (build, "nb")); + +The function `gtk_builder_new_from_file` reads the file given as an argument, build the widgets, generate GtkBuilder object and set pointers to the widgets in it. +The function `gtk_builder_get_object (build, "win")` returns the pointer to the widget `win`, which is the id in the ui file. +All the widgets are connected based on the parent-children relationship described in the ui file. +We only need `win` and `nb` for the program after this, so we don't need to take out any other widgets. +This reduces lines in the C source file. + + $ diff tfe2.c tfe3.c + 58a59 + > GtkBuilder *build; + 60,104c61,65 + < GtkWidget *boxv; + < GtkWidget *boxh; + < GtkWidget *dmy1; + < GtkWidget *dmy2; + < GtkWidget *dmy3; + < GtkWidget *btnn; /* button for new */ + < GtkWidget *btno; /* button for open */ + < GtkWidget *btns; /* button for save */ + < GtkWidget *btnc; /* button for close */ + < + < + < win = gtk_application_window_new (GTK_APPLICATION (app)); + < gtk_window_set_title (GTK_WINDOW (win), "file editor"); + < gtk_window_set_default_size (GTK_WINDOW (win), 600, 400); + < + < boxv = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + < gtk_window_set_child (GTK_WINDOW (win), boxv); + < + < boxh = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + < gtk_box_append (GTK_BOX (boxv), boxh); + < + < dmy1 = gtk_label_new(NULL); /* dummy label for left space */ + < gtk_label_set_width_chars (GTK_LABEL (dmy1), 10); + < dmy2 = gtk_label_new(NULL); /* dummy label for center space */ + < gtk_widget_set_hexpand (dmy2, TRUE); + < dmy3 = gtk_label_new(NULL); /* dummy label for right space */ + < gtk_label_set_width_chars (GTK_LABEL (dmy3), 10); + < btnn = gtk_button_new_with_label ("New"); + < btno = gtk_button_new_with_label ("Open"); + < btns = gtk_button_new_with_label ("Save"); + < btnc = gtk_button_new_with_label ("Close"); + < + < gtk_box_append (GTK_BOX (boxh), dmy1); + < gtk_box_append (GTK_BOX (boxh), btnn); + < gtk_box_append (GTK_BOX (boxh), btno); + < gtk_box_append (GTK_BOX (boxh), dmy2); + < gtk_box_append (GTK_BOX (boxh), btns); + < gtk_box_append (GTK_BOX (boxh), btnc); + < gtk_box_append (GTK_BOX (boxh), dmy3); + < + < nb = gtk_notebook_new (); + < gtk_widget_set_hexpand (nb, TRUE); + < gtk_widget_set_vexpand (nb, TRUE); + < gtk_box_append (GTK_BOX (boxv), nb); + < + --- + > build = gtk_builder_new_from_file ("tfe3.ui"); + > win = GTK_WIDGET (gtk_builder_get_object (build, "win")); + > gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + > nb = GTK_WIDGET (gtk_builder_get_object (build, "nb")); + > g_object_unref(build); + 139c100 + < app = gtk_application_new ("com.github.ToshioCP.tfe2", G_APPLICATION_HANDLES_OPEN); + --- + > app = gtk_application_new ("com.github.ToshioCP.tfe3", G_APPLICATION_HANDLES_OPEN); + +`65,104c61,65` means 40 (=104-65+1) lines change to 5 (=65-61+1) lines. +Therefore 35 lines are reduced. +Using ui file not only shortens C source files, but also makes the widgets' structure clear. + +Now I'll show you the C source code `tfe3.c`. +Only functions `on_open` are shown as follows. + + 1 static void + 2 on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + 3 GtkWidget *win; + 4 GtkWidget *nb; + 5 GtkWidget *lab; + 6 GtkNotebookPage *nbp; + 7 GtkWidget *scr; + 8 GtkWidget *tv; + 9 GtkTextBuffer *tb; + 10 char *contents; + 11 gsize length; + 12 char *filename; + 13 int i; + 14 GtkBuilder *build; + 15 + 16 build = gtk_builder_new_from_file ("tfe3.ui"); + 17 win = GTK_WIDGET (gtk_builder_get_object (build, "win")); + 18 gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + 19 nb = GTK_WIDGET (gtk_builder_get_object (build, "nb")); + 20 g_object_unref(build); + 21 for (i = 0; i < n_files; i++) { + 22 if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + 23 scr = gtk_scrolled_window_new (); + 24 tv = tfe_text_view_new (); + 25 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 26 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 27 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 28 + 29 tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + 30 gtk_text_buffer_set_text (tb, contents, length); + 31 g_free (contents); + 32 filename = g_file_get_basename (files[i]); + 33 lab = gtk_label_new (filename); + 34 gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + 35 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + 36 g_object_set (nbp, "tab-expand", TRUE, NULL); + 37 g_free (filename); + 38 } else { + 39 filename = g_file_get_path (files[i]); + 40 g_print ("No such file: %s.\n", filename); + 41 g_free (filename); + 42 } + 43 } + 44 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + 45 gtk_widget_show (win); + 46 } else + 47 gtk_window_destroy (GTK_WINDOW (win)); + 48 } + +### Using ui string + +GtkBuilder can build widgets using string. +Use the function gtk\_builder\_new\_from\_string instead of gtk\_builder\_new\_from\_file. + + char *uistring; + + uistring = + "" + "" + "file editor" + "600" + "400" + "" + "" + "GTK_ORIENTATION_VERTICAL" + ... ... ... + ... ... ... + ""; + + build = gtk_builder_new_from_stringfile (uistring); + +This method has an advantage and disadvantage. +The advantage is that the ui string is written in the source code. +So ui file is not necessary on runtime. +The disadvantage is that writing C string is a bit bothersome because of the double quotes. +If you want to use this method, you should write a script that transforms ui file into C-string. + +- add backslash before each double quote. +- add double quote at the left and right. + +### Using Gresource + +Using Gresource is similar to using string. +But Gresource is compressed binary data, not text data. +And there's a compiler that compiles ui file into Gresource. +It can compile not only text files but also binary files such as images, sounds and so on. +And after compilation, it bundles them up into one Gresource object. + +An xml file is necessary for the resource compiler `glib-compile-resources`. +It describes resource files. + + 1 + 2 + 3 + 4 tfe3.ui + 5 + 6 + +- 2: gresources tag can include mulitple gresources (gresource tags). +However, this xml has only one gresource. +- 3: The gresource has a prefix `/com/github/ToshioCP/tfe3`. +- 4: The gresource has tfe3.ui. +And it is pointed by `/com/github/ToshioCP/tfe3/tfe3.ui` because it needs prefix. +If you want to add more files, then insert them between line 4 and 5. + +Save this xml text to `tfe3.gresource.xml`. +The gresource compiler `glib-compile-resources` shows its ussage with the argument `--help`. + + $ LANG=C glib-compile-resources --help + Usage: + glib-compile-resources [OPTION?] FILE + + Compile a resource specification into a resource file. + Resource specification files have the extension .gresource.xml, + and the resource file have the extension called .gresource. + + Help Options: + -h, --help Show help options + + Application Options: + --version Show program version and exit + --target=FILE Name of the output file + --sourcedir=DIRECTORY The directories to load files referenced in FILE from (default: current directory) + --generate Generate output in the format selected for by the target filename extension + --generate-header Generate source header + --generate-source Generate source code used to link in the resource file into your code + --generate-dependencies Generate dependency list + --dependency-file=FILE Name of the dependency file to generate + --generate-phony-targets Include phony targets in the generated dependency file + --manual-register Don?t automatically create and register resource + --internal Don?t export functions; declare them G_GNUC_INTERNAL + --external-data Don?t embed resource data in the C file; assume it's linked externally instead + --c-name C identifier name used for the generated source code + + +Now run the compiler. + + $ glib-compile-resources tfe3.gresource.xml --target=resources.c --generate-source + +Then a C source file `resources.c` is generated. +Modify tfe3.c and save it as tfe3_r.c + + # include "resources.c" + ... ... ... + ... ... ... + build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe3/tfe3.ui"); + ... ... ... + ... ... ... + +Then, compile and run it. +The window appears and it is the same as the screenshot at the beginning of this page. + +Up: [Readme.md](src/Readme.md), Prev: [Section 5}](src/sec5.src.md), Next: [Section 7[(src/sec7.src.md) \ No newline at end of file diff --git a/sec7.md b/sec7.md new file mode 100644 index 0000000..27922e0 --- /dev/null +++ b/sec7.md @@ -0,0 +1,421 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 6}](src/sec6.src.md), Next: [Section 8[(src/sec8.src.md)# Build system + +## What do we need to think about building? + +We've managed to compile a small editor so far. +But Some bad signs are beginning to appear. + +- We have only one C source file and put everything into it. +We need to sort it out. +- There are two compilers, `gcc` and `glib-compile-resources`. +We want to control them by one building tool. + +## Divide a C source file into two parts. + +When you divide C source file into several parts, each file should contain only one thing. +For example, our source has two things, the definition of TfeTextView and functions related to GtkApplication and GtkApplicationWindow. +It is a good idea to separate them into two files, `tfetextview.c` and `tfe.c`. + +- `tfetextview.c` includes the definition and functions of TfeTextView. +- `tfe.c` includes functions like `main`, `on_activate`, `on_open` and so on, which relate to GtkApplication and GtkApplicationWindow + +Now we have three source files, `tfetextview.c`, `tfe.c` and `tfe3.ui`. +The `3` of `tfe3.ui` is like a version number. +Managing version with filenames is one possible idea but it may make bothersome complicated problem. +You need to rewrite filename in each version and it affects to contents of sourcefiles that refer to filenames. +So, we should take `3` away from the filename. + +In `tfe.c` the function `tfe_text_view_new` is invoked to generate TfeTextView. +But it is defined in `tfetextview.c`, not `tfe.c`. +The lack of the declaration (not definition) of `tfe_text_view_new` makes error when `tfe.c` is compiled. +The declaration is necessary in `tfe.c`. +Those public information is usually written in header files. +It has `.h` suffix like `tfetextview.h` +And header files are included by C source files. +For example, `tfetextview.h` is included by `tfe.c`. + +`tfetextview.h` + + 1 #include + 2 + 3 #define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () + 4 G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + 5 + 6 void + 7 tfe_text_view_set_file (TfeTextView *tv, GFile *f); + 8 + 9 GFile * + 10 tfe_text_view_get_file (TfeTextView *tv); + 11 + 12 GtkWidget * + 13 tfe_text_view_new (void); + 14 + +`tfetextview.c` + + 1 #include + 2 #include "tfetextview.h" + 3 + 4 struct _TfeTextView + 5 { + 6 GtkTextView parent; + 7 GFile *file; + 8 }; + 9 + 10 G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + 11 + 12 static void + 13 tfe_text_view_init (TfeTextView *tv) { + 14 } + 15 + 16 static void + 17 tfe_text_view_class_init (TfeTextViewClass *class) { + 18 } + 19 + 20 void + 21 tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + 22 tv -> file = f; + 23 } + 24 + 25 GFile * + 26 tfe_text_view_get_file (TfeTextView *tv) { + 27 return tv -> file; + 28 } + 29 + 30 GtkWidget * + 31 tfe_text_view_new (void) { + 32 return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + 33 } + 34 + +`tfe.c` + + 1 #include + 2 #include "tfetextview.h" + 3 + 4 static void + 5 on_activate (GApplication *app, gpointer user_data) { + 6 g_print ("You need a filename argument.\n"); + 7 } + 8 + 9 static void + 10 on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + 11 GtkWidget *win; + 12 GtkWidget *nb; + 13 GtkWidget *lab; + 14 GtkNotebookPage *nbp; + 15 GtkWidget *scr; + 16 GtkWidget *tv; + 17 GtkTextBuffer *tb; + 18 char *contents; + 19 gsize length; + 20 char *filename; + 21 int i; + 22 GtkBuilder *build; + 23 + 24 build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe3/tfe.ui"); + 25 win = GTK_WIDGET (gtk_builder_get_object (build, "win")); + 26 gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + 27 nb = GTK_WIDGET (gtk_builder_get_object (build, "nb")); + 28 g_object_unref (build); + 29 for (i = 0; i < n_files; i++) { + 30 if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + 31 scr = gtk_scrolled_window_new (NULL, NULL); + 32 tv = tfe_text_view_new (); + 33 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 34 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 35 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + 36 + 37 tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + 38 gtk_text_buffer_set_text (tb, contents, length); + 39 g_free (contents); + 40 filename = g_file_get_basename (files[i]); + 41 lab = gtk_label_new (filename); + 42 gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + 43 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + 44 g_object_set (nbp, "tab-expand", TRUE, NULL); + 45 g_free (filename); + 46 } else { + 47 filename = g_file_get_path (files[i]); + 48 g_print ("No such file: %s.\n", filename); + 49 g_free (filename); + 50 } + 51 } + 52 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + 53 gtk_widget_show (win); + 54 } else + 55 gtk_window_destroy (GTK_WINDOW (win)); + 56 } + 57 + 58 int + 59 main (int argc, char **argv) { + 60 GtkApplication *app; + 61 int stat; + 62 + 63 app = gtk_application_new ("com.github.ToshioCP.tfe3", G_APPLICATION_HANDLES_OPEN); + 64 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 65 g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + 66 stat =g_application_run (G_APPLICATION (app), argc, argv); + 67 g_object_unref (app); + 68 return stat; + 69 } + 70 + +`tfe.ui` + + 1 + 2 + 3 file editor + 4 600 + 5 400 + 6 + 7 + 8 GTK_ORIENTATION_VERTICAL + 9 + 10 + 11 GTK_ORIENTATION_HORIZONTAL + 12 + 13 + 14 10 + 15 + 16 + 17 + 18 + 19 New + 20 + 21 + 22 + 23 + 24 Open + 25 + 26 + 27 + 28 + 29 TRUE + 30 + 31 + 32 + 33 + 34 Save + 35 + 36 + 37 + 38 + 39 Close + 40 + 41 + 42 + 43 + 44 10 + 45 + 46 + 47 + 48 + 49 + 50 + 51 TRUE + 52 TRUE + 53 + 54 + 55 + 56 + 57 + 58 + 59 + +`tfe.gresource.xml` + + 1 + 2 + 3 + 4 tfe.ui + 5 + 6 + +## Make + +Dividing a file makes it easy to maintain source files. +But now we are faced with a new problem. +The building step increases. + +- Compile the ui file `tfe.ui` into `resources.c`. +- Compile `tfe.c` into `tfe.o` (object file). +- Compile `tfetextview.c` into `tfetextview.o`. +- Compile `resources.c` into `resources.o`. +- Link all the object files into application `tfe`. + +Now build tool is necessary to manage it. +Make is one of the build tools. +It was originally created in 1976. +So it is an old and widely used program. + +Make analyzes Makefile and executes compilers. +All instructions are written in Makefile. + + sample.o: sample.c + gcc -o sample.o sample.c + +The sample of Malefile above consists of three elements, `sample.o`, `sample.c` and `gcc -0 sample.o sample.c`. + +- `sample.o` is called target. +- `sample.c` is prerequisite. +- `gcc -0 sample.o sample.c` is recipe. +Recipes follow tab characters, not spaces. +(It is very important. Use tab not space, or make won't work as you expected). + +The rule is: + +If a prerequisite modified later than a target, then make executes the recipe. + +In the example above, if `sample.c` is modified after the generation of `sample.o`, then make executes gcc and compile `sample.c` into `sample.o`. +If the modification time of `sample.c` is older then the generation of `sample.o`, then no compiling is necesarry, so make does nothing. + +The Makefile for `tfe` is as follows. + + 1 all: tfe + 2 + 3 tfe: tfe.o tfetextview.o resources.o + 4 gcc -o tfe tfe.o tfetextview.o resources.o `pkg-config --libs gtk4` + 5 + 6 tfe.o: tfe.c tfetextview.h + 7 gcc -c -o tfe.o `pkg-config --cflags gtk4` tfe.c + 8 tfetextview.o: tfetextview.c tfetextview.h + 9 gcc -c -o tfetextview.o `pkg-config --cflags gtk4` tfetextview.c + 10 resources.o: resources.c + 11 gcc -c -o resources.o `pkg-config --cflags gtk4` resources.c + 12 + 13 resources.c: tfe.gresource.xml tfe.ui + 14 glib-compile-resources tfe.gresource.xml --target=resources.c --generate-source + 15 + 16 .Phony: clean + 17 + 18 clean: + 19 rm -f tfe tfe.o tfetextview.o resources.o resources.c + +Only you need is to type `make`. + + $ make + gcc -c -o tfe.o `pkg-config --cflags gtk4` tfe.c + gcc -c -o tfetextview.o `pkg-config --cflags gtk4` tfetextview.c + glib-compile-resources tfe.gresource.xml --target=resources.c --generate-source + gcc -c -o resources.o `pkg-config --cflags gtk4` resources.c + gcc -o tfe tfe.o tfetextview.o resources.o `pkg-config --libs gtk4` + +I used only very basic rules to write this Makefile. +There are many more convenient methods to make it more compact. +But it needs long story to explain. +So I want to finish the explanation about make. + +## Rake + +Rake is a similar program to make. +It is written in Ruby code. +If you don't use Ruby, you don't need to read this subsection. +However, Ruby is really sophisticated and recommendable script language. + +- Rakefile controls the behavior of `rake`. +- You can write any ruby code in Rakefile. + +Rake has task and file task, which is similar to target, prerequisite and recipe in make. + + 1 require 'rake/clean' + 2 + 3 targetfile = "tfe" + 4 srcfiles = FileList["tfe.c", "tfetextview.c", "resources.c"] + 5 rscfile = srcfiles[2] + 6 objfiles = srcfiles.gsub(/.c$/, '.o') + 7 + 8 CLEAN.include(targetfile, objfiles, rscfile) + 9 + 10 task default: targetfile + 11 + 12 file targetfile => objfiles do |t| + 13 sh "gcc -o #{t.name} #{t.prerequisites.join(' ')} `pkg-config --libs gtk4`" + 14 end + 15 + 16 objfiles.each do |obj| + 17 src = obj.gsub(/.o$/,'.c') + 18 file obj => src do |t| + 19 sh "gcc -c -o #{t.name} `pkg-config --cflags gtk4` #{t.source} " + 20 end + 21 end + 22 + 23 file rscfile => ["tfe.gresource.xml", "tfe.ui"] do |t| + 24 sh "glib-compile-resources #{t.prerequisites[0]} --target=#{t.name} --generate-source" + 25 end + +What `Rakefile` describes is almost same as `Makefile` in the previous subsection. + +- 3-6: define target file, source file and so on. +- 1, 8: Load clean library. And define CLEAN file list. +The files included by CLEAN will be removed when `rake clean` is typed on the command line. +- 10: default target depends on targetfile. +default is the final goal of tasks. +- 12-14: targetfile depends on objfiles. +The variable `t` is a task object. + - t.name is a target name + - t.prerequisites is an array of prerequisits. + - t.source is the first element of prerequisites. +- sh is a method to give the following string to shell as an argument and execute. +- 16-21: Loop by each element of the array of objfiles. Each object depends on corresponding source file. +- 23-25: resouce file depends on xml file and ui file. + +Rakefile might seem to be difficult for beginners. +But, you can use any ruby syntax in Rakefile, so it is really flexible. +If you practice Ruby and Rakefile, it will be highly productive tools. + +## Meson and ninja + +Meson is one of the most popular building tool despite the developing version. +And ninja is similar to make but much faster than make. +Several years ago, most of the C developers used autotools and make. +But now the situation has changed. +Many developers are using meson and ninja now. + +To use meson, you first need to write `meson.build` file. + + 1 project('tfe', 'c') + 2 + 3 gtkdep = dependency('gtk4') + 4 + 5 gnome=import('gnome') + 6 resources = gnome.compile_resources('resources','tfe.gresource.xml') + 7 + 8 sourcefiles=files('tfe.c', 'tfetextview.c') + 9 + 10 executable('tfe', sourcefiles, resources, dependencies: gtkdep) + +- 1: The function `project` defines things about the project. +The first parameter is the name of the project and the second is the programing language. +- 2: `dependency` function defines a dependency that is taken by `pkg-config`. +We put `gtk4` as an argument. +- 5: `import` function inports a module. +In line 5, gnome module is imported and assignd to the variable `gnome`. +gnome module provides helper tools to build GTK programs. +- 6: `.compile_resources` is a method of gnome module and compile files to resources under the instruction of xml file. +In line 6, the resource filename is `resources`, which means `resources.c` and `resources.h`, and xml file is `tfe.gresource.xml`. +This method generates C source file by default. +- 8: define source files. +- 10: executable function generates a target file by building source files. +The first parameter is the filename of the target. The following parameters are source files. +The last parameter has a option `dependencies`. +In line 10 it is `gtkdep` which is defined in line 3. + +Now run meson and ninja. + + $ meson _build + $ ninja -C _build + +Then, the executable file `tfe` has been generated under the directory `_build`. + + $ _build/tfe tfe.c tfetextview.c + +Then the window appears. + +I show you three build tools. +I think meson and ninja is the best choice for the present. + +We divided a file into some categorized files and used a build tool. +This method is used by many developers. + +Up: [Readme.md](src/Readme.md), Prev: [Section 6}](src/sec6.src.md), Next: [Section 8[(src/sec8.src.md) \ No newline at end of file diff --git a/sec8.md b/sec8.md new file mode 100644 index 0000000..60b2a9f --- /dev/null +++ b/sec8.md @@ -0,0 +1,426 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 7}](src/sec7.src.md), Next: [Section 9[(src/sec9.src.md)# Instance and class + +This section and the following four sections are descriptions about next version of the text file editor (tfe). +It is tfe5. +It has many changes from the prior version. +All the sources are listed after the five sections. + +## Encapsulation + +We've divided C source file into two parts. +But it is not enough in terms of encapsulation. + +- `tfe.c` includes everything other than TfeTextView. +It should be divided at least into two parts, `tfeapplication.c` and `tfenotebook.c`. +- Header files also need to be organized. + +However, first of all, I'd like to focus on the object TfeTextView. +It is a child object of GtkTextView. +And important thing is it has newly added Gfile in it. + +- What is necessary to GFile when generating (or initializing) TfeTextView? +- What is necessary to GFile when destructing TfeTextView? +- TfeTextView should read/write a file by itself or not? +- How it communicate with objects outside? + +You need to know at least class/instance and signals before thinking about them. +I will explain them in this section and the next section. +After that I will explain: + +- Organizing functions. +- How to use FileChooserDialog + +## GObject and its children + +GObject and its children are objects, which have both class and instance. +First, think about instance of objects. +Instance is structured memories and the structure is described using C language structure. +The following is a structure of TfeTextView. + + /* This typedef statement is automaticaly generated by the macro G_DECLARE_FINAL_TYPE */ + typedef struct _TfeTextView TfeTextView; + + struct _TfeTextView { + GtkTextView parent; + GtkTextBuffer *tb; + GFile *file; + gboolean changed; + }; + +Each instance has similar structure as above. + +- `parent` is the structure of GtkTextView which is the parent object of TfeTextView. +- `tb` is a pointer to GtkTextBuffer connected to GtkTextView. +- `file` is a pointer to GFile which is a file corresponds to `tb` (or NULL is available). +- `changed` is TRUE if the buffer has been modified, FALSE if not. + +Comparing to the source file in the previous section, `tb` and `changed` are added. +Notice the program above is the declaration of the structure, not the definition. +So, no memories are allocated at this moment. +They are to be allocated when `tfe_text_view_new` function is invoked. + +You can find the declaration of the ancestors of TfeTextView in the sourcefiles of GTK and GLib. +The following is extracts from the source files (not exactly the same). + + typedef struct _GObject GObject; + typedef struct _GObject GInitiallyUnowned; + struct _GObject + { + GTypeInstance g_type_instance; + volatile guint ref_count; + GData *qdata; + }; + + typedef struct _GtkWidget GtkWidget; + struct _GtkWidget + { + GInitiallyUnowned parent_instance; + GtkWidgetPrivate *priv; + }; + + typedef struct _GtkTextView GtkTextView; + struct _GtkTextView + { + GtkWidget parent_instance; + GtkTextViewPrivate *priv; + }; + +In each structure, its parent instance is declared at the top of the members. +So, every ancestors is included in the child instance. +This is very important. +It guarantees a child widget to derive all the features from ancestors. +The structure of `TfeTextView` is like the following diagram. + +![The structure of the instance TfeTextView](TfeTextView.png) + + +## Generate TfeTextView instance + +The function `tfe_text_view_new` generates a new TfeTextView instance. + + 1 GtkWidget * + 2 tfe_text_view_new (void) { + 3 return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + 4 } + +When this function is run, the following procedure is gone through. + +1. Initialize GObject instance in TfeTextView instance. +2. Initialize GtkWidget instance in TfeTextView instance. +3. Initialize GtkTextView instance in TfeTextView instance. +4. Initialize TfeTextView instance. + +Step one through three is done automatically. +Step four is done by the function `tfe_text_view_init`. + +> (In the same way, `gtk_text_view_init`, `gtk_widget_init` and `g_object_init` is the initialization functions of GtkTextView, GtkWidget and GObject respectively. +> You can find them in the GTK or GLib source file.) + + 1 static void + 2 on_changed (GtkTextBuffer *tb, TfeTextView *tv) { + 3 tv->changed=TRUE; + 4 } + 5 + 6 static void + 7 tfe_text_view_init (TfeTextView *tv) { + 8 tv->tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 9 tv->file = NULL; + 10 tv->changed = FALSE; + 11 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + 12 g_signal_connect (tv->tb, "changed", G_CALLBACK (on_changed), tv); + 13 } + +`tfe_text_view_init` initializes the instance. + +- 8-10: Initialize `tb`, `file` and `changed`. +- 11: Set the wrap mode of GtkTextView as GTK\_WRAP\_WORD\_CHAR. +- 12: Connect "changed" signal to a handler `on_changed`. +"changed" signal is defined in GtkTextBuffer. +It is emitted when the contents in the buffer is changed. +- 2-4: `on_changed` handler records TRUE to `tv->changed` when "changed" signal is emitted. + +## Functions and Classes + +In Gtk, all objects derived from GObject have class and instance. +Instance is memories which has a structure defined by C structure declaration as I mentioned in the previous two subsections. +And instance can be generated two or more. +Those instances have the same structure. +However, structured memories are insufficient to define its behavior. +We need at least two things. +One is functions and the other is class. + +You've already seen many functions, for example, `tfe_text_view_new` is a function to generate TfeTextView instance. +These functions are similar to object methods in object oriented languages such as Java and Ruby. +Functions are public, which means that they are expected to be used by other objects. + +Class comprises mainly pointers to functions. +And the functions are used by the object itself or its children objects. +For example, GObject class is declared in `gobject.h` in GLib source files. + + 1 typedef struct _GObjectClass GObjectClass; + 2 typedef struct _GObjectClass GInitiallyUnownedClass; + 3 + 4 struct _GObjectClass { + 5 GTypeClass g_type_class; + 6 /*< private >*/ + 7 GSList *construct_properties; + 8 /*< public >*/ + 9 /* seldom overidden */ + 10 GObject* (*constructor) (GType type, + 11 guint n_construct_properties, + 12 GObjectConstructParam *construct_properties); + 13 /* overridable methods */ + 14 void (*set_property) (GObject *object, + 15 guint property_id, + 16 const GValue *value, + 17 GParamSpec *pspec); + 18 void (*get_property) (GObject *object, + 19 guint property_id, + 20 GValue *value, + 21 GParamSpec *pspec); + 22 void (*dispose) (GObject *object); + 23 void (*finalize) (GObject *object); + 24 /* seldom overidden */ + 25 void (*dispatch_properties_changed) (GObject *object, + 26 guint n_pspecs, + 27 GParamSpec **pspecs); + 28 /* signals */ + 29 void (*notify) (GObject *object, + 30 GParamSpec *pspec); + 31 + 32 /* called when done constructing */ + 33 void (*constructed) (GObject *object); + 34 /*< private >*/ + 35 gsize flags; + 36 /* padding */ + 37 gpointer pdummy[6]; + 38 }; + +I'd like to explain some of the members. +There's a pointer to the function `dispose` in line 22. + + void (*dispose) (GObject *object); + +The declaration is a bit complicated. +The asterisk before the identifier `dispose` means pointer. +So, the pointer `disopse` points a function which has one parameter , which points a GObject structure, and returns no value because of void type. +In the same way, line 23 says `finalize` is a pointer to the function which has one paremeter, which points a GObject structure, and returns no value. + + void (*finalize) (GObject *object); + +Look at the declaration of `_GObjectClass` so that you would find that most of the members are pointers to functions. + +- 10: A function pointed by `constructor` is called when the instance is generated. It completes the initialization of the instance. +- 22: A function pointed by `dispose` is called when the instance destructs itself. Destruction process is divided into two phases. First is called disposing and the instance releases all the references to other instances. The second is finalizing. +- 23: A funtion pointed by `finalize` finishes the destruction process. +- The other pointers point functions which are called during the instance lives. + +## TfeTextView class + +TfeTextView class is a structure and it includes all its ancestors' class in it. +Let's look at all the classes from GObject, which is the top level object, to TfeTextView object, which is the lowest. + + GObject -- GInitiallyUnowned -- GtkWidget -- GtkTextView -- TfeTextView + +The following is extracts from the source files (not exactly the same). + + 1 struct _GtkWidgetClass { + 2 GInitiallyUnownedClass parent_class; + 3 /*< public >*/ + 4 guint activate_signal; + 5 /* basics */ + 6 void (* show) (GtkWidget *widget); + 7 void (* hide) (GtkWidget *widget); + 8 void (* map) (GtkWidget *widget); + 9 void (* unmap) (GtkWidget *widget); + 10 void (* realize) (GtkWidget *widget); + 11 void (* unrealize) (GtkWidget *widget); + 12 void (* root) (GtkWidget *widget); + 13 void (* unroot) (GtkWidget *widget); + 14 void (* size_allocate) (GtkWidget *widget, + 15 int width, + 16 int height, + 17 int baseline); + 18 void (* state_flags_changed) (GtkWidget *widget, + 19 GtkStateFlags previous_state_flags); + 20 void (* direction_changed) (GtkWidget *widget, + 21 GtkTextDirection previous_direction); + 22 void (* grab_notify) (GtkWidget *widget, + 23 gboolean was_grabbed); + 24 /* size requests */ + 25 GtkSizeRequestMode (* get_request_mode) (GtkWidget *widget); + 26 void (* measure) (GtkWidget *widget, + 27 GtkOrientation orientation, + 28 int for_size, + 29 int *minimum, + 30 int *natural, + 31 int *minimum_baseline, + 32 int *natural_baseline); + 33 /* Mnemonics */ + 34 gboolean (* mnemonic_activate) (GtkWidget *widget, + 35 gboolean group_cycling); + 36 /* explicit focus */ + 37 gboolean (* grab_focus) (GtkWidget *widget); + 38 gboolean (* focus) (GtkWidget *widget, + 39 GtkDirectionType direction); + 40 void (* set_focus_child) (GtkWidget *widget, + 41 GtkWidget *child); + 42 /* keyboard navigation */ + 43 void (* move_focus) (GtkWidget *widget, + 44 GtkDirectionType direction); + 45 gboolean (* keynav_failed) (GtkWidget *widget, + 46 GtkDirectionType direction); + 47 /* accessibility support + 48 */ + 49 AtkObject * (* get_accessible) (GtkWidget *widget); + 50 gboolean (* query_tooltip) (GtkWidget *widget, + 51 gint x, + 52 gint y, + 53 gboolean keyboard_tooltip, + 54 GtkTooltip *tooltip); + 55 void (* compute_expand) (GtkWidget *widget, + 56 gboolean *hexpand_p, + 57 gboolean *vexpand_p); + 58 void (* css_changed) (GtkWidget *widget, + 59 GtkCssStyleChange *change); + 60 void (* system_setting_changed) (GtkWidget *widget, + 61 GtkSystemSetting settings); + 62 void (* snapshot) (GtkWidget *widget, + 63 GtkSnapshot *snapshot); + 64 gboolean (* contains) (GtkWidget *widget, + 65 gdouble x, + 66 gdouble y); + 67 /*< private >*/ + 68 GtkWidgetClassPrivate *priv; + 69 gpointer padding[8]; + 70 }; + 71 + 72 struct _GtkTextViewClass { + 73 GtkWidgetClass parent_class; + 74 /*< public >*/ + 75 void (* move_cursor) (GtkTextView *text_view, + 76 GtkMovementStep step, + 77 gint count, + 78 gboolean extend_selection); + 79 void (* set_anchor) (GtkTextView *text_view); + 80 void (* insert_at_cursor) (GtkTextView *text_view, + 81 const gchar *str); + 82 void (* delete_from_cursor) (GtkTextView *text_view, + 83 GtkDeleteType type, + 84 gint count); + 85 void (* backspace) (GtkTextView *text_view); + 86 void (* cut_clipboard) (GtkTextView *text_view); + 87 void (* copy_clipboard) (GtkTextView *text_view); + 88 void (* paste_clipboard) (GtkTextView *text_view); + 89 void (* toggle_overwrite) (GtkTextView *text_view); + 90 GtkTextBuffer * (* create_buffer) (GtkTextView *text_view); + 91 void (* snapshot_layer) (GtkTextView *text_view, + 92 GtkTextViewLayer layer, + 93 GtkSnapshot *snapshot); + 94 gboolean (* extend_selection) (GtkTextView *text_view, + 95 GtkTextExtendSelection granularity, + 96 const GtkTextIter *location, + 97 GtkTextIter *start, + 98 GtkTextIter *end); + 99 void (* insert_emoji) (GtkTextView *text_view); + 100 /*< private >*/ + 101 gpointer padding[8]; + 102 }; + 103 + 104 /* The following definition is generated by the macro G_DECLARE_FINAL_TYPE + 105 typedef struct { + 106 GtkTextView parent_class; + 107 } TfeTextViewClass; + 108 + +- 105-107: This three lines are generated by the macro G\_DECLARE\_FINAL\_TYPE. +So, they are not written in either `tfe_text_view.h` or `tfe_text_view.c`. +- 2, 73, 106: Each derived class puts its parent class at the first member of its structure. +It is the same as instance structures. +- Class members in ancesters are open to their child class. +So, they can be changed in `tfe_text_view_class_init` function. +For example, the `dispose` pointer in GObjectClass will be overridden later in `tfe_text_view_class_init`. +(Override is an object oriented programing terminology. +Override is rewriting ancestors' class methods in the child class.) +- Some class methods are often overridden. +`set_property`, `get_property`, `dispose`, `finalize` and `constructed` are such methods. + +TfeTextViewClass includes its ancsestors' class in it. +It is illustrated in the following diagram. + +![The structure of TfeTextView Class](TfeTextViewClass.png) + +## Destruction of TfeTextView + +Every Object derived from GObject has a reference count. +If an object A uses an object B, then A keeps a pointr to B in A and at the same time increaces the reference count of B by one with the function `g_object_ref (B)`. +If A doesn't need B any longer, then A discards the pointer to B (usually it is done by assigning NULL to the pointer) and decreaces the reference count of B by one with the function `g_object_unref (B)`. + +If two objects A and B refer to C, then the reference count of C is two. +After A used C and if A no longer needs C, A discards the pointer to C and decreases the reference count in C by one. +Now the reference count of C is one. +In the same way, when B no longer needs C, B discards the pointer to C and decreases the reference count in C by one. +At this moment, no object refers C and the reference count of C is zero. +This means C is no longer useful. +Then C destructs itself and finally the memories allocated to C is freed. + +![Reference count of B](refcount.png) + +The idea above is based on an assumption that an object refered by nothing has reference count of zero. +When the reference count drops to zero, the object starts its destruction process. +The destruction process is split in two phases: disposing and finalizing. +In the disposing process, the object invokes the handler pointed by `dispose` in its class to release all references to other objects. +In the finalizing process, it invokes the handler pointed by `finalize` in its class to complete the destruction process. + +In the destruction process of TfeTextView, the reference count of widgets related to TfeTextView is automatically decreased. +But GFile pointed by `tv->file` needs to decrease its reference count by one. +You must write the code in the dispose handler `tfe_text_view_dispose`. + + 1 static void + 2 tfe_text_view_dispose (GObject *gobject) { + 3 TfeTextView *tv = TFE_TEXT_VIEW (gobject); + 4 + 5 if (G_IS_FILE (tv->file)) + 6 g_clear_object (&tv->file); + 7 + 8 G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject); + 9 } + +- 5,6: If `tv->file` points a GFile, decrease its reference count. +`g_clear_object` decreases the reference count and assigns NULL to `tv->file`. In dispose handlers, we usually use `g_clear_object` rather than `g_object_unref`. +- 8: invoke parent's despose handler. (This will be explained later.) + +In the desposing process, the object uses the pointer in its class to call the handler. +Therefore, `tfe_text_view_dispose` needs to be registerd in the class when the TfeTextView class is initialized. +The function `tfe_text_view_class_init` is the class initialization function and it is declared in the replacement produced by `G_DEFINE_TYPE` macro. + + static void + tfe_text_view_class_init (TfeTextViewClass *class) { + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = tfe_text_view_dispose; + + } + +Each ancestors' class is generated before TfeTextViewClass. +Therefore, there are four classes and each class has a pointer to each dispose handler. +Look at the following diagram. +There are four classes -- GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass. +Each class has its own dispose handler -- `dh1`, `dh2`, `dh3` and `tfe_text_view_dispose`. + +![dispose handers](dispose_handler.png) + +Now, look at the `tfe_text_view_dispose` program above. +It first releases the reference to GFile object pointed by `tv->file`. +Then it invokes its parent's dispose handler in line 8. + + G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject); + +`tfe_text_view_parent_class`,which is made by `G_DEFINE_TYPE` macro, is a pointer that points the parent object class. +Therefore, `G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose` points the handler `dh3` in the diagram above. +And `gobject` is a pointer to TfeTextView object which is casted as a GObject instanse. +`dh3` releases all the references to objects in the GtkTextView part (it is actually the private area pointed by `prev`) in TfeTextView instance. +After that, `dh3` calls `dh2`, and `dh2` calls `dh1`. +Finally all the references are released. + +Up: [Readme.md](src/Readme.md), Prev: [Section 7}](src/sec7.src.md), Next: [Section 9[(src/sec9.src.md) \ No newline at end of file diff --git a/sec9.md b/sec9.md new file mode 100644 index 0000000..0c97a9d --- /dev/null +++ b/sec9.md @@ -0,0 +1,162 @@ +Up: [Readme.md](src/Readme.md), Prev: [Section 8}](src/sec8.src.md), Next: [Section 10[(src/sec10.src.md)# Signals + +## Signals + +In GTK programming, each object is capsulated. +And it is not recommended to use global variables because they tend to make the program complicated. +So, we need something to communicate between objects. +There are two ways to do so. + +- Functions. +For example, `tb = gtk_text_view_get_buffer (tv)`. +The function caller requests `tv`, which is a GtkTextView object, to give back `tb`, which is a GtkTextBuffer object connected to `tv`. +- Signals. +For example, `activate` signal on GApplication object. +When the application is activated, the signal is emitted. +Then the handler, which has been connected to the signal, is invoked. + +The caller of the function or the handler connected to the signal is usually outside of the object. +One of the difference between these two is that the object is active or passive. +In functions the object responds to the caller. +In signals the object actively sends a signal to the handler. + +GObject signal can be registered, connected and emitted. + +1. A signal is registered with the object type on which it can be emitted. +This is done usually when the class is initialized. +2. It is connected to a handler by `g_connect_signal` or its family functions. +3. When it is emmitted, the connected handler is invoked. + +Step one and three are done in the object on which the signal is emitted. +Step two is done outside the objects. + +## Signal registration + +In TfeTextView, two signals are registered. + +- "change-file" signal. +This signal is emitted when `tv->file` is changed. +- "open-response" signal. +`tfe_text_view_open` function is not able to return the status because of using GtkFileChooserDialog. +This signal is emitted instead of the return value of the function. + +Static variable is used to store the signal ID. +If you need to register two or more signals, static array is usually used. + + enum { + CHANGE_FILE, + OPEN_RESPONSE, + NUMBER_OF_SIGNALS + }; + + static guint tfe_text_view_signals[NUMBER_OF_SIGNALS]; + +Signal registration codes are written in the class initialization function. + + 1 static void + 2 tfe_text_view_class_init (TfeTextViewClass *class) { + 3 GObjectClass *object_class = G_OBJECT_CLASS (class); + 4 + 5 object_class->dispose = tfe_text_view_dispose; + 6 tfe_text_view_signals[CHANGE_FILE] = g_signal_newv ("change-file", + 7 G_TYPE_FROM_CLASS (class), + 8 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 9 NULL /* closure */, + 10 NULL /* accumulator */, + 11 NULL /* accumulator data */, + 12 NULL /* C marshaller */, + 13 G_TYPE_NONE /* return_type */, + 14 0 /* n_params */, + 15 NULL /* param_types */); + 16 GType param_types[] = {G_TYPE_INT}; + 17 tfe_text_view_signals[OPEN_RESPONSE] = g_signal_newv ("open-response", + 18 G_TYPE_FROM_CLASS (class), + 19 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 20 NULL /* closure */, + 21 NULL /* accumulator */, + 22 NULL /* accumulator data */, + 23 NULL /* C marshaller */, + 24 G_TYPE_NONE /* return_type */, + 25 1 /* n_params */, + 26 param_types); + 27 } + +- 6-15: Register "change-file"signal. +`g_signal_newv` function is used. +This signal has no default handler (object method handler). +I think you usually don't need to set a default handler in final type object. +If you need it, put the closure of the handler in line 9. +- The return value of `g_signal_newv` is the signal id. +The type of signal id is guint, which is the same as unsigned int. +It is used when the signal is emitted. +- 16-26: Register "open-response" signal. +This signal has a parameter. +- 25: Number of the parameter. +"open-response" signal has one parameter. +- 26: An array of types of parameters. +The array `param_types` is defined in line 16. +It has one element, which is `G_TYPE_INT`. +`G_TYPE_INT` is a type of integer. +Such fundamental types are described in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html). + +The handlers are as follows. + + void change_file_handler (TfeTextView *tv, gpointer user_data); + void open_response_handler (TfeTextView *tv, guint parameter, gpointer user_data); + +- Because "change-file" signal doesn't have parameter, the handler's parameter is TfeTextView object and user data. +- Because "open-response" signal has one parameter, the handler's parameter is TfeTextView object, the parameter and user data. +- `tv` is the object instance on which the signal is emitted. +- `user_data` comes from the fourth argument of `g_signal_connect`. +- `parameter` comes from the fourth argument of `g_signal_emit`. + +The parameter is defined in `tfetextview.h` because it is public. + + /* "open-response" signal response */ + enum + { + TFE_OPEN_RESPONSE_SUCCESS, + TFE_OPEN_RESPONSE_CANCEL, + TFE_OPEN_RESPONSE_ERROR + }; + +- `TFE_OPEN_RESPONSE_SUCCESS` is set when `tfe_text_view_open` successfully has opend a file and loaded it. +- `TFE_OPEN_RESPONSE_CANCEL` is set when the user canceled to open a file. +- `TFE_OPEN_RESPONSE_ERROR` is set when error occured. + +## Signal connection + +A signal and a handler are connected by the function `g_signal_connect`. +There some similar functions like `g_signal_connect_after`, `g_signal_connect_swapped` and so on. +But I think `g_signal_connect` is the most common function. +The signals "change-file" is connected to a callback function `file_changed` outside of TfeTextView object. +In the same way, the signals "open-response" is connected to a callback function `open_response` outside of TfeTextView object. +The functions `file_changed` and `open_response` will be explained later. + + g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb); + + g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb); + +## Signal emission + +Signals are emitted on the object. +The type of the object is the second argument of `g_signal_newv`. +The relationship between the signal and object (type) is made up when the signal is generated. + +`g_signal_emit` is used to emit the signal. +The following is extract from `tfetexties.c`. + + g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS); + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL); + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + +- The first argument is the object on which the signal is emitted. +- The second argument is the signal id. +- The third argument is the detail of the signal. +"change-file" signal and "open-response" signal doesn't have details and the argument is zero when no details. +- "change-file" signal doesn't have parameter, so no fourth parameter. +- "open-response" signal has one parameter. +The fourth parameter is the parameter. + +Up: [Readme.md](src/Readme.md), Prev: [Section 8}](src/sec8.src.md), Next: [Section 10[(src/sec10.src.md) \ No newline at end of file diff --git a/src/class_gobject.c b/src/class_gobject.c new file mode 100644 index 0000000..66288bd --- /dev/null +++ b/src/class_gobject.c @@ -0,0 +1,38 @@ +typedef struct _GObjectClass GObjectClass; +typedef struct _GObjectClass GInitiallyUnownedClass; + +struct _GObjectClass { + GTypeClass g_type_class; + /*< private >*/ + GSList *construct_properties; + /*< public >*/ + /* seldom overidden */ + GObject* (*constructor) (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); + /* overridable methods */ + void (*set_property) (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + void (*get_property) (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + void (*dispose) (GObject *object); + void (*finalize) (GObject *object); + /* seldom overidden */ + void (*dispatch_properties_changed) (GObject *object, + guint n_pspecs, + GParamSpec **pspecs); + /* signals */ + void (*notify) (GObject *object, + GParamSpec *pspec); + + /* called when done constructing */ + void (*constructed) (GObject *object); + /*< private >*/ + gsize flags; + /* padding */ + gpointer pdummy[6]; +}; diff --git a/src/classes.c b/src/classes.c new file mode 100644 index 0000000..6b3741d --- /dev/null +++ b/src/classes.c @@ -0,0 +1,108 @@ +struct _GtkWidgetClass { + GInitiallyUnownedClass parent_class; + /*< public >*/ + guint activate_signal; + /* basics */ + void (* show) (GtkWidget *widget); + void (* hide) (GtkWidget *widget); + void (* map) (GtkWidget *widget); + void (* unmap) (GtkWidget *widget); + void (* realize) (GtkWidget *widget); + void (* unrealize) (GtkWidget *widget); + void (* root) (GtkWidget *widget); + void (* unroot) (GtkWidget *widget); + void (* size_allocate) (GtkWidget *widget, + int width, + int height, + int baseline); + void (* state_flags_changed) (GtkWidget *widget, + GtkStateFlags previous_state_flags); + void (* direction_changed) (GtkWidget *widget, + GtkTextDirection previous_direction); + void (* grab_notify) (GtkWidget *widget, + gboolean was_grabbed); + /* size requests */ + GtkSizeRequestMode (* get_request_mode) (GtkWidget *widget); + void (* measure) (GtkWidget *widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline); + /* Mnemonics */ + gboolean (* mnemonic_activate) (GtkWidget *widget, + gboolean group_cycling); + /* explicit focus */ + gboolean (* grab_focus) (GtkWidget *widget); + gboolean (* focus) (GtkWidget *widget, + GtkDirectionType direction); + void (* set_focus_child) (GtkWidget *widget, + GtkWidget *child); + /* keyboard navigation */ + void (* move_focus) (GtkWidget *widget, + GtkDirectionType direction); + gboolean (* keynav_failed) (GtkWidget *widget, + GtkDirectionType direction); + /* accessibility support + */ + AtkObject * (* get_accessible) (GtkWidget *widget); + gboolean (* query_tooltip) (GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_tooltip, + GtkTooltip *tooltip); + void (* compute_expand) (GtkWidget *widget, + gboolean *hexpand_p, + gboolean *vexpand_p); + void (* css_changed) (GtkWidget *widget, + GtkCssStyleChange *change); + void (* system_setting_changed) (GtkWidget *widget, + GtkSystemSetting settings); + void (* snapshot) (GtkWidget *widget, + GtkSnapshot *snapshot); + gboolean (* contains) (GtkWidget *widget, + gdouble x, + gdouble y); + /*< private >*/ + GtkWidgetClassPrivate *priv; + gpointer padding[8]; +}; + +struct _GtkTextViewClass { + GtkWidgetClass parent_class; + /*< public >*/ + void (* move_cursor) (GtkTextView *text_view, + GtkMovementStep step, + gint count, + gboolean extend_selection); + void (* set_anchor) (GtkTextView *text_view); + void (* insert_at_cursor) (GtkTextView *text_view, + const gchar *str); + void (* delete_from_cursor) (GtkTextView *text_view, + GtkDeleteType type, + gint count); + void (* backspace) (GtkTextView *text_view); + void (* cut_clipboard) (GtkTextView *text_view); + void (* copy_clipboard) (GtkTextView *text_view); + void (* paste_clipboard) (GtkTextView *text_view); + void (* toggle_overwrite) (GtkTextView *text_view); + GtkTextBuffer * (* create_buffer) (GtkTextView *text_view); + void (* snapshot_layer) (GtkTextView *text_view, + GtkTextViewLayer layer, + GtkSnapshot *snapshot); + gboolean (* extend_selection) (GtkTextView *text_view, + GtkTextExtendSelection granularity, + const GtkTextIter *location, + GtkTextIter *start, + GtkTextIter *end); + void (* insert_emoji) (GtkTextView *text_view); + /*< private >*/ + gpointer padding[8]; +}; + +/* The following definition is generated by the macro G_DECLARE_FINAL_TYPE +typedef struct { + GtkTextView parent_class; +} TfeTextViewClass; + diff --git a/src/gvarianttype_test.c b/src/gvarianttype_test.c new file mode 100644 index 0000000..7bd733b --- /dev/null +++ b/src/gvarianttype_test.c @@ -0,0 +1,8 @@ +#include + +int +main (int argc, char **argv) { + GVariantType *vtype = g_variant_type_new ("s"); + const gchar *type_string = g_variant_type_peek_string (vtype); + g_print ("%s\n",type_string); +} diff --git a/src/lb1.c b/src/lb1.c new file mode 100644 index 0000000..adcb790 --- /dev/null +++ b/src/lb1.c @@ -0,0 +1,29 @@ +#include + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + GtkWidget *lab; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "lb4"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + lab = gtk_label_new ("Hello."); + gtk_window_set_child (GTK_WINDOW (win), lab); + + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.lb1", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/lb2.c b/src/lb2.c new file mode 100644 index 0000000..a9a235c --- /dev/null +++ b/src/lb2.c @@ -0,0 +1,35 @@ +#include + +static void +on_clicked (GtkButton *btn, gpointer user_data) { + g_print ("Clicked.\n"); +} + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + GtkWidget *btn; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "lb4"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + btn = gtk_button_new_with_label ("Click me"); + gtk_window_set_child (GTK_WINDOW (win), btn); + g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), NULL); + + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.lb2", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/lb3.c b/src/lb3.c new file mode 100644 index 0000000..ad155b9 --- /dev/null +++ b/src/lb3.c @@ -0,0 +1,36 @@ +#include + +static void +on_clicked (GtkButton *btn, gpointer user_data) { + GtkWindow *win = GTK_WINDOW (user_data); + gtk_window_destroy (win); +} + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + GtkWidget *btn; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "lb4"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + btn = gtk_button_new_with_label ("Quit"); + gtk_window_set_child (GTK_WINDOW (win), btn); + g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), win); + + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.lb3", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/lb4.c b/src/lb4.c new file mode 100644 index 0000000..44d2948 --- /dev/null +++ b/src/lb4.c @@ -0,0 +1,58 @@ +#include + +static void +on_clicked1 (GtkButton *btn, gpointer user_data) { + const gchar *s; + + s = gtk_button_get_label (btn); + if (g_strcmp0 (s, "Hello.") == 0) + gtk_button_set_label (btn, "Good-bye."); + else + gtk_button_set_label (btn, "Hello."); +} + +static void +on_clicked2 (GtkButton *btn, gpointer user_data) { + GtkWindow *win = GTK_WINDOW (user_data); + gtk_window_destroy (win); +} + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + GtkWidget *box; + GtkWidget *btn1; + GtkWidget *btn2; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "lb4"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); + gtk_box_set_homogeneous (GTK_BOX (box), TRUE); + gtk_window_set_child (GTK_WINDOW (win), box); + + btn1 = gtk_button_new_with_label ("Hello."); + g_signal_connect (btn1, "clicked", G_CALLBACK (on_clicked1), NULL); + + btn2 = gtk_button_new_with_label ("Quit"); + g_signal_connect (btn2, "clicked", G_CALLBACK (on_clicked2), win); + + gtk_box_append (GTK_BOX (box), btn1); + gtk_box_append (GTK_BOX (box), btn2); + + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.lb4", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/menu1.c b/src/menu1.c new file mode 100644 index 0000000..935b2e5 --- /dev/null +++ b/src/menu1.c @@ -0,0 +1,47 @@ +#include + +static void +quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app) +{ + g_application_quit (G_APPLICATION(app)); +} + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "menu1"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + GSimpleAction *act_quit = g_simple_action_new ("quit", NULL); + g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit)); + g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), app); + + GMenu *menubar = g_menu_new (); + GMenuItem *menu_item_menu = g_menu_item_new ("Menu", NULL); + GMenu *menu = g_menu_new (); + GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + g_menu_append_item (menu, menu_item_quit); + g_object_unref (menu_item_quit); + g_menu_item_set_submenu (menu_item_menu, G_MENU_MODEL (menu)); + g_menu_append_item (menubar, menu_item_menu); + g_object_unref (menu_item_menu); + + gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar)); + gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE); + gtk_window_present (GTK_WINDOW (win)); +/* gtk_widget_show (win); is also OKay instead of gtk_window_present. */ +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.menu1", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/menu2.c b/src/menu2.c new file mode 100644 index 0000000..63e5ffb --- /dev/null +++ b/src/menu2.c @@ -0,0 +1,105 @@ +#include + +static GtkCssProvider *provider; + +static void +fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) { + if (g_variant_get_boolean (value)) + gtk_window_maximize (GTK_WINDOW (win)); + else + gtk_window_unmaximize (GTK_WINDOW (win)); + g_simple_action_set_state (action, value); +} + +static void +color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) { + gchar *color = g_strdup_printf ("label#lb {background-color: %s;}", g_variant_get_string (parameter, NULL)); + gtk_css_provider_load_from_data (provider, color, -1); + g_free (color); + g_action_change_state (G_ACTION (action), parameter); +} + +static void +quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app) +{ + g_application_quit (G_APPLICATION(app)); +} + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "menu2"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + GtkWidget *lb = gtk_label_new (NULL); + gtk_widget_set_name (lb, "lb"); /* the name is used by CSS Selector */ + gtk_window_set_child (GTK_WINDOW (win), lb); + + GSimpleAction *act_fullscreen + = g_simple_action_new_stateful ("fullscreen", NULL, g_variant_new_boolean (FALSE)); + GSimpleAction *act_color + = g_simple_action_new_stateful ("color", g_variant_type_new("s"), g_variant_new_string ("red")); + GSimpleAction *act_quit + = g_simple_action_new ("quit", NULL); + + GMenu *menubar = g_menu_new (); + GMenu *menu = g_menu_new (); + GMenu *section1 = g_menu_new (); + GMenu *section2 = g_menu_new (); + GMenu *section3 = g_menu_new (); + GMenuItem *menu_item_fullscreen = g_menu_item_new ("Full Screen", "win.fullscreen"); + GMenuItem *menu_item_red = g_menu_item_new ("Red", "win.color::red"); + GMenuItem *menu_item_green = g_menu_item_new ("Green", "win.color::green"); + GMenuItem *menu_item_blue = g_menu_item_new ("Blue", "win.color::blue"); + GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + + g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win); + g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win); + g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), app); + g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_fullscreen)); + g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_color)); + g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit)); + + g_menu_append_item (section1, menu_item_fullscreen); + g_menu_append_item (section2, menu_item_red); + g_menu_append_item (section2, menu_item_green); + g_menu_append_item (section2, menu_item_blue); + g_menu_append_item (section3, menu_item_quit); + g_object_unref (menu_item_red); + g_object_unref (menu_item_green); + g_object_unref (menu_item_blue); + g_object_unref (menu_item_fullscreen); + g_object_unref (menu_item_quit); + + g_menu_append_section (menu, NULL, G_MENU_MODEL (section1)); + g_menu_append_section (menu, "Color", G_MENU_MODEL (section2)); + g_menu_append_section (menu, NULL, G_MENU_MODEL (section3)); + g_menu_append_submenu (menubar, "Menu", G_MENU_MODEL (menu)); + + gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar)); + gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE); + +/* GtkCssProvider *provider = gtk_css_provider_new ();*/ + provider = gtk_css_provider_new (); + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (win)); + gtk_css_provider_load_from_data (provider, "label#lb {background-color: red;}", -1); + gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_USER); + +/* gtk_widget_show (win);*/ + gtk_window_present (GTK_WINDOW (win)); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.menu2", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/menu3/menu3.c b/src/menu3/menu3.c new file mode 100644 index 0000000..7c82763 --- /dev/null +++ b/src/menu3/menu3.c @@ -0,0 +1,106 @@ +#include + +static void +new_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +open_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +save_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +saveas_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +close_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +cut_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +copy_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +paste_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +selectall_activated (GSimpleAction *action, GVariant *parameter, gpointer win) { +} + +static void +fullscreen_changed (GSimpleAction *action, GVariant *state, gpointer win) { + if (g_variant_get_boolean (state)) + gtk_window_maximize (GTK_WINDOW (win)); + else + gtk_window_unmaximize (GTK_WINDOW (win)); + g_simple_action_set_state (action, state); +} + +static void +quit_activated (GSimpleAction *action, GVariant *parameter, gpointer app) +{ + g_application_quit (G_APPLICATION(app)); +} + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + + const GActionEntry win_entries[] = { + { "new", new_activated, NULL, NULL, NULL }, + { "open", open_activated, NULL, NULL, NULL }, + { "save", save_activated, NULL, NULL, NULL }, + { "saveas", saveas_activated, NULL, NULL, NULL }, + { "close", close_activated, NULL, NULL, NULL }, + { "cut", cut_activated, NULL, NULL, NULL }, + { "copy", copy_activated, NULL, NULL, NULL }, + { "paste", paste_activated, NULL, NULL, NULL }, + { "selectall", selectall_activated, NULL, NULL, NULL }, + { "fullscreen", NULL, NULL, "false", fullscreen_changed } + }; + g_action_map_add_action_entries (G_ACTION_MAP (win), win_entries, G_N_ELEMENTS (win_entries), win); + + gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE); + + gtk_window_set_title (GTK_WINDOW (win), "menu3"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + gtk_widget_show (win); +} + +static void +on_startup (GApplication *app, gpointer user_data) { + GtkBuilder *builder = gtk_builder_new_from_resource ("/com/github/ToshioCP/menu3/menu3.ui"); + GMenuModel *menubar = G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")); + + gtk_application_set_menubar (GTK_APPLICATION (app), menubar); + g_object_unref (builder); + + const GActionEntry app_entries[] = { + { "quit", quit_activated, NULL, NULL, NULL } + }; + g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, G_N_ELEMENTS (app_entries), app); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.menu3", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "startup", G_CALLBACK (on_startup), NULL); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/menu3/menu3.gresource.xml b/src/menu3/menu3.gresource.xml new file mode 100644 index 0000000..ff1192b --- /dev/null +++ b/src/menu3/menu3.gresource.xml @@ -0,0 +1,6 @@ + + + + menu3.ui + + diff --git a/src/menu3/menu3.ui b/src/menu3/menu3.ui new file mode 100644 index 0000000..366609c --- /dev/null +++ b/src/menu3/menu3.ui @@ -0,0 +1,72 @@ + + + + + File +
+ + New + win.new + + + Open + win.open + +
+
+ + Save + win.save + + + Save As… + win.saveas + +
+
+ + Close + win.close + +
+
+ + Quit + app.quit + +
+
+ + Edit +
+ + Cut + win.cut + + + Copy + win.copy + + + Paste + win.paste + +
+
+ + Select All + win.selectall + +
+
+ + View +
+ + Full Screen + win.fullscreen + +
+
+
+
diff --git a/src/menu3/meson.build b/src/menu3/meson.build new file mode 100644 index 0000000..1c3ceb0 --- /dev/null +++ b/src/menu3/meson.build @@ -0,0 +1,10 @@ +project('menu3', 'c') + +gtkdep = dependency('gtk4') + +gnome=import('gnome') +resources = gnome.compile_resources('resources','menu3.gresource.xml') + +sourcefiles=files('menu3.c') + +executable('menu3', sourcefiles, resources, dependencies: gtkdep) diff --git a/src/misc/pr1.c b/src/misc/pr1.c new file mode 100644 index 0000000..a5e7539 --- /dev/null +++ b/src/misc/pr1.c @@ -0,0 +1,13 @@ +#include + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.pr1", G_APPLICATION_FLAGS_NONE); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/misc/pr2.c b/src/misc/pr2.c new file mode 100644 index 0000000..eaf838d --- /dev/null +++ b/src/misc/pr2.c @@ -0,0 +1,19 @@ +#include + +static void +on_activate (GApplication *app, gpointer *user_data) { + g_print ("GtkApplication is activated.\n"); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.pr2", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/misc/pr3.c b/src/misc/pr3.c new file mode 100644 index 0000000..e20a865 --- /dev/null +++ b/src/misc/pr3.c @@ -0,0 +1,23 @@ +#include + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + + win = gtk_window_new (); + gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.pr3", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/misc/pr4.c b/src/misc/pr4.c new file mode 100644 index 0000000..229ab52 --- /dev/null +++ b/src/misc/pr4.c @@ -0,0 +1,24 @@ +#include + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "pr4"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.pr4", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/sec1.src.md b/src/sec1.src.md new file mode 100644 index 0000000..8e0ae36 --- /dev/null +++ b/src/sec1.src.md @@ -0,0 +1,238 @@ +# GtkApplication and GtkApplicationWindow + +## GtkApplication + +### GtkApplication and g\_application\_run + +Usually people write a programming code to make an application. +What are appications? +Applications are software that runs using libraries, which includes OS, frameworks and so on. +In Gtk4 programming, GtkApplication is an object that runs on GTK libraries. + +The basic way how to write GtkApplication is as follows. + +- Generate a GtkApplication object +- Run it + +That's all. +Very simple. +The following is the C code representing the scenario above. + +@@@ misc/pr1.c + +The first line says that this program includes the GTK header libraries. +The function `main` above is a startup function in C language. +The variable `app` is defined as a pointer to GtkApplication, which is actually a structure in which information about the application is stored. +The function `gtk_application_new` generates a GtkApplication and sets its pointer to `app`. +The meaning of the arguments will be explained later. +The function `g_application_run` invokes the GtkApplication pointed by `app`. +(We often say that the function invokes `app`. +Actually, `app` is not an object but an pointer to the object. +However, it is simple and short, and probably no confusion occurs.) + +To compile this, the following command needs to be run. +The string pr1.c is the filename of the C source code. + + $ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4` + +The C compiler gcc generates an executable file `a.out`. +Let's run it. + + $ ./a.out + + (a.out:13533): GLib-GIO-WARNING **: 15:30:17.449: Your application does not implement g_application_activate() and has no handlers connected to the "activate" signal. It should do one of these. + $ + +Oh, just an error message. +But this error message means that the GtkApplication object ran without a doubt. +Now, think about the message in the next section. + +### signal + +The message tells us that: + +1. The application GtkApplication doesn't implement `g_application_activate()`. +2. And it has no handlers connected to the activate signal. +3. You need to solve at least one of this. + +These two cause of the error are related to signals. +So, I will explain it to you first. + +Signal is emitted when something happens. +For example, a window is generated, a window is destroyed and so on. +The signal "activate" is emitted when the application is activated. +If the signal is connected to a function, which is called signal handler or simply handler, then the function invokes when the signal emits. +The flow is like this: + +1. Something happens. +2. If it's related to a certain signal, then the signal is emitted. +3. If the signal is connected to a handler in advance, then the handler is invoked. + +Signals are defined in objects. +For example, "activate" signal belongs to GApplication object, which is a parent object of GtkApplication object. +GApplication object is a child object of GObject object. +GObject is the top object in the hierarchy of all the objects. + + GObject -- GApplication -- GtkApplication + <---parent --->child + +A child object derives signals, functions, properties and so on from its parent object. +So, Gtkapplication also has the "activate" signal. + +Now we can solve the problem in `pr1.c`. +We need to connect the activate signal to a handler. +We use a function `g_signal_connect` which connects a signal to a handler. + +@@@ misc/pr2.c + +First, we define the handler `on_activate` which simply displays a message. +In the function `main`, we add `g_signal_connect` before `g_application_run`. +The function `g_signal_connect` has four arguments. + +1. An object to which the signal belongs. +2. The name of the signal. +3. A handler function (also called callback), which needs to be casted by `G_CALLBACK`. +4. Data to pass to the handler. If no data is necessary, NULL should be given. + +You can find the description of each signal in API reference. +For example, "activate" signal is in GApplication subsection in GIO API reference. +The handler function is described in that subsection. + +In addition, `g_signal_connect` is described in GObject API reference. +API reference is very important. +You should see and understand it to write GTK applications. + +Let's compile the source file `pr2.c` above and run it. + + $ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4` + $ ./a.out + GtkApplication is activated. + $ + +OK, well done. +However, you may have noticed that it's painful to type such a long line to compile. +It is a good idea to use shell script to solve this problem. +Make a text file which contains the following text. + + gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4` + +Then, save it in $HOME/bin, which is usually /home/(username)/bin. +(If your user name is James, then the directory is /home/james/bin). +And turn on the execute bit of the file. +Suppose the filename is comp, then the procedure is as follows. + + $ chmod 755 $HOME/bin/comp + $ ls -log $HOME/bin + ... ... ... + -rwxr-xr-x 1 62 May 23 08:21 comp + ... ... ... + +If this is the first time that you make a $HOME/bin directory and save a file in it, then you need to logout and login again. + + $ comp pr2 + $ ./a.out + GtkApplication is activated. + $ + +## GtkWindow and GtkApplicationWindow + +### GtkWindow + +A message "GtkApplication is activated." was printed out in the previous subsection. +It was good in terms of a test of GtkApplication. +However, it is insufficient because GTK is a framework for graphical user interface (GUI). +Now we go ahead with adding a window into this program. +What we need to do is: + +1. Generate a GtkWindow. +2. Connect it to GtkApplication. +3. Show the window. + +Now rewrite the function `on_activate`. + +#### Generate a GtkWindow + +@@@ misc/pr3.c on_activate + +Widget is an abstract concept that includes all the GUI interfaces such as windows, dialogs, buttons, multiline text, containers and so on. +And GtkWidget is a base object from which all the GUI objects derive. + + parent <-----> child + GtkWidget -- GtkWindow + +GtkWindow includes GtkWidget at the top of its object. + +![GtkWindow and GtkWidget](window_widget.png) + +The function `gtk_window_new` is defined as follows. + + GtkWidget * + gtk_window_new (void); + +By this definition, it returns a pointer to GtkWidget, not GtkWindow. +It actually generates a new GtkWindow object (not GtkWidget) but returns a pointer to GtkWidget. +However,the pointer points the GtkWidget and at the same time it also points GtkWindow that contains GtkWidget in it. + +If you want to use `win` as a pointer to the GtkWindow, you need to cast it. + + (GtkWindow *) win + +Or you can use `GTK_WINDOW` macro that performs a similar function. + + GTK_WINDOW (win) + +This is a recommended way. + +#### Connect it to GtkApplication. + +The function `gtk_window_set_application` is used to connect GtkWidow to GtkApplication. + + gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + +You need to cast `win` to GtkWindow and `app` to GtkApplication. +`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that. + +GtkApplication continues to run until the related window is destroyed. +If you didn't connect GtkWindow and GtkApplication, GtkApplication shutdowns soon. +Because no window is connected to GtkApplication, it doesn't need to wait anything. +As it shutdowns the generated window is also destroyed. + +#### Show the window. + +The function `gtk_widget_show` is used to show the window. + +Gtk4 changed the default widget visibility to on, so every widget doesn't need this function to show itself. +But, there's an exception. +Top window (this term will be explained later) isn't visible when it is generated. +So you need to use the function above and show the window. + +Save the program as `pr3.c` and compile and run it. + + $ comp pr3 + $ ./a.out + +A small window appears. + +![Screenshot of the window](screenshot_pr3.png) + +Click on the close button then the window disappears and the program finishes. + +### GtkApplicationWindow + +GtkApplicationWindow is a child object of GtkWindow. +It has some extra functionality for better integration with GtkApplication. +It is recommended to use it instead of GtkWindow when you use GtkApplication. + +Now rewrite the program and use GtkAppliction Window. + +@@@ misc/pr4.c on_activate + +When you generate GtkApplicationWindow, you need to give GtkApplication object as an argument. +Then it automatically connect these two objects. +So you don't need to call `gtk_window_set_application` any more. + +The program sets the title and the default size of the window. +Compile it and run `a.out`, then you will see a bigger window with its title "pr4". + +![Screenshot of the window](screenshot_pr4.png) + diff --git a/src/sec10.src.md b/src/sec10.src.md new file mode 100644 index 0000000..7ebc2fa --- /dev/null +++ b/src/sec10.src.md @@ -0,0 +1,176 @@ +# Functions in TfeTextView + +In this section I will explain each function in TfeTextView object. + +### tfe.h and tfetextview.h + +`tfe.h` is a top header file and it includes `gtk.h` and all the header files. +Every C source files, which are `tfeapplication.c`, `tfenotebook.c` and `tfetextview.c`, include `tfe.h` at the beginning of each file. + +@@@ tfe5/tfe.h + +`tfetextview.h` is a header file which describes the public functions in `tfetextview.c`. + +@@@ tfe5/tfetextview.h + +- 1-2: These two lines are used to define TfeTextView. +- 4-10: Definitions of parameter used in the handler of "open-response" signal. +- 12-28: Public functions on GtkTextView. + +Each function will be explained later in this section. + +## Functions to generate TfeTextView object + +TfeTextView Object is generated by `tfe_text_view_new` or `tfe_text_view_new_with_file`. + + GtkWidget *tfe_text_view_new (void); + +`tfe_text_view_new` just generates a new TfeTextView object and returns the pointer to the new object. + + GtkWidget *tfe_text_view_new_with_file (GFile *file); + +`tfe_text_view_new_with_file` is given a Gfile object as the argument and it loads the file into the GtkTextBuffer object, then returns the pointer to the new object. + +Parameter: + +- `file`: a pointer to the GFile object. + +Return value: + +- A pointer to the generated TfeTextView object but it is casted to a pointer to GtkWidget. +If an error occures during the genration process, NULL is returned. + +Each function is defined as follows. + +@@@ tfe5/tfetextview.c tfe_text_view_new_with_file tfe_text_view_new + +- 18-21: `tfe_text_view_new`. +Just returns the value from the function `gtk_widget_new`. +Initialization is done in `tfe_text_view_init` which is called in the process of `gtk_widget_new` function. +- 1-16: `tfe_text_view_new_with_file` +- 3: `g_return_val_if_fail` is described in [Glib API reference](https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail). +It tests whether the argument `file` is a pointer to GFile. +If it's true, then the program goes on to the next line. +If it's false, then it returns NULL (the second argument) immediately. +And at the same time it logs out the error message (usually the log is outputted to stderr or stdout). +This function is used to check the programmer's error. +If an error occurs, the solution is usually to change the (caller) program and fix the bug. +You need to distinguish programmer's errors and runtime errors. +You shouldn't use this function to find runtime errors. +- 9-10: If an error occurs when reading the file, then return NULL. +- 11-15: Generate TfeTextView and set the pointer to it to `tv`. +Set the contents read from the file to GtkTextBuffer `tv->tb`. +Free the memories pointed by `contents`. +Duplicate `file` and set it to `tv->file`. +Return `tv`. + +## Save and saveas functions + +Save and saveas functions write the contents in GtkTextBuffer to a file. + + void tfe_text_view_save (TfeTextView *tv) + +`save` function writes the contents in GtkTextBuffer to a file specified by `tv->file`. +If `tv->file` is NULL, then it shows GtkFileChooserDialog and lets the user to give a file to the program. After that, it saves the contents to the specified file and set the file into `tv->file`. + + void tfe_text_view_saveas (TfeTextView *tv) + +`saveas` function uses GtkFileChooserDialog and lets the user to give a new file to the program. Then, the function changes `tv->file` and save the contents to the specified new file. + +If an error occures, it is shown to the user through the message dialog. +The error is managed only in the object and no information is notified to the caller. + +@@@ tfe5/tfetextview.c saveas_dialog_response tfe_text_view_save tfe_text_view_saveas + +- 17-53: `Tfe_text_view_save` function. +- 19: If `tv` is not a pointer to TfeTextView, then it logs an error message and immediately returns. +This function is similar to `g_return_val_if_fail` function, but no value is returned because `tfe_text_view_save` doesn't return a value. +- 28-29: If the buffer hasn't modified, then it doesn't need to save it. +So the function returns. +- 30-31: If `tv->file` is NULL, no file has given yet. +It calls `tfe_text_view_save`, which lets the user to choose a file to save. +- 33-35: Save the buffer to the file. +If it succeeds, assigns FALSE to `tv->changed`. +- 38-50: If file writing fails, it assigns NULL to `tv->file`. +Emits "change-file" signal. +Shows the error message dialog (45-49). +Because the handler is `gtk_window_destroy`, the dialog disappears when user clicks on the button in the dialog. +- 55-68: `tfe_text_view_saveas` function. +It shows GtkFileChooserDialog and lets the user choose a file and give it to the signal handler. +- 62: Generate GtkFileChooserDialog. +The title is "Save file". +Transient parent of the dialog is `win`, which is the top level window. +The action is save mode. +The buttons are Cancel and Save. +- 63: connect the "response" signal of the dialog and `saveas_dialog_response` handler. +- 1-15: `saveas_dialog_response` signal handler. +- 5-13: If the response is `GTK_RESPONSE_ACCEPT`, which is set to the argument when the user has clicked on Save button, then gets a pointer to the GFile object, set it to `tv->file`, assign TRUE to `tv->changed`, emits "change-file" signal then call `tfe_text_view_save` to save the buffer to the file. + +![Saveas process](saveas.png) + +When you use GtkFileChooserDialog, you need to divide the program into two parts. +They are a function which generates GtkFileChooserDialog and the signal handler. +The function just generates and shows the dialog. +The rest is done by the handler. +It gets Gfile from GtkFileChooserDialog, save the buffer to the file and do some things necessary. + +## Open function + +Open function shows GtkFileChooserDialog to the user and let him/her choose a file. +Then read the file and set it to GtkTextBuffer. + + void tfe_text_view_open (TfeTextView *tv) + +TfeTextView object `tv` has to be generated in advance. +And it should be empty and `tv->file` is NULL. +If it is not empty, `tfe_text_view_open` doesn't treat it as an error. +If you want to revert the buffer, calling this function is apropreate. +Otherwise probably bad things will happen. + +@@@ tfe5/tfetextview.c open_dialog_response tfe_text_view_open + +- 33-45: `tfe_text_view_open` function. +- 39: Generate GtkFileChooserDialog. +The title is "Open file". +No transient parent window. +The action is open mode. +The buttons are Cancel and Open. +- 43: connect the "reponse" signal of the dialog and `open_dialog_response` signal handler. +- 44: Show the dialog. +- 1-31: `open_dialog_response` signal handler. +- 9-10: If the response from GtkFileChooserDialog is not `GTK_RESPONSE_ACCEPT`, which means the user has clicked on the "Cancel" button or close button, then it emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_CANCEL`. +- 11-12: Get a pointer to Gfile by `gtk_file_chooser_get_file`. +If it is not GFile, maybe an error occured. +Then it emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_ERROR`. +- 13-22: If an error occurs when it has read the file, then it decreases the reference count of Gfile, shows a message dialog to report the error to the user and emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_ERROR`. +- 24-28: If the file has successfully read, then the text is set to GtkTextBuffer, free the temporary buffer pointed by `contents`, set file to `tv->file` (no duplication or unref is not necessary) and emits "open-response" signal with the parameter `TFE_OPEN_RESPONSE_SUCCESS`. +- 30: close GtkFileCooserDialog. + +Now let's think about the whole process between the other object (caller) and TfeTextView. +It is shown in the following diagram and you would think that it is really complicated. +Because signal is the only way for GtkFileChooserDialog to communicate with others. +In Gtk3, `gtk_dialog_run` function is available. +It simplifies the process. +However, in Gtk4, `gtk_dialog_run`is unavailable any more. + +![Caller and TfeTextView](open.png) + +1. A caller get a pointer `tv` to TfeTextView by calling `tfe_text_view_new`. +2. The caller connects the handler (left bottom in the diagram) and the signal "open-response". +3. It calls `tfe_text_view_open` to let the user select a file from GtkFileChooserDialog. +4. The dialog emits a signal and it invokes the handler `open_dialog_response`. +5. The handler read the file and set it into GtkTextBuffer and emits a signal to inform the response status. +6. The handler outside TfeTextView recieves the signal. + +## Get file function + +`gtk_text_view_get_file` is a simple function show as follows. + +@@@ tfe5/tfetextview.c tfe_text_view_get_file + +The important thing is duplicate `tv->file`. +Otherwise, if the caller free the GFile object, `tv->file` is no more guaranteed to point the GFile. + +## Source file of tfetextview.c + +All the source files are listed in [Section 13](ch13.html). diff --git a/src/sec11.src.md b/src/sec11.src.md new file mode 100644 index 0000000..616775d --- /dev/null +++ b/src/sec11.src.md @@ -0,0 +1,92 @@ +# Functions with GtkNotebook + +GtkNotebook is a very important object in the text file editor `tfe`. +It connects the application and TfeTextView objects. +`tfenotebook.h` and `tfenotebook.c` describe a set of functions related to GtkTextbook. + +@@@ tfe5/tfenotebook.h + +This header file shows the public functions in `tfenotebook.c`. + +- `notebook_page_new` generates a new GtkNotebookPage and adds GtkScrolledWindow and TfeTextView under the page. +- `notebook_page_new_with_file` generates a new GtkNotebookPage and adds GtkScrolledWindow and TfeTextView under the page. `file` is set to the pointer to GFile in the TfeTextView object and the file is read and set into GtkTextBuffer. +- `notebook_page_open` lets the user select a file and sets it into GtkTextBuffer. +- `notebook_page_save` save the contents in GtkTextBuffer to a file, using the pointer `tv->file`. + +You probably find that the functions above are higher level functions of `tfe_text_view_new`, `tfe_text_view_new_with_file`, `tef_text_view_open` and `tfe_text_view_save` respectively. +There are two layers. +One of them is `tfe_text_view ...`, which is the lower level layer. +The other is `note_book ...`, which is the higher level layer. + +Now let's look at each program of the functions. + +## notebook\_page\_new + +@@@ tfe5/tfenotebook.c get_untitled notebook_page_build notebook_page_new + +- 27-37: `notebook_page_new` function. +- 29: `g_return_if_fail` is used because `notebook_page_new` is a public function. +- 34: Generate TfeTextView object. +- 35: Generate filename, which is "Untitled", "Untitled2", ... . +- 1-8: `get_untitled` function. +- 3: Static variable `c` is initialized at the first call of this function. After that `c` keeps its value except it is changed explicitly. +- 4-7: Increase `c` by one and if it is zero then the name is "Untitled". If it is a positive integer then the name is "Untitled", for example, "Untitled1", "Untitled2", and so on. +It returns the name. +`g_strdup_printf` generates a string and it should be freed by `g_free` function. +The caller of `get_untitled` is in charge of freeing the memories of the string. +- 36: call `notebook_page_build` to build the contents of the page. +- 10- 25: `notebook_page_build` function. +- 17-18: Generate GtkScrolledWindow and set `tv` to its child. +- 19-20: Generate GtkLabel, then GtkNotebookPage. +- 21-22: Set "tab-expand" property to TRUE. +- 23: Set the page to the current page. +- 24: Connect "change-file" signal and `file_changed` handler. + +## notebook\_page\_new\_with\_file + +@@@ tfe5/tfenotebook.c notebook_page_new_with_file + +- 9-10: Call `tfe_text_view_new_with_file`. +If it returns NULL, then do nothing and return because of an error. +-11-13: Get the filename , build the contents of the page, then free `filename`. + +## notebook\_page\_open + +@@@ tfe5/tfenotebook.c open_response notebook_page_open + +- 18-27: `notebook_page_open` function. +- 24: Generate TfeTextView object. +- 25: Connect the signal "open-response" and the handler `open_response`. +- 26: Call `tfe_text_view_open`. +It emits "open-response" signal to inform the status after the series of functions run. +- 1-16: `open_response` handler. +This is the postfunction of `notebook_page_open`. +- 6-7: It the status is NOT `TFE_OPEN_RESPONSE_SUCCESS`, cancel what we did in `notebook_page_open`. +Unref `tv`. +- 8-9: If `tfe_text_view_get_file` returns a pointer not to point GFile, then something bad happens. Cancel what we did. Unref `tv`. +- 10-14: Otherwise, everything was okay. +Get the filename, build the contents of the page, free `filename` and unref `tv` + +## notebook\_page\_save + +@@@ tfe5/tfenotebook.c notebook_page_save + +- 7-9: Get TfeTextView belongs to the current notebook page. +- 10: Call `tfe_text_view_save`. + +## file\_changed handler + +`file_changed` is a handler connected to "change-file" signal. +If `tv->file` is changed, TfeTextView emits this signal. +This handler changes the label of GtkNotebookPage. + +@@@ tfe5/tfenotebook.c file_changed + +- 8: Get GFile from TfeTextView. +- 9: Get the parent (GkScrolledWindow) of `tv`. +- 10-13: If `file` points GFile, then assign the filename of the GFile into `filename`. +Otherwise (this is the case file is NULL), assign untitled string to `filename`. +- 14-15: Generate a label with the filename and set it into GtkNotebookPage. +- 16-17: Free `filename and unref `file`. + + diff --git a/src/sec12.src.md b/src/sec12.src.md new file mode 100644 index 0000000..5a35345 --- /dev/null +++ b/src/sec12.src.md @@ -0,0 +1,153 @@ +# tfeapplication.c + +`tfeapplication.c` includes all the code other than `tfetxtview.c` and `tfenotebook.c`. +It does following things. + +- Application support, mainly handling command line arguments. +- Build widgets using ui file. +- Connect button signals and their handlers. +- Manage CSS. + +## main + +Th function `main` is the first invoked function in C language. +It connects the command line given by the user and GTK application. + +@@@ tfe5/tfeapplication.c main + +- 6: Generate GtkApplication object. +- 8-10: Connect "startup", "activate" and "open signals to their handlers. +- 12: Run the application. +- 13-14: release the reference to the application and return the status. + +## statup signal handler + +"startup" signal is emitted just after the application is generated. +What the signal handler needs to do is initialization of the application. + +- Build the widgets using ui file. +- Connect button signals and their handlers. +- Set CSS. + +The handler is as follows. + +@@@ tfe5/tfeapplication.c tfe_startup + +- 12-15: Build widgets using ui file (resource). +Connect the top window and the application using `gtk_window_set_application`. +- 16-23: Get buttons and connect their signals and handlers. +- 24: Release the reference to GtkBuilder. +- 26-31: Set CSS. +CSS in GTK is similar to CSS in HTML. +You can set margin, border, padding, color, font and so on with CSS. +In this program CSS is in line 30. +It sets padding, font-family and font size of GtkTextView. +- 26-28: GdkDisplay is used to set CSS. +CSS will be explained in the next subsection. + +## CSS in GTK + +CSS is an abbretiation of Cascading Style Sheet. +It is originally used with HTML to describe the presentation semantics of a document. +You might have found that the widgets in GTK is simialr to the window in a browser. +It implies that CSS can also be apllied to GTK windowing system. + +### CSS nodes, selectors + +The syntax of CSS is as follws. + + selector { color: yellow; padding-top: 10px; ...} + +Every widget has CSS node. +For example GtkTextView has `textview` node. +If you want to set style to GtkTextView, set "textview" to the selector. + + textview {color: yeallow; ...} + +Class, ID and some other things can be applied to the selector like Web CSS. Refer GTK4 API reference for further information. + +In line 30, the CSS is a string. + + textview {padding: 10px; font-family: monospace; font-size: 12pt;} + +- padding is a space between the border and contents. +This space makes the text easier to read. +- font-family is a name of font. +"monospace" is one of the generic family font keywords. +- font-size is set to 12pt. +It is a bit large, but easy on the eyes especially for elderly people. + +### GtkStyleContext, GtkCSSProvider and GdkDisplay + +GtkStyleContext is an object that stores styling information affecting a widget. +Each widget is connected to the corresponding GtkStyleContext. +You can get the context by `gtk_widget_get_style_context`. + +GtkCssProvider is an object which parses CSS in order to style widgets. + +To apply your CSS to wodgets, you need to add GtkStyleProvider (the interface of GtkCSSProvider) to GtkStyleContext. +However, instead, you can add it to GdkDisplay of the window (usually top level window). + +Look at the source file of `startup` handler again. + +- 28: The display is obtained by `gtk_widget_get_display`. +- 29: Generate GtkCssProvider. +- 30: Set the CSS into the provider. +- 31: Add the provider to the display. + +It is possible to add the provider to the context of GtkTextView instead of GdkDiplay. +To do so, rewrite `tfe_text_view_new`. + + GtkWidget * + tfe_text_view_new (void) { + GtkWidget *tv; + + tv = gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + + GtkStyleContext *context; + + context = gtk_widget_get_style_context (GTK_WIDGET (tv)); + GtkCssProvider *provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, "textview {padding: 10px; font-family: monospace; font-size: 12pt;}", -1); + gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER); + + return tv; + } + +CSS set to the context takes precedence over the one set to the display. + +## activate and open handler + +The handler of "activate" and "open" signal are `tfe_activate` and `tfe_open` respectively. +They just generate a new GtkNotebookPage. + +@@@ tfe5/tfeapplication.c tfe_activate tfe_open + +- 1-14: `tfe_activate`. +- 8-10: Get GtkNotebook object. +- 12-13: Generate a new GtkNotebookPage and show the window. +- 16-33: `tfe_open`. +- 24-26: Get GtkNotebook object. +- 28-29: Generate GtkNotebookPage with files. +- 30-31: If opening and reading file failed and no GtkNotebookPage has generated, then generate a empty page. +- 32: Show the window. + +These codes have become really simple thanks to tfenotebook.c and tfetextview.c. + +## a series of handlers correspond to the button signals + +@@@ tfe5/tfeapplication.c open_clicked new_clicked save_clicked close_clicked + +`open_clicked`, `new_clicked` and `save_clicked` just call corresponding notebook page functions. +`close_clicked` is a bit complicated. + +- 22-25: If there's only one page, closing the last page is considered that it also close the top level window and quit the application. +Therefore, it gets the top level window and call `gtk_window_destroy`. +- 26-28: Otherwise, it removes the current page. + +## meson.build + +@@@ tfe5/meson.build + +This file is just modified the source file names. + diff --git a/src/sec13.src.md b/src/sec13.src.md new file mode 100644 index 0000000..19ac0a9 --- /dev/null +++ b/src/sec13.src.md @@ -0,0 +1,45 @@ +# tfe5 source files + +The followings are the source files of tfe5. + +## meson.buld + +@@@ tfe5/meson.build + +## tfe.gresource.xml + +@@@ tfe5/tfe.gresource.xml + +## tfe.ui + +@@@ tfe5/tfe.ui + +## tfe.h + +@@@ tfe5/tfe.h + +## tfeapplication.c + +@@@ tfe5/tfeapplication.c + +### tfenotebook.h + +@@@ tfe5/tfenotebook.h + +## tfenotebook.c + +@@@ tfe5/tfenotebook.c + +## tfetextview.h + +@@@ tfe5/tfetextview.h + +## tfetextview.c + +@@@ tfe5/tfetextview.c + +## Total number of lines, words and charcters + +$$$ +wc tfe5/meson.build tfe5/tfeapplication.c tfe5/tfe.gresource.xml tfe5/tfe.h tfe5/tfenotebook.c tfe5/tfenotebook.h tfe5/tfetextview.c tfe5/tfetextview.h tfe5/tfe.ui +$$$ diff --git a/src/sec14.src.md b/src/sec14.src.md new file mode 100644 index 0000000..0718f50 --- /dev/null +++ b/src/sec14.src.md @@ -0,0 +1,168 @@ +# Menu and action + +## Menu + +Users often use menus to tell the command to the computer. +It is like this: + +![Menu](menu.png) + +Now let's analyze the menu above. +There are two types of object. + +- "File", "Edit", "View", "Cut", "Copy", "Paste" and "Select All". +They are called "menu item" or simply "item". +When the user clicks one of these items, then something will happen. +- Menubar, submenu referenced by "Edit" item and two sections. +They are called "menu". +Menu is an ordered list of items. +They are similar to arrays. + +![Menu structure](menu_structure.png) + +- Menubar is a menu which has three items, which are "File", "Edit" and "View". +- The menu item labeled "Edit" has a link to the submenu which has two items. +These two items don't have labels. +Each item refers to a section. +- The first section is a menu which has three items -- "Cut", "Copy" and "Paste". +- The second section is a menu which has one item -- "Select All". + +Menus can build a complicated structure thanks to the links of menu items. + +## GMenuModel, GMenu and GMenuItem + +GMenuModel is an abstact object which represents a menu. +GMenu is a simple implementation of GMenuModel and a child object of GMenuModel. + + GObjct -- GMenuModel -- GMenu + +Because GMenuModel is an abstract object, it doesn't have any functions to generate it. +Therefore, if you want to generate a menu, use `g_menu_new` function to generate GMenu object. +GMenu inherits all the functions of GMenuModel because of the child object. + +GMenuItem is an object directly derived from GObject. +GMenuItem and Gmenu (or GMenuModel) don't have a parent-child relationship. + + GObject -- GMenuModel -- GMenu + GObject -- GMenuItem + +Usually, GMenuItem has attributes. +One of the attributes is label. +For example, there is a menu item which has "Edit" label in the first diagram in this section. +"Cut", "Copy", "Paste" and "Select All" are also the lables of menu items. +Other attributes will be explained later. + +Some menu items have a link to another GMenu. +There are two types of links, submenu and section. + +GMenuItem can be inserted, appended or prepended to GMenu. +When it is inserted, all of the attribute and link values of the item are copied and used to form a new item within the menu. +The GMenuItem itself is not really inserted. +Therefore, after the insertion, GMenuItem is useless and it should be freed. +The same goes for appending or prepending. + +The following code shows how to append GMenuItem to GMenu. + + GMenu *menu = g_menu_new (); + GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + g_menu_append_item (menu, menu_item_quit); + g_object_unref (menu_item_quit); + +## Menu and action + +One of the attributes of menu items is an action. +This attribute points an action object. + +There are two action objects, GSimpleAction and GPropertyAction. +GSimpleAction is often used. +And it is used with a menu item. +Only GSimpleAction is described in this section. + +An action corresponds to a menu item will be activated when the menu item is clicked. +Then the action emits an activate signal. + +1. menu item is clicked. +2. The corresponding action is activated. +3. The action emits a signal. +4. The connected handler is invoked. + + +The following code is an example. + + static void + quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app) { ... ... ...} + + GSimpleAction *act_quit = g_simple_action_new ("quit", NULL); + g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), app); + GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit"); + +1. `menu_item_quit` is a menu item. +It has a label "Quit" and is connected to an action "app.quit". +"app" is a prefix and "quit" is the name of an action. +The prefix means that the action belongs to GtkApplication. +If the menu is clicked, then the corresponding action "quit" which belongs to GtkApplication will be activated. +2. `act_quit` is an action. +It has a name "quit". +It belongs to GtkApplication, but it is not obvious in the code above. +The function `g_simple_action_new` generates a stateless action. +So, `act_quit` is stateless. +The meaning of stateless will be explained later. +The argument `NULL` means that the action doesn't have an parameter. +Generally, most of the actions are stateless and have no parameter. +When `act_quit` is activated, it will emit "activate" signal. +3. "activate" signal of the action is connected to the handler `quit_activated`. +So, if the action is activated, the handler will be invoked. + +## Simple example + +The following is a simple example of menus and actions. + +@@@ menu1.c + +- 3-7: `quit_activated` is a handler of an action `act_quit`. +Handlers of actions have three parameters. + 1. The action object which has emitted the signal. + 2. Parameter. +In this example it is `NULL` because the second argument of `g_simple_action_new` (line 15) is `NULL`. +You don' t need to care about it. + 3. User data. +It is the fourth parameter in the `g_signal_connect` (line 17) that has connected the action and the handler. +- 6: A function `g_application_quit` immediately quits the application. +- 9-33: `on_activate` is a handler of "activate" signal on GtkApplication. +- 11-13: Generate a GtkApplicationWindow and set a pointer to it to `win`. And set the title and default size. +- 15: Generate GSimpleAction `act_quit`. +It is stateless. +The first argument of `g_simple_action_new` is a name of the action and the second argument is a parameter. +If you don't need the parameter, set it `NULL`. +THerefore, `act_quit` has a name "quit" and no parameter. +- 16: Add the action to GtkApplication `app`. +GtkApplication implements an interface GActionMap and GActionGroup. +And GtkApplication can have a group of actions and actions are added by the function `g_action_map_add_action`. +This function is described in GMenuModel section in GIO API reference. +- 17: Connect "activate" signal of the action and the handler `quit_activated`. +- 19-22: Generate GMenu and GMenuItem. +`menubar` and `menu` are GMenu. +`menu_item_menu` and `menu_item_quit` are GMenuItem. +`menu_item_menu` has a label "Menu" and no action. +`menu_item_quit` has a label "Quit". +The second argument "app.quit" is a combination of "app" and "quit". +"app" is a prefix and it means that the action belongs to GtkApplication. "quit" is the name of the action. +Therefore, it points the action which belongs to GtkApplication and has the name "quit" -- it is `act_quit`. +- 23-24: Append `act_quit` to `menu`. +As I mentioned before, all the attribute and link values are copied and used to form a new item within `menu`. +Therefore after the appending, `menu` has a copy of `act_quit` in itself and `act_quit` is no longer needed. +It is freed by `g_object_unref`. +- 25: Set a submenu link to `menu_item_menu`. +And the link points the GMenu `menu`. +- 26-27: Append `menu_item_menu` to `menubar`. +Then free `menu_item_menu`. +GMenu and GMenuItem are connected and finally a menu is made up. +The structure of the menu is shown in the diagram below. +- 29: The menu is set to GtkApplication. +- 30: Set GtkApplicationWindow to show the menubar. +- 31: Show the window. + +![menu and action](menu1.png) + +![Screenshot of menu1](menu1_screenshot.png) + diff --git a/src/sec15.src.md b/src/sec15.src.md new file mode 100644 index 0000000..5b9047b --- /dev/null +++ b/src/sec15.src.md @@ -0,0 +1,257 @@ +# Stateful action + +Some actions have states. +The values of states can be boolean or string. +Actions which have states are called stateful. + +## Stateful action without a parameter + +Some menus are called toggle menu. +For example, fullscreen menu has a state which has two values -- fullscreen and non-fullscreen. +The value of the state is changed every time the menu is clicked. +An action corresponds to the fullscreen menu also have a state. +Its value is TRUE or FALSE and it is called boolean value. +TRUE corresponds to fullscreen and FALSE to non-fullscreen. + +The following is an example code to implement a fullscreen menu except the signal handler. +The signal handler will be described after the explanation of this code. + + static void + on_activate (GApplication *app, gpointer user_data) { + ... ... ... + GSimpleAction *act_fullscreen = g_simple_action_new_stateful ("fullscreen", NULL, g_variant_new_boolean (FALSE)); + GMenuItem *menu_item_fullscreen = g_menu_item_new ("Full Screen", "win.fullscreen"); + g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win); + ... ... ... + } + +- `act_fullscreen` is GSimpleAction. +It is generated by `g_simple_action_new_stateful`. +The function has three arguments. +The first argument "fullscreen" is the name of the action. +The second argument is a parameter type. +`NULL` means the action doesn't have a parameter. +The third argument is the initial state of the action. +It is a GVariant value. +GVariant will be explained in the next subsection. +The function `g_variant_new_boolean (FALSE)` returns a GVariant value which is the boolean value `FALSE`. +- `menu_item_fullscreen` is GMenuItem. +There are two arguments. +The first argument "Full Screen" is a label which is one of the attributes of GMenuItem. +The second argument is called detailed action. +Detailed action has three parts, prefix, action name and target. +"win.fullscreen" means that the prefix is "win", the action name is "fullscreen" and there's no target. +The prefix says that the action belongs to the window. +- connect the action `act_fullscreen` and the "change-state" signal handler `fullscreen_`value2`changed`. +If the fullscreen menu is clicked, then the corresponding action `act_fullscreen` is activated. +But no handler is connected to "activate" signal. +Then, the default behaviour for boolean-stated actions with a NULL parameter type like `act_fullscreen` is to toggle them via the “change-state” signal. + +The following is the "change-state" signal handler. + + static void + fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) { + if (g_variant_get_boolean (value)) + gtk_window_maximize (GTK_WINDOW (win)); + else + gtk_window_unmaximize (GTK_WINDOW (win)); + g_simple_action_set_state (action, value); + } + +- There are three parameters. +The first parameter is the action which emits the "change-state" signal. +The second parameter is the value of the state of the action. +But it is toggled because of no "activate" signal handler. +Ther third parameter is a user data which is set in `g_signal_connect`. +- If the value is boolean type and `TRUE`, then maximize the window. +Otherwise unmaximize. +- Set `value` to the state of the action. +Note: the second argument was the toggled state value, but at this stage the state of the action has the original value. +So, you need to set the new value by `g_simple_action_set_state`. + +You can use "activate" signal instead ot "change-state" signal, or both signals. +But the way above is the simplest and best. + +### GVariant + +GVarient can contain boolean, string or other simple type values. +For example, the following program set TRUE to `value` whose type is GVariant. + + GVariant *value = g_variant_new_boolean (TRUE); + +Another example is: + + GVariant *value2 = g_variant_new_string ("Hello"); + +`value2` is a GVariant and it has a string type value "Hello". +GVariant can contain other types like int16, int32, int64, double and so on. + +If you want to get the boolean value, use g\_variant\_get series functions. + + gboolean bool = g_variant_get_boolean (value); + +Because `value` has been generated as a boolean type GVariant and `TRUE` value, `bool` equals `TRUE`. +In the same way, you can get a string from `value2` + + const gchar *str = g_variant_get_string (value2, NULL); + +The second parameter is a pointer to gsize type variable (gsize is defined as unsigned long). +If it isn't NULL, then the length of the string will be set by the function. +If it is NULL, nothing happens. +The returned string `str` can't be changed. + +## Stateful action with a parameter + +Another example of stateful actions is an action corresponds to color select menus. +For example, there are three menus and each menu has red, green or blue color respectively. +They determine the background color of a certain widget. +One action is connected to the three menus. +The action has a state which values are "red", "green" and "blue". +The values are string. +Those colors are given to the signal handler as a parameter. + + static void + on_activate (GApplication *app, gpointer user_data) { + ... ... ... + GSimpleAction *act_color = g_simple_action_new_stateful ("color", g_variant_type_new("s"), g_variant_new_string ("red")); + GMenuItem *menu_item_red = g_menu_item_new ("Red", "win.color::red"); + GMenuItem *menu_item_green = g_menu_item_new ("Green", "win.color::green"); + GMenuItem *menu_item_blue = g_menu_item_new ("Blue", "win.color::blue"); + g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win); + ... ... ... + } + +- `act_color` is GSimpleAction. +It is generated by `g_simple_action_new_stateful`. +The function has three arguments. +The first argument "color" is the name of the action. +The second argument is a parameter type which is GVariantType. +`g_variant_type_new("s")` generates GVariantType which is a string type (G\_VARIANT\_TYPE\_STRING). +The third argument is the initial state of the action. +It is a GVariant. +GVariantType will be explained in the next subsection. +The function `g_variant_new_string ("red")` returns a GVariant value which has the string value "red". +- `menu_item_red` is GMenuItem. +There are two arguments. +The first argument "Red" is a label which is one of the attributes of GMenuItem. +The second argument is a detailed action. +Its prefix is "win", action name is "color" and target is "red". +Target is sent to the action as a parameter. +The same goes for `menu_item_green` and `menu_item_blue`. +- connect the action `act_color` and the "activate" signal handler `color_activate`. +If one of the three menus is clicked, then the action `act_color` is activated with a parameter to which the menu item gives its target. +No handler is connected to "change-state" signal. +Then the default behaviour is to call `g_simple_action_set_state()` to set the state to the requested value. + +The following is the "activate" signal handler. + + static void + color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) { + gchar *color = g_strdup_printf ("label#lb {background-color: %s;}", g_variant_get_string (parameter, NULL)); + gtk_css_provider_load_from_data (provider, color, -1); + g_free (color); + g_action_change_state (G_ACTION (action), parameter); + } + +- There are three parameters. +The first parameter is the action which emits the "activate" signal. +The second parameter is the parameter given to the action. +It is a color specified by the menu. +The third parameter is a user data which is set in `g_signal_connect`. +- `color` is a CSS string generated by `g_strdup_printf`. +The parameter of `g_str_dup` is the same as printf C standard function. +`g_variant_get_string` get the string contained in `parameter`. +- Set the color to the css provider. +- Free the string `color`. +- Change the state by `g_action_change_state`. +The function just set the parameter to the state of the action by `g_simple_action_set_state`. +Therefore, you can use `g_simple_action_set_state` instead of `g_action_change_state`. + +Note: If you have set a "change-state" signal handler, `g_action_change_state` will emit "change-state" signal instead of calling `g_simple_action_set_state`. + +### GVariantType + +GVariantType gives a type of GVariant. +GVariant can contain many kinds of types. +And the type often needs to be recognized at runtime. +GVariantType provides such functionality. + +When GVariantType is generated, the type is expressed by the string. + +- "b" means boolean type. +- "s" means string type. + +The following program is a simple example. +It finally output the string "s". + +@@@ gvarianttype_test.c + +- `g_variant_tpe_new` generates GVariantType. +It uses a type string "s" which means string. +- `g_variant_type_peek_string` takes a peek at `vtype`. +It is the string "s" given at the generation time. +- print the string to the terminal. + +## Example code +The following code includes stateful actions above. +This program has menus like this: + +![menu2](menu2.png) + +- Fullscreen menu toggles the size of the window between maximum and non-maximum. +If the window is maximum size, which is called full screen, then a check mark is put before "fullscreen" label. +- Red, green and blue menu determines the back ground color of the label, which is the child widget of the window. +The menus have radio buttons on the left of each of the menus. +And the radio button of the selected menu turns on. +- Quit menu quits the application. + +The code is as follows. + +@@@ menu2.c + +- 5-26: Signal handlers. +They have been explained in this section. +- 30-36: `win` and `lb` are GtkApplicationWindow and GtkLabel respectively. +`win` has a title "menu2" and its defaust size is 400x300. +`lb` is named as "lb". +The name is used in CSS. +`lb` is set to `win` as a child. +- 38-43: Three actions are defined. +They are: + - stateful and has no parameter. +It has a toggle state. + - stateful and has a parameter. +Parameter is a string type. + - stateless and has no parameter. +- 45-54: Generate GMenu and GMenuItem. +There are three sections. +- 56-61: Signals are connected to handlers. +And actions are added to GActionMap. +Because `act_fullscreen` and `act_color` have "win" prefix and belong to GtkApplicationWindow, +they are added to `win`. +GtkApplicationWindow implements GActionModel interface like GtkApplication. +`act_quit` has "app" prefix and belongs to GtkApplication, +it is added to `app`. +- 63-77: Connect and build the menus. +Useless GMenuItem are freed. +- 79-80: GMenuModel `menubar` is set to `app`. +Set show menubar property to `TRUE` in `win`. +Note: `gtk_application_window_set_show_menubar` generates GtkPopoverMenubar from GMenuModel. +This is a different point between Gtk3 and Gtk4. +And you can use GtkPopoverMenubar directly and set it as a descendant widget of the window. +You may use GtkBox as a child widget of the window and set GtkPopoverMenubar as the first child of the box. +- 82-87: Set CSS. +`provider` is GtkCssProvider which is defined in line three as a static variable. +Its CSS data is: +`label#lb {background-color: red;}`. +"label#lb" is called selector. +"label" is the node of GtkLabel. +"#" precedes an ID which is an identiable name of the widget. +"lb" is the name of GtkLabel `lb`. +(See line 35). +The style is surrounded by open and close braces. +The style is applied to GtkLabel which has a name "lb". +Other GtkLabel have no effect from this. +The provider is added to GdkDisplay. +- 90: Show the window. + diff --git a/src/sec16.src.md b/src/sec16.src.md new file mode 100644 index 0000000..56e580b --- /dev/null +++ b/src/sec16.src.md @@ -0,0 +1,145 @@ +# Ui file for menu and action entries + +## Ui file for menu + +You might have thought that building menus is really bothersome. +Yes, the program was complicated and it needs lots of time to code it. +The situation is similar to building widgets. +When we built widgets, using ui file was a good way to avoid such complicated coding. +The same goes for menus. + +The ui file for menus has interface, menu tags. +The file starts and ends with interface tag. + + + + + + +`menu` tag corresponds to GMenu object. +`id` attribute defines the name of the object. +It will be refered by GtkBuilder. + + + File + + New + win.new + + + +`item` tag corresponds to item in GMenu which has the same structure as GMenuItem. +The item above has a label attribute. +Its value is "New". +The item also has an action attribute and its value is "win.new". +"win" is a prefix and "new" is an action name. +`submenu` tag corresponds to both GMenuItem and GMenu. +The GMenuItem has a link to GMenu. + +The ui file above can be described as follows. + + + File + + + New + win.new + + + + +`link` tag expresses the link to submenu. +And at the same time it also expresses the submenu itself. +This file illustrates the relationship between the menus and items better than the prior ui file. +But `submenu` tag is simple and easy to understand. +So, we usually prefer the former ui file style. + +The following is a screenshot of the sample program in this section. +Its name is `menu3`. + +![menu3](menu3.png) + +The following is the ui file of the menu in `menu3`. + +@@@ menu3/menu3.ui + +The ui file is converted to the resource by the resouce compiler `glib-compile-resouces` with xml file below. + +@@@ menu3/menu3.gresource.xml + +GtkBuilder builds menus from the resource. + + GtkBuilder *builder = gtk_builder_new_from_resource ("/com/github/ToshioCP/menu3/menu3.ui"); + GMenuModel *menubar = G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")); + + gtk_application_set_menubar (GTK_APPLICATION (app), menubar); + g_object_unref (builder); + +It is important that `builder` is unreferred after the GMenuModel `menubar` is set to the application. +If you do it before setting, bad thing will happen -- your computer might freeze. + +## Action entry + +The coding for building actions and signal handlers is always the same. +Therefore, it can be automated. +You can implement them easily with GActionEntry `g_action_map_add_action_entries`. + +GActionEntry is a strutcure. +It contains action name, signal handlers, parameter and state. + + typedef struct _GActionEntry GActionEntry; + + struct _GActionEntry + { + const gchar *name; /* action name */ + void (* activate) (GSimpleAction *action, GVariant *parameter, gpointer user_data); /* activate handler */ + const gchar *parameter_type; /* the type of the parameter given as a single GVariant type string */ + const gchar *state; /* initial state given in GVariant text format */ + void (* change_state) (GSimpleAction *action, GVariant *value, gpointer user_data); /* change-state handler */ + /*< private >*/ + gsize padding[3]; + }; + +For example, the actions in the previous section are: + + { "fullscreen", NULL, NULL, "false", fullscreen_changed } + { "color", color_activated, "s", "red", NULL } + { "quit", quit_activated, NULL, NULL, NULL }, + +And `g_action_map_add_action_entries` does all the process instead of the functions you have needed. + + const GActionEntry app_entries[] = { + { "quit", quit_activated, NULL, NULL, NULL } + }; + g_action_map_add_action_entries (G_ACTION_MAP (app), app_entries, G_N_ELEMENTS (app_entries), app); + +The code above does: + +- Build the "quit" action +- Connect the action and the "activate" signal handler `quit_activate` +- Add the action to the action map `app`. + + const GActionEntry win_entries[] = { + { "fullscreen", NULL, NULL, "false", fullscreen_changed }, + { "color", color_activated, "s", "red", NULL } + }; + g_action_map_add_action_entries (G_ACTION_MAP (win), win_entries, G_N_ELEMENTS (win_entries), win); + +The code above does: + +- Build the "fullscreen" action and "color" action. +- Connect the "fullscreen" action and the "change-state" signal handler `fullscreen_changed` +- Its initial state is set to FALSE. +- Connect the "color" action and the "activate" signal handler `color_activate` +- Its parameter type is string and the initial value is "red". +- Add the action to the action map `win`. + +## Example code + +The C source code of `menu3` and `meson.build` is as follows. + +@@@ menu3/menu3.c + +meson.build + +@@@ menu3/meson.build diff --git a/src/sec17.src.md b/src/sec17.src.md new file mode 100644 index 0000000..632e06c --- /dev/null +++ b/src/sec17.src.md @@ -0,0 +1,4 @@ +# GtkMenuButton + +before close + diff --git a/src/sec2.src.md b/src/sec2.src.md new file mode 100644 index 0000000..63322aa --- /dev/null +++ b/src/sec2.src.md @@ -0,0 +1,141 @@ +# Widgets (1) + +## GtkLabel, GtkButton and Gtkbox + +### GtkLabel + +We made an window and show it on the screen in the previous chapter. +Now we go on to the next topic, widgets in the window. +The simplest widget is GtkLabel. +It is a widget with a string in it. + +@@@ lb1.c + +Save this program to a file `lb1.c`. +Then compile and run it. + + $ comp lb1 + $ ./a.out + +A window with a message "Hello." appears. + +![Screenshot of the label](screenshot_lb1.png) + +There's only a little change between `pr4.c` and `lb1.c`. +Diff is a good program to know the difference between two files. + +$$$ +diff misc/pr4.c lb1.c +$$$ + +This tells us: + +- The definition of a variable lab is added. +- The title of the window is changed. +- A label is generated and connected to the window. + +The function `gtk_window_set_child (GTK_WINDOW (win), lab)` makes the label `lab` a child widget of the window `win`. +Be careful. +A child widget is different from a child object. +Objects have parent-child relationship and Widgets also have parent-child relationship. +But these two relationships are totally different. +Don't be confused. +In the program `lb1.c`, `lab` is a child widget of `win`. +Child widgets are always located inside its parent widget in the screen. +See the window appeared on the screen. +The window includes the label. + +The window `win` dosen't have any parents. +We call such a window top-level window. +One application can have two or more top-level windows. + +### GtkButton + +Next widget is GtkButton. +It has a label or icon on it. +In this subsection, we will make a button with a label. +When a button is clicked on, it emits a "clicked" signal. +The following program shows how to catch the signal and do something. + +@@@ lb2.c + +Look at the line 17 to 19. +First, generate a GtkButton widget `btn` with a label "Click me". +Then, set it to the window `win` as a child. +Finally, connect a "clicked" signal of the button to a handler (function) `on_click`. +So, if `btn` is clicked, the function `on_click` is invoked. + +Name the program `lb2.c` and save it. +Now compile and run it. + +![Screenshot of the label](screenshot_lb2.png) + +A window with the button appears. +Click the button (it is a large button, you can click everywhere inside the window), then a string "Clicked." appears on the shell terminal. +It shows the handler was invoked by clicking the button. + +It's fairly good for us to make sure that the clicked signal was caught and the handler was invoked. +However, using g_print is out of harmony with GTK which is a GUI library. +So, we will change the handler. +The following code is `lb3.c`. + +@@@ lb3.c on_clicked on_activate + +And the difference between `lb2.c` and `lb3.c` is as follows. + +$$$ +diff lb2.c lb3.c +$$$ + +The change is: + +- The function `g_print` in `lb2.c` was deleted and two lines above are inserted instead. +- The label of `btn` is changed from "Click me" to "Quit". +- The fourth argument of `g_signal_connect` is changed from `NULL` to `win`. + +Most important is the fourth argument of `g_signal_connect`. +It is described as "data to pass to handler" in the definition of g\_signal\_connect in GObject API reference. +Therefore, `win` which is a pointer to GtkApplicationWindow is passed to the handler as a second parameter user_data. +Then, the handler cast it to a pointer to GtkWindow and call `gtk_window_destroy` and destroy the top window. +Then, the application quits. + +### GtkBox + +GtkWindow and GtkApplicationWindow can have only one child. +If you want to add two or more widgets inside a window, you need a container widget. +GtkBox is one of the containers. +It arranges two or more child widgets into a single row or column. +The following procedure shows the way to add two buttons in a window. + +- Generate GtkApplicationWindow. +- Generate GtkBox and set it a child of GtkApplicationWindow. +- Generate GtkButton and append it to GtkBox. +- Generate another GtkButton and append it to GtkBox. + +After this, the Widgets are connected as following diagram. + +![Parent-child relationship](box.png) + +Now, code it. + +@@@ lb4.c + +Look at the function `on_activate`. + +After the generation of GtkApplicationWindow, GtkBox is generated. + + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); + gtk_box_set_homogeneous (GTK_BOX (box), TRUE); + +The first argument arranges children vertically. +The second argument is sizes between children. +The next function fills a box with children, giving them equal space. + +After that, two buttons `btn1` and `btn2` are generated and the signal handlers are set. +Then, these two buttons are appended to the box. + +![Screenshot of the box](screenshot_lb4.png) + +The handler corresponds to `btn1` changes its label. +The handler corresponds to `btn2` destroys the top-level window and the application quits. + diff --git a/src/sec3.src.md b/src/sec3.src.md new file mode 100644 index 0000000..33e4d68 --- /dev/null +++ b/src/sec3.src.md @@ -0,0 +1,57 @@ +# Widgets (2) + +## GtkTextView, GtkTextbuffer and GtkScrolledWindow + +### GtkTextView and GtkTextBuffer + +GtkTextview is a widget for multiline text editing. +GtkTextBuffer is a text buffer which is connected to GtkTextView. +See a sample program `tfv1.c` below. + +@@@ tfv1.c + +Look at line 25. +GtkTextView is generated and its pointer is assigned to `tv`. +When GtkTextView is generated, the connected GtkTextBuffer is also generated automatically. +In the next line, the pointer to the buffer is got and assigned to `tb`. +Then, the text from line 10 to 20 is assigned to the buffer. + +GtkTextView has a wrap mode. +When `GTK_WRAP_WORD_CHAR` is set, text wraps in between words, or if that is not enough, also between graphemes. + +In line 30, `tv` is set to `win` as a child. + +Now compile and run it. + +![GtkTextView](screenshot_tfv1.png) + +There's an I-beam pointer in the window. +You can add or delete any character on GtkTextview. +And your change is kept in GtkTextBuffer. +If you add more characters than the limit of the window, the height of the window extends. +If the height gets bigger than the height of the display screen, you won't be able to control the size of the window back to the original size. +It's a problem. +You can solve it by putting GtkScrolledWindow between GtkApplicationWindow and GtkTextView. + +### GtkScrolledWindow + +What we need to do is: + +- Generate GtkScrolledWindow and set it as a child of GtkApplicationWindow. +- Set GtkTextVies as a child of GtkScrolledWindow. + +Modify `tfv1.c` and save it as `tfv2.c`. +The difference between these two files is very little. + +$$$ +diff tfv1.c tfv2.c +$$$ + +Though you can modify the source file by this diff output, It's good for you to show `tfv2.c`. + +@@@ tfv2.c + +Now compile and run it. +This time the window doesn't extend even if you type a lot of characters. +It just scrolls. + diff --git a/src/sec4.src.md b/src/sec4.src.md new file mode 100644 index 0000000..48653c7 --- /dev/null +++ b/src/sec4.src.md @@ -0,0 +1,178 @@ +# Widgets (3) + +## Open signal + +### G\_APPLICATION\_HANDLES\_OPEN flag + +GtkTextView, GtkTextBuffer and GtkScrolledWindow have given us a minimum editor in the previous section. +Next, we will add a read function to this program and remake it into a file viewer. +There are many way to implement the function. +However, because this is a tutorial for beginners, we take the simplest way. + +When the program starts, we give a filename as an argument. + + $ ./a.out filename + +Then it opens the file and set it into GtkTextBuffer. + +At the beginning of the implementation, we need to know how GtkApplication (or GApplication) recognizes arguments. +It is described in the GIO API reference. + +When GtkApplication is generated, a flag (its type is GApplicationFlags) is given as an argument. + + GtkApplication * + gtk_application_new (const gchar *application_id, GApplicationFlags flags); + +This flag is described in the GApplication section in GIO API reference. + + GApplicationFlags' Members + + G_APPLICATION_FLAGS_NONE Default. (No argument allowed) + ... ... ... + G_APPLICATION_HANDLES_OPEN This application handles opening files (in the primary instance). + ... ... ... + +There are ten flags. +But we only need two of them so far. +We've already used `G_APPLICATION_FLAGS_NONE`. +It is the simplest option. +No argument is allowed. +If you give arguments and run the application, then error occurs. + +`G_APPLICATION_HANDLES_OPEN` is the second simplest option. +It allows arguments but only files. +The application assumes all the arguments are filenames. + +Now we use this flag when generating GtkApplication. + + app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN); + +### open signal + +When the application starts, two signals are possible. + +- activate signal --- This signal is emitted when there's no argument. +- open signal --- This signal is emitted when there is at least one argument. + +The handler of open signal is called as follows. + + void user_function (GApplication *application, + gpointer files, + gint n_files, + gchar *hint, + gpointer user_data) + +The parameters are as follows: + +- application --- the application (usually GtkApplication) +- files --- an array of GFiles. [array length=n_files] [element-type GFile] +- n_files --- the length of files +- hint --- a hint provided by the calling instance (usually it can be ignored) +- user_data --- user data set when the signal handler was connected. + +The way how to read a file using GFiles will be described in the next section. + +## Coding a file viewer + +### What is a file viewer? + +A file viewer is a program that shows a text file given as an argument. +It works as follows. + +- If it is given arguments, it recognizes the first argument as a filename and open it. +- If opening the file succeeds, read and set it to GtkTextBuffer and show the window. +- If it fails to open the file, show an error message and quit. +- If there's no argument, show an error message and quit. +- If there are two or more arguments, the second one and after are ignored. + +The program is as follows. + +@@@ tfv3.c + +Save it as `tfv3.c`. +Then compile and run it. + + $ comp tfv3 + $ ./a.out tfv3.c + +![File viewer](screenshot_tfv3.png) + +Now I want to explain the program `tfv3.c`. +First, the function `main` changes in only two lines. + +- `G_APPLICATION_FLAGS_NONE` is replaced with `G_APPLICATION_HANDLES_OPEN`. +- `g_signal_connect (app, "open", G_CALLBACK (on_open), NULL)` is added. + +Next, the handler `on_activate` is now very simple. +Just output the error message. +The application quits immediately because no window is generated. + +The point is the handler `on_open`. + +- It generates GtkApplicationWindow, GtkScrolledWindow, GtkTextView and GtkTextBuffer and connect them. +- Set wrap mode to `GTK_WRAP_WORD_CHAR` in GtktextView. +- Set non-editable to GtkTextView because the program isn't an editor but only a viewer. +- Read the file and set it to GtkTextBuffer (this will be explained in detail later). +- If the file is not opened then output an error message and destroy the window. It makes the application quit. + +The file reading part of the program is shown again below. + + if (g_file_load_contents(files[0], NULL, &contents, &length, NULL, NULL)) { + gtk_text_buffer_set_text(tb, contents, length); + g_free(contents); + filename = g_file_get_basename(files[0]); + gtk_window_set_title (GTK_WINDOW (win), filename); + g_free(filename); + gtk_widget_show (win); + } else { + filename = g_file_get_path(files[0]); + g_print ("No such file: %s.\n", filename); + gtk_window_destroy (GTK_WINDOW (win)); + } + +The function `g_file_load_contents` loads the file contents into a buffer, which is automatically allocated, and set the pointer to the buffer into `contents`. +And the length of the buffer is set to `length`. +It returns `TRUE` if the file's contents were successfully loaded. `FALSE` if there were errors. + +If the function succeeds, set the contents into GtkTextBuffer, free the buffer memories pointed by `contents`, set the filename to the title of the window, +free the memories pointed by `filename` and show the window. +If it fails, it outputs an error message and destroy the window. + +## GtkNotebook + +GtkNotebook is a container widget that contains multiple children with tabs in it. + +![GtkNotebook](screenshot_gtk_notebook.png) + +Look at the screenshots above. +The left one is a window at the startup. +It shows the file `pr1.c`. +The filename is in the left tab. +After clicking on the right tab, then the contents of `tfv1.c` appears. +It is shown in the right screenshot. + +GtkNotebook widget is between GtkApplicationWindow and GtkScrolledWindow. +Now I want to show you the program `tfv4.c`. + +@@@ tfv4.c + +Most of the change is in the function `on_open`. +The numbers at the left of the following items are line numbers in the source code. + +- 11-13: Variables `nb`, `lab` and `nbp` are defined and point GtkNotebook, GtkLabel and GtkNotebookPage respectively. +- 23: The window's title is set to "file viewer". +- 25: The size of the window is set to maximum because a big window is appropriate for file viewers. +- 27-28 GtkNotebook is generated and set it as a child of GtkApplicationWindow. +- 30-52 For-loop. Each loop corresponds to an argument. And files[i] is GFile object with respect to the i-th argument. +- 32-37 GtkScrollledWindow, GtkTextView and GtkTextBuffer are generated and GtkTextView is connected to GtkScrolledWindow as a child. + They corresponds to each file, so they are generated inside the for-loop. +- 39-42 Set the contents of the file into GtkTextBuffer and free the memory pointed by `contents`. Get the filename and generate GtkLabel with the filename. +- 43: Append GtkScrolledWindow and GtkLabel to GtkNotebook. The appended objects are children of automatically generated GtkNotebookPage object. Therefore, the structure is like this: + + GtkNotebook -- GtkNotebookPage -- (GtkScrolledWindow and GtkLabel) + +- 44: Get GtkNotebookPage object and set its pointer to `nbp`. +- 45: GtkNotebookPage has a property "tab-expand". If it is set to TRUE then the tab expand horizontally as long as possible. If FALSE, then the width of the tab is determined by the size of the label. `g_object_set` is a general function to set properties in any objects. +- 46: free the memory pointed by `filename` +- 53-56: If at least one file was read, then the number of GtkNotebookPage is greater than zero. If it's true, then show the window. If it's false, then destroy the window. + diff --git a/src/sec5.src.md b/src/sec5.src.md new file mode 100644 index 0000000..554bc65 --- /dev/null +++ b/src/sec5.src.md @@ -0,0 +1,187 @@ +# Define Child object + +## Very simple editor + +We made a very simple file viewer in the previous section. +Now we go on to rewrite it and make a very simple editor. +Its source file name is tfe1.c (text file editor 1). + +GtkTextView originally has a feature of multi line editing. +Therefore, we don't need to rewrite the program from scratch. +We just add two things to the file viewer. + +- Static memory is needed to store a pointer to GFile. +- We need to implement file write function. + +A couple of ways are possible to get memories to keep GFile. + +- Use global variables. +- make a child widget object and extend the memories allocated to the widget. + +Using global variables is easy to implement. +Define a sufficient size array of pointers to GFile. +For example, + + GFile *f[20]; + +And `f[i]` corresponds to i-th GtkNotebookPage. +However, there are two problems. +One is the size of the array. +If a user gives arguments more than that, bad thing may happen. +The other is the difficulty of maintenance of the program. +It is a small program so far. +However, if you continue developing it, then its size grows bigger and bigger. +Generally speaking, the bigger the program size, the more difficult to maintain global variables. + +Making child widget object is a good idea in terms of maintenance. +However, one thing you need to be careful is the difference between "child object" and "child widget". +What we are thinking about now is "child object". +A child object includes its parent object. +And a child widget object derives everything from the parent widget object. + +![Child widget of GtkTwxtView](child.png) + +We will define TfeTextView as a child widget object of GtkTextView. +It has everything that GtkTextView has. +For example, TfeTextView has GtkTextbuffer correspods to GtkTextView inside TfeTextView. +And important thing is that TfeTextView can have a memory to keep a pointer to GFile. + +However, to understand the general theory about gobjects is very hard especially for beginners. +So, I will just show you the way how to write the code and avoid the theoretical side in the next section. + +## How to define a child widget of GtkTextView + + +Let's define TfeTextView widget object which is a child object of GtkTextView. +First, look at the program below. + + #define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () + G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + + struct _TfeTextView + { + GtkTextView parent; + GFile *file; + }; + + G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + + static void + tfe_text_view_init (TfeTextView *tv) { + } + + static void + tfe_text_view_class_init (TfeTextViewClass *class) { + } + + void + tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + tv -> file = f; + } + + GFile * + tfe_text_view_get_file (TfeTextView *tv) { + return tv -> file; + } + + GtkWidget * + tfe_text_view_new (void) { + return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); + } + +If you are curious about the background theory of this program, It's very good for you. +Because to know the theory is very important for you to program GTK applications. +Look at GObject API reference. +All you need is described in it. +However, it's a tough journey especially for beginners. +For now, you don't need to know such difficult theory. +Just remember the instructions below. + +- TfeTextView is divided into two parts. +Tfe and TextView. +Tfe is called prefix, namespace or module. +TextView is called object. +- There are three patterns. +TfeTextView (camel case), tfe\_text\_view (this is used to write functions) and TFE\_TEXT\_VIEW (This is used to write casts). +- First, define TFE\_TYPE\_TEXT\_VIEW as tfe\_text\_view\_get\_type (). +The name is always (prefix)\_TYPE\_(object) and the letters are upper case. +And the replacement text is always (prefix)\_(object)\_get\_type () and the letters are lower case. +- Next, use G\_DECLARE\_FINAL\_TYPE macro. +The arguments are the child object name in camel case, lower case with underscore, prefix, object and parent object name. +- Declare the structure \_TfeTextView. +The underscore is necessary. +The first member is the parent object. +Notice this is not a pointer but the object itself. +The second member and after are members of the child object. +TfeTextView structure has a pointer to GFile as a member. +- Use G\_DEFINE\_TYPE macro. +The arguments are the child object name in camel case, lower case with underscore and parent object type (prefix)\_TYPE\_(module). +- Define instance init function (tfe\_text\_view\_init). +Usually you don't need to do anything. +- Define class init function (tfe\_text\_view\_class\_init). +You don't need to do anything in this widget. +- Write function codes you want to add (tfe\_text\_view\_set\_file and tfe\_text\_view\_get\_file). +`tv` is a pointer to TfeTextView object instance which is a C-struture declared with the tag \_TfeTextView. +So, the structure has a member `file` as a pointer to GFile. +`tv->file = f` is an assignment of `f` to a member `file` of the structure pointed by `tv`. +This is an example how to use the extended memory in a child widget. +- Write object generation function. +Its name is (prefix)\_(object)\_new. +If the parent object function needs parameters, this function also need them. +You sometimes might want to add some parameters. +It's your choice. +Use gtk\_widget\_new function to generate the child widget. +The arguments are (prefix)\_TYPE\_(object), a list to initialize properties and NULL. +In this code no property needs to be initialized. + +This program is not perfect. +It has some problem. +But I don't discuss it now. +It will be modified later. + +## Close-request signal + +As a first step, `tfe1.c` writes files just before the window closes. +GtkWindow emits "close-request" signal before it closes. +We connect the signal and the handler `before_close`. +A handler is a C function. +When a function is connected to a certain signal, we call the function handler. +Then, the function `before_close` is invoked when the signal "close-request" is emittd. + + g_signal_connect (win, "close-request", G_CALLBACK (before_close), NULL); + +The argument win is GtkApplicationWindow, in which the signal "close-request" is defined, and before\_close is the handler. +`G_CALLBACK` cast is necessary before the handler. +The program of before\_close is as follows. + +@@@ tfe1.c before_close + +The numbers on the left of items are line numbers in the source code. + +- 13: Get the number of pages `nb` has. +- 14-23: For loop with regard to the index to each pages. +- 15-17: Get GtkScrolledWindow, TfeTextView and a pointer to GFile. The pointer was stored when `on_open` handler ran. It will be shown later. +- 18-20: Get GtkTextBuffer and contents. start\_iter and end\_iter is iterators of the buffer. I don't want to explain them now because it would take a lot of time. Just remember these lines for the present. +- 21: Write the file. + +## Source code of tfe1.c + +Now I will show you all the source code of `tfe1`.c. + +@@@ tfe1.c + +- 102: set the pointer to GFile into TfeTextView. +`files[i]` is a pointer to GFile structure. +It will be freed by the system. So you need to copy it. +`g_file_dup` duplicate the given GFile structure. +- 118: connect "close-request" signal and `before_close` handler. +The fourth argument is called user data and it is given to the signal handler. +So, `nb` is given to `before_close` as the second argument. + +Now compile and run it. +Type `./a.out somefile` and make sure that the file is modified. + +Now we got a very simple editor. +It's not smart. +We need more features like open, save, saveas, change font and so on. +We will add them in the next section and after. diff --git a/src/sec6.src.md b/src/sec6.src.md new file mode 100644 index 0000000..424ba16 --- /dev/null +++ b/src/sec6.src.md @@ -0,0 +1,174 @@ +# Ui file and GtkBuiler + +## New, open and save button + +We made the simplest editor in the previous section. +It reads the files in `on_open` funciton at start-up and writes it at closing window. +It works but is not good. +It is better to make "New", "Open", "Save" and "Close" buttons. +This section describes how to put those buttons into the window. +Signals and handlers will be explained later. + +![Screenshot of the file editor](screenshot_tfe2.png) + +The screenshot above shows the layout. +The function `on_open` in the source code `tfe2.c` is as follows. + +@@@ tfe2.c on_open + +The point is how to build the window. + +- 26-28: Generate GtkApplicationWindow and set its title and default size. +- 30-31: Generate GtkBox `boxv`. +It is a vertical box and a child of GtkApplicationWindow. +It has two children. +The first child is a horizontal box includes buttons. +The second child is GtkNotebook. +- 33-34: Generate GtkBox `boxh` and append it to 'boxv' as a first child. +- 36-41: Generate three dummy labels. +The labels `dmy1` and `dmy3` has a character width of ten. +The other label `dmy2` is set hexpand property TRUE. +This makes the label expands horizontally as long as possible. +- 42-45: Generate four buttons. +- 47-53: Append these GtkLabel and GtkButton to `boxh`. +- 55-58: Generate GtkNotebook and set hexpand and vexpand properties TRUE. +This makes it expands horizontally and vertically as big as possible. +It is appended to `boxv` as the second child. + +The number of lines is 33(=58-26+1) to build the widgets. +And we needed many variables (boxv, boxh, dmy1 ...). +Most of them aren't necessary except building the widgets. +Are there any good solution to reduce these work? + +Gtk provides GtkBuilder. +It reads ui data and builds a window. +It reduces the cumbersom work. + +## Ui file + +First, let's look at the ui file `tfe3.ui` that defines a structure of the widgets. + +@@@ tfe3.ui + +This is coded with XML structure. +Constructs begin with `<` and end with `>` is called tags. +And it is divided into two parts, start tag and end tag. +For example, `` is a start tag and `` is an end tag. +Ui file begins and ends with interface tags. +Some tags, for example, object tags can have a class and id attributes inside the start tag. + +- 2-5: An object with `GtkApplicationWindow` class and `win` id is defined. +This is the top level window. +And the three properties of the window are defined. +`title` property is "file editor", `default-width` property is 400 and `default-height` property is 300. +- 6: child tag means a child of the object above. +For example, line 7 tells us that GtkBox object which id is "boxv" is a child of `win`. + +Compare this ui file and the lines 26-58 in the source code of `on_open`. +Those two decribe the same structure of widgets. + +## GtkBuilder + +GtkBuilder builds widgets based on the ui file. + + GtkBuilder *build; + + build = gtk_builder_new_from_file ("tfe3.ui"); + win = GTK_WIDGET (gtk_builder_get_object (build, "win")); + gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + nb = GTK_WIDGET (gtk_builder_get_object (build, "nb")); + +The function `gtk_builder_new_from_file` reads the file given as an argument, build the widgets, generate GtkBuilder object and set pointers to the widgets in it. +The function `gtk_builder_get_object (build, "win")` returns the pointer to the widget `win`, which is the id in the ui file. +All the widgets are connected based on the parent-children relationship described in the ui file. +We only need `win` and `nb` for the program after this, so we don't need to take out any other widgets. +This reduces lines in the C source file. + +$$$ +diff tfe2.c tfe3.c +$$$ + +`65,104c61,65` means 40 (=104-65+1) lines change to 5 (=65-61+1) lines. +Therefore 35 lines are reduced. +Using ui file not only shortens C source files, but also makes the widgets' structure clear. + +Now I'll show you the C source code `tfe3.c`. +Only functions `on_open` are shown as follows. + +@@@ tfe3.c on_open + +### Using ui string + +GtkBuilder can build widgets using string. +Use the function gtk\_builder\_new\_from\_string instead of gtk\_builder\_new\_from\_file. + + char *uistring; + + uistring = + "" + "" + "file editor" + "600" + "400" + "" + "" + "GTK_ORIENTATION_VERTICAL" + ... ... ... + ... ... ... + ""; + + build = gtk_builder_new_from_stringfile (uistring); + +This method has an advantage and disadvantage. +The advantage is that the ui string is written in the source code. +So ui file is not necessary on runtime. +The disadvantage is that writing C string is a bit bothersome because of the double quotes. +If you want to use this method, you should write a script that transforms ui file into C-string. + +- add backslash before each double quote. +- add double quote at the left and right. + +### Using Gresource + +Using Gresource is similar to using string. +But Gresource is compressed binary data, not text data. +And there's a compiler that compiles ui file into Gresource. +It can compile not only text files but also binary files such as images, sounds and so on. +And after compilation, it bundles them up into one Gresource object. + +An xml file is necessary for the resource compiler `glib-compile-resources`. +It describes resource files. + +@@@ tfe3.gresource.xml + +- 2: gresources tag can include mulitple gresources (gresource tags). +However, this xml has only one gresource. +- 3: The gresource has a prefix `/com/github/ToshioCP/tfe3`. +- 4: The gresource has tfe3.ui. +And it is pointed by `/com/github/ToshioCP/tfe3/tfe3.ui` because it needs prefix. +If you want to add more files, then insert them between line 4 and 5. + +Save this xml text to `tfe3.gresource.xml`. +The gresource compiler `glib-compile-resources` shows its ussage with the argument `--help`. + +$$$ +LANG=C glib-compile-resources --help +$$$ + +Now run the compiler. + + $ glib-compile-resources tfe3.gresource.xml --target=resources.c --generate-source + +Then a C source file `resources.c` is generated. +Modify tfe3.c and save it as tfe3_r.c + + # include "resources.c" + ... ... ... + ... ... ... + build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe3/tfe3.ui"); + ... ... ... + ... ... ... + +Then, compile and run it. +The window appears and it is the same as the screenshot at the beginning of this page. + diff --git a/src/sec7.src.md b/src/sec7.src.md new file mode 100644 index 0000000..689aaac --- /dev/null +++ b/src/sec7.src.md @@ -0,0 +1,191 @@ +# Build system + +## What do we need to think about building? + +We've managed to compile a small editor so far. +But Some bad signs are beginning to appear. + +- We have only one C source file and put everything into it. +We need to sort it out. +- There are two compilers, `gcc` and `glib-compile-resources`. +We want to control them by one building tool. + +## Divide a C source file into two parts. + +When you divide C source file into several parts, each file should contain only one thing. +For example, our source has two things, the definition of TfeTextView and functions related to GtkApplication and GtkApplicationWindow. +It is a good idea to separate them into two files, `tfetextview.c` and `tfe.c`. + +- `tfetextview.c` includes the definition and functions of TfeTextView. +- `tfe.c` includes functions like `main`, `on_activate`, `on_open` and so on, which relate to GtkApplication and GtkApplicationWindow + +Now we have three source files, `tfetextview.c`, `tfe.c` and `tfe3.ui`. +The `3` of `tfe3.ui` is like a version number. +Managing version with filenames is one possible idea but it may make bothersome complicated problem. +You need to rewrite filename in each version and it affects to contents of sourcefiles that refer to filenames. +So, we should take `3` away from the filename. + +In `tfe.c` the function `tfe_text_view_new` is invoked to generate TfeTextView. +But it is defined in `tfetextview.c`, not `tfe.c`. +The lack of the declaration (not definition) of `tfe_text_view_new` makes error when `tfe.c` is compiled. +The declaration is necessary in `tfe.c`. +Those public information is usually written in header files. +It has `.h` suffix like `tfetextview.h` +And header files are included by C source files. +For example, `tfetextview.h` is included by `tfe.c`. + +`tfetextview.h` + +@@@ tfe4/tfetextview.h + +`tfetextview.c` + +@@@ tfe4/tfetextview.c + +`tfe.c` + +@@@ tfe4/tfe.c + +`tfe.ui` + +@@@ tfe4/tfe.ui + +`tfe.gresource.xml` + +@@@ tfe4/tfe.gresource.xml + +## Make + +Dividing a file makes it easy to maintain source files. +But now we are faced with a new problem. +The building step increases. + +- Compile the ui file `tfe.ui` into `resources.c`. +- Compile `tfe.c` into `tfe.o` (object file). +- Compile `tfetextview.c` into `tfetextview.o`. +- Compile `resources.c` into `resources.o`. +- Link all the object files into application `tfe`. + +Now build tool is necessary to manage it. +Make is one of the build tools. +It was originally created in 1976. +So it is an old and widely used program. + +Make analyzes Makefile and executes compilers. +All instructions are written in Makefile. + + sample.o: sample.c + gcc -o sample.o sample.c + +The sample of Malefile above consists of three elements, `sample.o`, `sample.c` and `gcc -0 sample.o sample.c`. + +- `sample.o` is called target. +- `sample.c` is prerequisite. +- `gcc -0 sample.o sample.c` is recipe. +Recipes follow tab characters, not spaces. +(It is very important. Use tab not space, or make won't work as you expected). + +The rule is: + +If a prerequisite modified later than a target, then make executes the recipe. + +In the example above, if `sample.c` is modified after the generation of `sample.o`, then make executes gcc and compile `sample.c` into `sample.o`. +If the modification time of `sample.c` is older then the generation of `sample.o`, then no compiling is necesarry, so make does nothing. + +The Makefile for `tfe` is as follows. + +@@@ tfe4/Makefile + +Only you need is to type `make`. + + $ make + gcc -c -o tfe.o `pkg-config --cflags gtk4` tfe.c + gcc -c -o tfetextview.o `pkg-config --cflags gtk4` tfetextview.c + glib-compile-resources tfe.gresource.xml --target=resources.c --generate-source + gcc -c -o resources.o `pkg-config --cflags gtk4` resources.c + gcc -o tfe tfe.o tfetextview.o resources.o `pkg-config --libs gtk4` + +I used only very basic rules to write this Makefile. +There are many more convenient methods to make it more compact. +But it needs long story to explain. +So I want to finish the explanation about make. + +## Rake + +Rake is a similar program to make. +It is written in Ruby code. +If you don't use Ruby, you don't need to read this subsection. +However, Ruby is really sophisticated and recommendable script language. + +- Rakefile controls the behavior of `rake`. +- You can write any ruby code in Rakefile. + +Rake has task and file task, which is similar to target, prerequisite and recipe in make. + +@@@ tfe4/Rakefile + +What `Rakefile` describes is almost same as `Makefile` in the previous subsection. + +- 3-6: define target file, source file and so on. +- 1, 8: Load clean library. And define CLEAN file list. +The files included by CLEAN will be removed when `rake clean` is typed on the command line. +- 10: default target depends on targetfile. +default is the final goal of tasks. +- 12-14: targetfile depends on objfiles. +The variable `t` is a task object. + - t.name is a target name + - t.prerequisites is an array of prerequisits. + - t.source is the first element of prerequisites. +- sh is a method to give the following string to shell as an argument and execute. +- 16-21: Loop by each element of the array of objfiles. Each object depends on corresponding source file. +- 23-25: resouce file depends on xml file and ui file. + +Rakefile might seem to be difficult for beginners. +But, you can use any ruby syntax in Rakefile, so it is really flexible. +If you practice Ruby and Rakefile, it will be highly productive tools. + +## Meson and ninja + +Meson is one of the most popular building tool despite the developing version. +And ninja is similar to make but much faster than make. +Several years ago, most of the C developers used autotools and make. +But now the situation has changed. +Many developers are using meson and ninja now. + +To use meson, you first need to write `meson.build` file. + +@@@ tfe4/meson.build + +- 1: The function `project` defines things about the project. +The first parameter is the name of the project and the second is the programing language. +- 2: `dependency` function defines a dependency that is taken by `pkg-config`. +We put `gtk4` as an argument. +- 5: `import` function inports a module. +In line 5, gnome module is imported and assignd to the variable `gnome`. +gnome module provides helper tools to build GTK programs. +- 6: `.compile_resources` is a method of gnome module and compile files to resources under the instruction of xml file. +In line 6, the resource filename is `resources`, which means `resources.c` and `resources.h`, and xml file is `tfe.gresource.xml`. +This method generates C source file by default. +- 8: define source files. +- 10: executable function generates a target file by building source files. +The first parameter is the filename of the target. The following parameters are source files. +The last parameter has a option `dependencies`. +In line 10 it is `gtkdep` which is defined in line 3. + +Now run meson and ninja. + + $ meson _build + $ ninja -C _build + +Then, the executable file `tfe` has been generated under the directory `_build`. + + $ _build/tfe tfe.c tfetextview.c + +Then the window appears. + +I show you three build tools. +I think meson and ninja is the best choice for the present. + +We divided a file into some categorized files and used a build tool. +This method is used by many developers. + diff --git a/src/sec8.src.md b/src/sec8.src.md new file mode 100644 index 0000000..378f31e --- /dev/null +++ b/src/sec8.src.md @@ -0,0 +1,258 @@ +# Instance and class + +This section and the following four sections are descriptions about next version of the text file editor (tfe). +It is tfe5. +It has many changes from the prior version. +All the sources are listed after the five sections. + +## Encapsulation + +We've divided C source file into two parts. +But it is not enough in terms of encapsulation. + +- `tfe.c` includes everything other than TfeTextView. +It should be divided at least into two parts, `tfeapplication.c` and `tfenotebook.c`. +- Header files also need to be organized. + +However, first of all, I'd like to focus on the object TfeTextView. +It is a child object of GtkTextView. +And important thing is it has newly added Gfile in it. + +- What is necessary to GFile when generating (or initializing) TfeTextView? +- What is necessary to GFile when destructing TfeTextView? +- TfeTextView should read/write a file by itself or not? +- How it communicate with objects outside? + +You need to know at least class/instance and signals before thinking about them. +I will explain them in this section and the next section. +After that I will explain: + +- Organizing functions. +- How to use FileChooserDialog + +## GObject and its children + +GObject and its children are objects, which have both class and instance. +First, think about instance of objects. +Instance is structured memories and the structure is described using C language structure. +The following is a structure of TfeTextView. + + /* This typedef statement is automaticaly generated by the macro G_DECLARE_FINAL_TYPE */ + typedef struct _TfeTextView TfeTextView; + + struct _TfeTextView { + GtkTextView parent; + GtkTextBuffer *tb; + GFile *file; + gboolean changed; + }; + +Each instance has similar structure as above. + +- `parent` is the structure of GtkTextView which is the parent object of TfeTextView. +- `tb` is a pointer to GtkTextBuffer connected to GtkTextView. +- `file` is a pointer to GFile which is a file corresponds to `tb` (or NULL is available). +- `changed` is TRUE if the buffer has been modified, FALSE if not. + +Comparing to the source file in the previous section, `tb` and `changed` are added. +Notice the program above is the declaration of the structure, not the definition. +So, no memories are allocated at this moment. +They are to be allocated when `tfe_text_view_new` function is invoked. + +You can find the declaration of the ancestors of TfeTextView in the sourcefiles of GTK and GLib. +The following is extracts from the source files (not exactly the same). + + typedef struct _GObject GObject; + typedef struct _GObject GInitiallyUnowned; + struct _GObject + { + GTypeInstance g_type_instance; + volatile guint ref_count; + GData *qdata; + }; + + typedef struct _GtkWidget GtkWidget; + struct _GtkWidget + { + GInitiallyUnowned parent_instance; + GtkWidgetPrivate *priv; + }; + + typedef struct _GtkTextView GtkTextView; + struct _GtkTextView + { + GtkWidget parent_instance; + GtkTextViewPrivate *priv; + }; + +In each structure, its parent instance is declared at the top of the members. +So, every ancestors is included in the child instance. +This is very important. +It guarantees a child widget to derive all the features from ancestors. +The structure of `TfeTextView` is like the following diagram. + +![The structure of the instance TfeTextView](TfeTextView.png) + + +## Generate TfeTextView instance + +The function `tfe_text_view_new` generates a new TfeTextView instance. + +@@@ tfe5/tfetextview.c tfe_text_view_new + +When this function is run, the following procedure is gone through. + +1. Initialize GObject instance in TfeTextView instance. +2. Initialize GtkWidget instance in TfeTextView instance. +3. Initialize GtkTextView instance in TfeTextView instance. +4. Initialize TfeTextView instance. + +Step one through three is done automatically. +Step four is done by the function `tfe_text_view_init`. + +> (In the same way, `gtk_text_view_init`, `gtk_widget_init` and `g_object_init` is the initialization functions of GtkTextView, GtkWidget and GObject respectively. +> You can find them in the GTK or GLib source file.) + +@@@ tfe5/tfetextview.c on_changed tfe_text_view_init + +`tfe_text_view_init` initializes the instance. + +- 8-10: Initialize `tb`, `file` and `changed`. +- 11: Set the wrap mode of GtkTextView as GTK\_WRAP\_WORD\_CHAR. +- 12: Connect "changed" signal to a handler `on_changed`. +"changed" signal is defined in GtkTextBuffer. +It is emitted when the contents in the buffer is changed. +- 2-4: `on_changed` handler records TRUE to `tv->changed` when "changed" signal is emitted. + +## Functions and Classes + +In Gtk, all objects derived from GObject have class and instance. +Instance is memories which has a structure defined by C structure declaration as I mentioned in the previous two subsections. +And instance can be generated two or more. +Those instances have the same structure. +However, structured memories are insufficient to define its behavior. +We need at least two things. +One is functions and the other is class. + +You've already seen many functions, for example, `tfe_text_view_new` is a function to generate TfeTextView instance. +These functions are similar to object methods in object oriented languages such as Java and Ruby. +Functions are public, which means that they are expected to be used by other objects. + +Class comprises mainly pointers to functions. +And the functions are used by the object itself or its children objects. +For example, GObject class is declared in `gobject.h` in GLib source files. + +@@@ class_gobject.c + +I'd like to explain some of the members. +There's a pointer to the function `dispose` in line 22. + + void (*dispose) (GObject *object); + +The declaration is a bit complicated. +The asterisk before the identifier `dispose` means pointer. +So, the pointer `disopse` points a function which has one parameter , which points a GObject structure, and returns no value because of void type. +In the same way, line 23 says `finalize` is a pointer to the function which has one paremeter, which points a GObject structure, and returns no value. + + void (*finalize) (GObject *object); + +Look at the declaration of `_GObjectClass` so that you would find that most of the members are pointers to functions. + +- 10: A function pointed by `constructor` is called when the instance is generated. It completes the initialization of the instance. +- 22: A function pointed by `dispose` is called when the instance destructs itself. Destruction process is divided into two phases. First is called disposing and the instance releases all the references to other instances. The second is finalizing. +- 23: A funtion pointed by `finalize` finishes the destruction process. +- The other pointers point functions which are called during the instance lives. + +## TfeTextView class + +TfeTextView class is a structure and it includes all its ancestors' class in it. +Let's look at all the classes from GObject, which is the top level object, to TfeTextView object, which is the lowest. + + GObject -- GInitiallyUnowned -- GtkWidget -- GtkTextView -- TfeTextView + +The following is extracts from the source files (not exactly the same). + +@@@ classes.c + +- 105-107: This three lines are generated by the macro G\_DECLARE\_FINAL\_TYPE. +So, they are not written in either `tfe_text_view.h` or `tfe_text_view.c`. +- 2, 73, 106: Each derived class puts its parent class at the first member of its structure. +It is the same as instance structures. +- Class members in ancesters are open to their child class. +So, they can be changed in `tfe_text_view_class_init` function. +For example, the `dispose` pointer in GObjectClass will be overridden later in `tfe_text_view_class_init`. +(Override is an object oriented programing terminology. +Override is rewriting ancestors' class methods in the child class.) +- Some class methods are often overridden. +`set_property`, `get_property`, `dispose`, `finalize` and `constructed` are such methods. + +TfeTextViewClass includes its ancsestors' class in it. +It is illustrated in the following diagram. + +![The structure of TfeTextView Class](TfeTextViewClass.png) + +## Destruction of TfeTextView + +Every Object derived from GObject has a reference count. +If an object A uses an object B, then A keeps a pointr to B in A and at the same time increaces the reference count of B by one with the function `g_object_ref (B)`. +If A doesn't need B any longer, then A discards the pointer to B (usually it is done by assigning NULL to the pointer) and decreaces the reference count of B by one with the function `g_object_unref (B)`. + +If two objects A and B refer to C, then the reference count of C is two. +After A used C and if A no longer needs C, A discards the pointer to C and decreases the reference count in C by one. +Now the reference count of C is one. +In the same way, when B no longer needs C, B discards the pointer to C and decreases the reference count in C by one. +At this moment, no object refers C and the reference count of C is zero. +This means C is no longer useful. +Then C destructs itself and finally the memories allocated to C is freed. + +![Reference count of B](refcount.png) + +The idea above is based on an assumption that an object refered by nothing has reference count of zero. +When the reference count drops to zero, the object starts its destruction process. +The destruction process is split in two phases: disposing and finalizing. +In the disposing process, the object invokes the handler pointed by `dispose` in its class to release all references to other objects. +In the finalizing process, it invokes the handler pointed by `finalize` in its class to complete the destruction process. + +In the destruction process of TfeTextView, the reference count of widgets related to TfeTextView is automatically decreased. +But GFile pointed by `tv->file` needs to decrease its reference count by one. +You must write the code in the dispose handler `tfe_text_view_dispose`. + +@@@ tfe5/tfetextview.c tfe_text_view_dispose + +- 5,6: If `tv->file` points a GFile, decrease its reference count. +`g_clear_object` decreases the reference count and assigns NULL to `tv->file`. In dispose handlers, we usually use `g_clear_object` rather than `g_object_unref`. +- 8: invoke parent's despose handler. (This will be explained later.) + +In the desposing process, the object uses the pointer in its class to call the handler. +Therefore, `tfe_text_view_dispose` needs to be registerd in the class when the TfeTextView class is initialized. +The function `tfe_text_view_class_init` is the class initialization function and it is declared in the replacement produced by `G_DEFINE_TYPE` macro. + + static void + tfe_text_view_class_init (TfeTextViewClass *class) { + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = tfe_text_view_dispose; + + } + +Each ancestors' class is generated before TfeTextViewClass. +Therefore, there are four classes and each class has a pointer to each dispose handler. +Look at the following diagram. +There are four classes -- GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass. +Each class has its own dispose handler -- `dh1`, `dh2`, `dh3` and `tfe_text_view_dispose`. + +![dispose handers](dispose_handler.png) + +Now, look at the `tfe_text_view_dispose` program above. +It first releases the reference to GFile object pointed by `tv->file`. +Then it invokes its parent's dispose handler in line 8. + + G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject); + +`tfe_text_view_parent_class`,which is made by `G_DEFINE_TYPE` macro, is a pointer that points the parent object class. +Therefore, `G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose` points the handler `dh3` in the diagram above. +And `gobject` is a pointer to TfeTextView object which is casted as a GObject instanse. +`dh3` releases all the references to objects in the GtkTextView part (it is actually the private area pointed by `prev`) in TfeTextView instance. +After that, `dh3` calls `dh2`, and `dh2` calls `dh1`. +Finally all the references are released. + diff --git a/src/sec9.src.md b/src/sec9.src.md new file mode 100644 index 0000000..87b4ce6 --- /dev/null +++ b/src/sec9.src.md @@ -0,0 +1,135 @@ +# Signals + +## Signals + +In GTK programming, each object is capsulated. +And it is not recommended to use global variables because they tend to make the program complicated. +So, we need something to communicate between objects. +There are two ways to do so. + +- Functions. +For example, `tb = gtk_text_view_get_buffer (tv)`. +The function caller requests `tv`, which is a GtkTextView object, to give back `tb`, which is a GtkTextBuffer object connected to `tv`. +- Signals. +For example, `activate` signal on GApplication object. +When the application is activated, the signal is emitted. +Then the handler, which has been connected to the signal, is invoked. + +The caller of the function or the handler connected to the signal is usually outside of the object. +One of the difference between these two is that the object is active or passive. +In functions the object responds to the caller. +In signals the object actively sends a signal to the handler. + +GObject signal can be registered, connected and emitted. + +1. A signal is registered with the object type on which it can be emitted. +This is done usually when the class is initialized. +2. It is connected to a handler by `g_connect_signal` or its family functions. +3. When it is emmitted, the connected handler is invoked. + +Step one and three are done in the object on which the signal is emitted. +Step two is done outside the objects. + +## Signal registration + +In TfeTextView, two signals are registered. + +- "change-file" signal. +This signal is emitted when `tv->file` is changed. +- "open-response" signal. +`tfe_text_view_open` function is not able to return the status because of using GtkFileChooserDialog. +This signal is emitted instead of the return value of the function. + +Static variable is used to store the signal ID. +If you need to register two or more signals, static array is usually used. + + enum { + CHANGE_FILE, + OPEN_RESPONSE, + NUMBER_OF_SIGNALS + }; + + static guint tfe_text_view_signals[NUMBER_OF_SIGNALS]; + +Signal registration codes are written in the class initialization function. + +@@@ tfe5/tfetextview.c tfe_text_view_class_init + +- 6-15: Register "change-file"signal. +`g_signal_newv` function is used. +This signal has no default handler (object method handler). +I think you usually don't need to set a default handler in final type object. +If you need it, put the closure of the handler in line 9. +- The return value of `g_signal_newv` is the signal id. +The type of signal id is guint, which is the same as unsigned int. +It is used when the signal is emitted. +- 16-26: Register "open-response" signal. +This signal has a parameter. +- 25: Number of the parameter. +"open-response" signal has one parameter. +- 26: An array of types of parameters. +The array `param_types` is defined in line 16. +It has one element, which is `G_TYPE_INT`. +`G_TYPE_INT` is a type of integer. +Such fundamental types are described in [GObject API reference](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html). + +The handlers are as follows. + + void change_file_handler (TfeTextView *tv, gpointer user_data); + void open_response_handler (TfeTextView *tv, guint parameter, gpointer user_data); + +- Because "change-file" signal doesn't have parameter, the handler's parameter is TfeTextView object and user data. +- Because "open-response" signal has one parameter, the handler's parameter is TfeTextView object, the parameter and user data. +- `tv` is the object instance on which the signal is emitted. +- `user_data` comes from the fourth argument of `g_signal_connect`. +- `parameter` comes from the fourth argument of `g_signal_emit`. + +The parameter is defined in `tfetextview.h` because it is public. + + /* "open-response" signal response */ + enum + { + TFE_OPEN_RESPONSE_SUCCESS, + TFE_OPEN_RESPONSE_CANCEL, + TFE_OPEN_RESPONSE_ERROR + }; + +- `TFE_OPEN_RESPONSE_SUCCESS` is set when `tfe_text_view_open` successfully has opend a file and loaded it. +- `TFE_OPEN_RESPONSE_CANCEL` is set when the user canceled to open a file. +- `TFE_OPEN_RESPONSE_ERROR` is set when error occured. + +## Signal connection + +A signal and a handler are connected by the function `g_signal_connect`. +There some similar functions like `g_signal_connect_after`, `g_signal_connect_swapped` and so on. +But I think `g_signal_connect` is the most common function. +The signals "change-file" is connected to a callback function `file_changed` outside of TfeTextView object. +In the same way, the signals "open-response" is connected to a callback function `open_response` outside of TfeTextView object. +The functions `file_changed` and `open_response` will be explained later. + + g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb); + + g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb); + +## Signal emission + +Signals are emitted on the object. +The type of the object is the second argument of `g_signal_newv`. +The relationship between the signal and object (type) is made up when the signal is generated. + +`g_signal_emit` is used to emit the signal. +The following is extract from `tfetexties.c`. + + g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS); + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL); + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + +- The first argument is the object on which the signal is emitted. +- The second argument is the signal id. +- The third argument is the detail of the signal. +"change-file" signal and "open-response" signal doesn't have details and the argument is zero when no details. +- "change-file" signal doesn't have parameter, so no fourth parameter. +- "open-response" signal has one parameter. +The fourth parameter is the parameter. + diff --git a/src/tfe1.c b/src/tfe1.c new file mode 100644 index 0000000..cde4dda --- /dev/null +++ b/src/tfe1.c @@ -0,0 +1,136 @@ +#include + +/* Define TfeTextView Widget which is the child object of GtkTextView */ + +#define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () +G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + +struct _TfeTextView +{ + GtkTextView parent; + GFile *file; +}; + +G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + +static void +tfe_text_view_init (TfeTextView *tv) { +} + +static void +tfe_text_view_class_init (TfeTextViewClass *class) { +} + +void +tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + tv -> file = f; +} + +GFile * +tfe_text_view_get_file (TfeTextView *tv) { + return tv -> file; +} + +GtkWidget * +tfe_text_view_new (void) { + return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); +} + +/* ---------- end of the definition of TfeTextView ---------- */ + +static gboolean +before_close (GtkWindow *win, GtkWidget *nb) { + GtkWidget *scr; + GtkWidget *tv; + GFile *file; + GtkTextBuffer *tb; + GtkTextIter start_iter; + GtkTextIter end_iter; + gchar *contents; /* gchar is the same as char ... typedef char gchar;*/ + guint n; + guint i; + + n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)); + for (i = 0; i < n; ++i) { + scr = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), i); + tv = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scr)); + file = tfe_text_view_get_file (TFE_TEXT_VIEW (tv)); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_buffer_get_bounds (tb, &start_iter, &end_iter); + contents = gtk_text_buffer_get_text (tb, &start_iter, &end_iter, FALSE); + if (! g_file_replace_contents (file, contents, strlen (contents), NULL, TRUE, G_FILE_CREATE_NONE, NULL, NULL, NULL)) + g_print ("ERROR : Can't save %s.", g_file_get_path (file)); + } + return FALSE; +} + +static void +on_activate (GApplication *app, gpointer user_data) { + g_print ("You need a filename argument.\n"); +} + +static void +on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + GtkWidget *win; + GtkWidget *nb; + GtkWidget *lab; + GtkNotebookPage *nbp; + GtkWidget *scr; + GtkWidget *tv; + GtkTextBuffer *tb; + char *contents; + gsize length; + char *filename; + int i; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "file editor"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + gtk_window_maximize (GTK_WINDOW (win)); + + nb = gtk_notebook_new (); + gtk_window_set_child (GTK_WINDOW (win), nb); + + for (i = 0; i < n_files; i++) { + if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + scr = gtk_scrolled_window_new (); + tv = tfe_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + + tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + gtk_text_buffer_set_text (tb, contents, length); + g_free (contents); + filename = g_file_get_basename (files[i]); + lab = gtk_label_new (filename); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + g_object_set (nbp, "tab-expand", TRUE, NULL); + g_free (filename); + } else { + filename = g_file_get_path (files[i]); + g_print ("No such file: %s.\n", filename); + g_free (filename); + } + } + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + g_signal_connect (win, "close-request", G_CALLBACK (before_close), nb); + gtk_widget_show (win); + } else + gtk_window_destroy (GTK_WINDOW (win)); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfe1", G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfe2.c b/src/tfe2.c new file mode 100644 index 0000000..c3053e2 --- /dev/null +++ b/src/tfe2.c @@ -0,0 +1,146 @@ +#include + +/* Define TfeTextView Widget which is the child object of GtkTextView */ + +#define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () +G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + +struct _TfeTextView +{ + GtkTextView parent; + GFile *file; +}; + +G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + +static void +tfe_text_view_init (TfeTextView *tv) { +} + +static void +tfe_text_view_class_init (TfeTextViewClass *class) { +} + +void +tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + tv -> file = f; +} + +GFile * +tfe_text_view_get_file (TfeTextView *tv) { + return tv -> file; +} + +GtkWidget * +tfe_text_view_new (void) { + return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); +} + +/* ---------- end of the definition of TfeTextView ---------- */ + +static void +on_activate (GApplication *app, gpointer user_data) { + g_print ("You need a filename argument.\n"); +} + +static void +on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + GtkWidget *win; + GtkWidget *nb; + GtkWidget *lab; + GtkNotebookPage *nbp; + GtkWidget *scr; + GtkWidget *tv; + GtkTextBuffer *tb; + char *contents; + gsize length; + char *filename; + int i; + + GtkWidget *boxv; + GtkWidget *boxh; + GtkWidget *dmy1; + GtkWidget *dmy2; + GtkWidget *dmy3; + GtkWidget *btnn; /* button for new */ + GtkWidget *btno; /* button for open */ + GtkWidget *btns; /* button for save */ + GtkWidget *btnc; /* button for close */ + + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "file editor"); + gtk_window_set_default_size (GTK_WINDOW (win), 600, 400); + + boxv = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_window_set_child (GTK_WINDOW (win), boxv); + + boxh = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_append (GTK_BOX (boxv), boxh); + + dmy1 = gtk_label_new(NULL); /* dummy label for left space */ + gtk_label_set_width_chars (GTK_LABEL (dmy1), 10); + dmy2 = gtk_label_new(NULL); /* dummy label for center space */ + gtk_widget_set_hexpand (dmy2, TRUE); + dmy3 = gtk_label_new(NULL); /* dummy label for right space */ + gtk_label_set_width_chars (GTK_LABEL (dmy3), 10); + btnn = gtk_button_new_with_label ("New"); + btno = gtk_button_new_with_label ("Open"); + btns = gtk_button_new_with_label ("Save"); + btnc = gtk_button_new_with_label ("Close"); + + gtk_box_append (GTK_BOX (boxh), dmy1); + gtk_box_append (GTK_BOX (boxh), btnn); + gtk_box_append (GTK_BOX (boxh), btno); + gtk_box_append (GTK_BOX (boxh), dmy2); + gtk_box_append (GTK_BOX (boxh), btns); + gtk_box_append (GTK_BOX (boxh), btnc); + gtk_box_append (GTK_BOX (boxh), dmy3); + + nb = gtk_notebook_new (); + gtk_widget_set_hexpand (nb, TRUE); + gtk_widget_set_vexpand (nb, TRUE); + gtk_box_append (GTK_BOX (boxv), nb); + + for (i = 0; i < n_files; i++) { + if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + scr = gtk_scrolled_window_new (); + tv = tfe_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + + tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + gtk_text_buffer_set_text (tb, contents, length); + g_free (contents); + filename = g_file_get_basename (files[i]); + lab = gtk_label_new (filename); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + g_object_set (nbp, "tab-expand", TRUE, NULL); + g_free (filename); + } else { + filename = g_file_get_path (files[i]); + g_print ("No such file: %s.\n", filename); + g_free (filename); + } + } + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + gtk_widget_show (win); + } else + gtk_window_destroy (GTK_WINDOW (win)); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfe2", G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfe3.c b/src/tfe3.c new file mode 100644 index 0000000..4b5b768 --- /dev/null +++ b/src/tfe3.c @@ -0,0 +1,107 @@ +#include + +/* Define TfeTextView Widget which is the child object of GtkTextView */ + +#define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () +G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + +struct _TfeTextView +{ + GtkTextView parent; + GFile *file; +}; + +G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + +static void +tfe_text_view_init (TfeTextView *tv) { +} + +static void +tfe_text_view_class_init (TfeTextViewClass *class) { +} + +void +tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + tv -> file = f; +} + +GFile * +tfe_text_view_get_file (TfeTextView *tv) { + return tv -> file; +} + +GtkWidget * +tfe_text_view_new (void) { + return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); +} + +/* ---------- end of the definition of TfeTextView ---------- */ + +static void +on_activate (GApplication *app, gpointer user_data) { + g_print ("You need a filename argument.\n"); +} + +static void +on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + GtkWidget *win; + GtkWidget *nb; + GtkWidget *lab; + GtkNotebookPage *nbp; + GtkWidget *scr; + GtkWidget *tv; + GtkTextBuffer *tb; + char *contents; + gsize length; + char *filename; + int i; + GtkBuilder *build; + + build = gtk_builder_new_from_file ("tfe3.ui"); + win = GTK_WIDGET (gtk_builder_get_object (build, "win")); + gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + nb = GTK_WIDGET (gtk_builder_get_object (build, "nb")); + g_object_unref(build); + for (i = 0; i < n_files; i++) { + if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + scr = gtk_scrolled_window_new (); + tv = tfe_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + + tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + gtk_text_buffer_set_text (tb, contents, length); + g_free (contents); + filename = g_file_get_basename (files[i]); + lab = gtk_label_new (filename); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + g_object_set (nbp, "tab-expand", TRUE, NULL); + g_free (filename); + } else { + filename = g_file_get_path (files[i]); + g_print ("No such file: %s.\n", filename); + g_free (filename); + } + } + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + gtk_widget_show (win); + } else + gtk_window_destroy (GTK_WINDOW (win)); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfe3", G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfe3.gresource.xml b/src/tfe3.gresource.xml new file mode 100644 index 0000000..0f61489 --- /dev/null +++ b/src/tfe3.gresource.xml @@ -0,0 +1,6 @@ + + + + tfe3.ui + + diff --git a/src/tfe3.ui b/src/tfe3.ui new file mode 100644 index 0000000..39b54b9 --- /dev/null +++ b/src/tfe3.ui @@ -0,0 +1,59 @@ + + + file editor + 600 + 400 + + + GTK_ORIENTATION_VERTICAL + + + GTK_ORIENTATION_HORIZONTAL + + + 10 + + + + + New + + + + + Open + + + + + TRUE + + + + + Save + + + + + Close + + + + + 10 + + + + + + + TRUE + TRUE + + + + + + + diff --git a/src/tfe4/Makefile b/src/tfe4/Makefile new file mode 100644 index 0000000..79c8c75 --- /dev/null +++ b/src/tfe4/Makefile @@ -0,0 +1,19 @@ +all: tfe + +tfe: tfe.o tfetextview.o resources.o + gcc -o tfe tfe.o tfetextview.o resources.o `pkg-config --libs gtk4` + +tfe.o: tfe.c tfetextview.h + gcc -c -o tfe.o `pkg-config --cflags gtk4` tfe.c +tfetextview.o: tfetextview.c tfetextview.h + gcc -c -o tfetextview.o `pkg-config --cflags gtk4` tfetextview.c +resources.o: resources.c + gcc -c -o resources.o `pkg-config --cflags gtk4` resources.c + +resources.c: tfe.gresource.xml tfe.ui + glib-compile-resources tfe.gresource.xml --target=resources.c --generate-source + +.Phony: clean + +clean: + rm -f tfe tfe.o tfetextview.o resources.o resources.c diff --git a/src/tfe4/Rakefile b/src/tfe4/Rakefile new file mode 100644 index 0000000..959fb93 --- /dev/null +++ b/src/tfe4/Rakefile @@ -0,0 +1,25 @@ +require 'rake/clean' + +targetfile = "tfe" +srcfiles = FileList["tfe.c", "tfetextview.c", "resources.c"] +rscfile = srcfiles[2] +objfiles = srcfiles.gsub(/.c$/, '.o') + +CLEAN.include(targetfile, objfiles, rscfile) + +task default: targetfile + +file targetfile => objfiles do |t| + sh "gcc -o #{t.name} #{t.prerequisites.join(' ')} `pkg-config --libs gtk4`" +end + +objfiles.each do |obj| + src = obj.gsub(/.o$/,'.c') + file obj => src do |t| + sh "gcc -c -o #{t.name} `pkg-config --cflags gtk4` #{t.source} " + end +end + +file rscfile => ["tfe.gresource.xml", "tfe.ui"] do |t| + sh "glib-compile-resources #{t.prerequisites[0]} --target=#{t.name} --generate-source" +end diff --git a/src/tfe4/meson.build b/src/tfe4/meson.build new file mode 100644 index 0000000..ae0c530 --- /dev/null +++ b/src/tfe4/meson.build @@ -0,0 +1,10 @@ +project('tfe', 'c') + +gtkdep = dependency('gtk4') + +gnome=import('gnome') +resources = gnome.compile_resources('resources','tfe.gresource.xml') + +sourcefiles=files('tfe.c', 'tfetextview.c') + +executable('tfe', sourcefiles, resources, dependencies: gtkdep) diff --git a/src/tfe4/tfe.c b/src/tfe4/tfe.c new file mode 100644 index 0000000..6132959 --- /dev/null +++ b/src/tfe4/tfe.c @@ -0,0 +1,70 @@ +#include +#include "tfetextview.h" + +static void +on_activate (GApplication *app, gpointer user_data) { + g_print ("You need a filename argument.\n"); +} + +static void +on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + GtkWidget *win; + GtkWidget *nb; + GtkWidget *lab; + GtkNotebookPage *nbp; + GtkWidget *scr; + GtkWidget *tv; + GtkTextBuffer *tb; + char *contents; + gsize length; + char *filename; + int i; + GtkBuilder *build; + + build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe3/tfe.ui"); + win = GTK_WIDGET (gtk_builder_get_object (build, "win")); + gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app)); + nb = GTK_WIDGET (gtk_builder_get_object (build, "nb")); + g_object_unref (build); + for (i = 0; i < n_files; i++) { + if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + scr = gtk_scrolled_window_new (NULL, NULL); + tv = tfe_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + + tfe_text_view_set_file (TFE_TEXT_VIEW (tv), g_file_dup (files[i])); + gtk_text_buffer_set_text (tb, contents, length); + g_free (contents); + filename = g_file_get_basename (files[i]); + lab = gtk_label_new (filename); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + g_object_set (nbp, "tab-expand", TRUE, NULL); + g_free (filename); + } else { + filename = g_file_get_path (files[i]); + g_print ("No such file: %s.\n", filename); + g_free (filename); + } + } + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { + gtk_widget_show (win); + } else + gtk_window_destroy (GTK_WINDOW (win)); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfe3", G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfe4/tfe.gresource.xml b/src/tfe4/tfe.gresource.xml new file mode 100644 index 0000000..70f351d --- /dev/null +++ b/src/tfe4/tfe.gresource.xml @@ -0,0 +1,6 @@ + + + + tfe.ui + + diff --git a/src/tfe4/tfe.ui b/src/tfe4/tfe.ui new file mode 100644 index 0000000..39b54b9 --- /dev/null +++ b/src/tfe4/tfe.ui @@ -0,0 +1,59 @@ + + + file editor + 600 + 400 + + + GTK_ORIENTATION_VERTICAL + + + GTK_ORIENTATION_HORIZONTAL + + + 10 + + + + + New + + + + + Open + + + + + TRUE + + + + + Save + + + + + Close + + + + + 10 + + + + + + + TRUE + TRUE + + + + + + + diff --git a/src/tfe4/tfetextview.c b/src/tfe4/tfetextview.c new file mode 100644 index 0000000..ef7dc0a --- /dev/null +++ b/src/tfe4/tfetextview.c @@ -0,0 +1,34 @@ +#include +#include "tfetextview.h" + +struct _TfeTextView +{ + GtkTextView parent; + GFile *file; +}; + +G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + +static void +tfe_text_view_init (TfeTextView *tv) { +} + +static void +tfe_text_view_class_init (TfeTextViewClass *class) { +} + +void +tfe_text_view_set_file (TfeTextView *tv, GFile *f) { + tv -> file = f; +} + +GFile * +tfe_text_view_get_file (TfeTextView *tv) { + return tv -> file; +} + +GtkWidget * +tfe_text_view_new (void) { + return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); +} + diff --git a/src/tfe4/tfetextview.h b/src/tfe4/tfetextview.h new file mode 100644 index 0000000..103bd52 --- /dev/null +++ b/src/tfe4/tfetextview.h @@ -0,0 +1,14 @@ +#include + +#define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () +G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + +void +tfe_text_view_set_file (TfeTextView *tv, GFile *f); + +GFile * +tfe_text_view_get_file (TfeTextView *tv); + +GtkWidget * +tfe_text_view_new (void); + diff --git a/src/tfe5/meson.build b/src/tfe5/meson.build new file mode 100644 index 0000000..376254b --- /dev/null +++ b/src/tfe5/meson.build @@ -0,0 +1,10 @@ +project('tfe', 'c') + +gtkdep = dependency('gtk4') + +gnome=import('gnome') +resources = gnome.compile_resources('resources','tfe.gresource.xml') + +sourcefiles=files('tfeapplication.c', 'tfenotebook.c', 'tfetextview.c') + +executable('tfe', sourcefiles, resources, dependencies: gtkdep) diff --git a/src/tfe5/tfe.gresource.xml b/src/tfe5/tfe.gresource.xml new file mode 100644 index 0000000..988a36e --- /dev/null +++ b/src/tfe5/tfe.gresource.xml @@ -0,0 +1,6 @@ + + + + tfe.ui + + diff --git a/src/tfe5/tfe.h b/src/tfe5/tfe.h new file mode 100644 index 0000000..8223521 --- /dev/null +++ b/src/tfe5/tfe.h @@ -0,0 +1,4 @@ +#include + +#include "tfetextview.h" +#include "tfenotebook.h" diff --git a/src/tfe5/tfe.ui b/src/tfe5/tfe.ui new file mode 100644 index 0000000..15e63ff --- /dev/null +++ b/src/tfe5/tfe.ui @@ -0,0 +1,64 @@ + + + file editor + 600 + 400 + + + GTK_ORIENTATION_VERTICAL + + + GTK_ORIENTATION_HORIZONTAL + + + 10 + + + + + _New + TRUE + + + + + _Open + TRUE + + + + + TRUE + + + + + _Save + TRUE + + + + + _Close + TRUE + + + + + 10 + + + + + + + TRUE + TRUE + TRUE + + + + + + + diff --git a/src/tfe5/tfeapplication.c b/src/tfe5/tfeapplication.c new file mode 100644 index 0000000..3eb10a6 --- /dev/null +++ b/src/tfe5/tfeapplication.c @@ -0,0 +1,117 @@ +#include "tfe.h" + +static void +open_clicked (GtkWidget *btno, GtkNotebook *nb) { + notebook_page_open (nb); +} + +static void +new_clicked (GtkWidget *btnn, GtkNotebook *nb) { + notebook_page_new (nb); +} + +static void +save_clicked (GtkWidget *btns, GtkNotebook *nb) { + notebook_page_save (nb); +} + +static void +close_clicked (GtkWidget *btnc, GtkNotebook *nb) { + GtkWidget *win; + GtkWidget *boxv; + gint i; + + if (gtk_notebook_get_n_pages (nb) == 1) { + boxv = gtk_widget_get_parent (GTK_WIDGET (nb)); + win = gtk_widget_get_parent (boxv); + gtk_window_destroy (GTK_WINDOW (win)); + } else { + i = gtk_notebook_get_current_page (nb); + gtk_notebook_remove_page (GTK_NOTEBOOK (nb), i); + } +} + +static void +tfe_activate (GApplication *application) { + GtkApplication *app = GTK_APPLICATION (application); + GtkWidget *win; + GtkWidget *boxv; + GtkNotebook *nb; + + win = GTK_WIDGET (gtk_application_get_active_window (app)); + boxv = gtk_window_get_child (GTK_WINDOW (win)); + nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv)); + + notebook_page_new (nb); + gtk_widget_show (GTK_WIDGET (win)); +} + +static void +tfe_open (GApplication *application, GFile ** files, gint n_files, const gchar *hint) { + GtkApplication *app = GTK_APPLICATION (application); + GtkWidget *win; + GtkWidget *boxv; + GtkNotebook *nb; + int i; + + win = GTK_WIDGET (gtk_application_get_active_window (app)); + boxv = gtk_window_get_child (GTK_WINDOW (win)); + nb = GTK_NOTEBOOK (gtk_widget_get_last_child (boxv)); + + for (i = 0; i < n_files; i++) + notebook_page_new_with_file (nb, files[i]); + if (gtk_notebook_get_n_pages (nb) == 0) + notebook_page_new (nb); + gtk_widget_show (win); +} + + +static void +tfe_startup (GApplication *application) { + GtkApplication *app = GTK_APPLICATION (application); + GtkApplicationWindow *win; + GtkNotebook *nb; + GtkBuilder *build; + GtkButton *btno; + GtkButton *btnn; + GtkButton *btns; + GtkButton *btnc; + + build = gtk_builder_new_from_resource ("/com/github/ToshioCP/tfe/tfe.ui"); + win = GTK_APPLICATION_WINDOW (gtk_builder_get_object (build, "win")); + nb = GTK_NOTEBOOK (gtk_builder_get_object (build, "nb")); + gtk_window_set_application (GTK_WINDOW (win), app); + btno = GTK_BUTTON (gtk_builder_get_object (build, "btno")); + btnn = GTK_BUTTON (gtk_builder_get_object (build, "btnn")); + btns = GTK_BUTTON (gtk_builder_get_object (build, "btns")); + btnc = GTK_BUTTON (gtk_builder_get_object (build, "btnc")); + g_signal_connect (btno, "clicked", G_CALLBACK (open_clicked), nb); + g_signal_connect (btnn, "clicked", G_CALLBACK (new_clicked), nb); + g_signal_connect (btns, "clicked", G_CALLBACK (save_clicked), nb); + g_signal_connect (btnc, "clicked", G_CALLBACK (close_clicked), nb); + g_object_unref(build); + +GdkDisplay *display; + + display = gtk_widget_get_display (GTK_WIDGET (win)); + GtkCssProvider *provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, "textview {padding: 10px; font-family: monospace; font-size: 12pt;}", -1); + gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfe", G_APPLICATION_HANDLES_OPEN); + + g_signal_connect (app, "startup", G_CALLBACK (tfe_startup), NULL); + g_signal_connect (app, "activate", G_CALLBACK (tfe_activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (tfe_open), NULL); + + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfe5/tfenotebook.c b/src/tfe5/tfenotebook.c new file mode 100644 index 0000000..5b30be2 --- /dev/null +++ b/src/tfe5/tfenotebook.c @@ -0,0 +1,114 @@ +#include "tfe.h" + +/* The returned string should be freed with g_free() when no longer needed. */ +static gchar* +get_untitled () { + static int c = -1; + if (++c == 0) + return g_strdup_printf("Untitled"); + else + return g_strdup_printf ("Untitled%u", c); +} + +static void +file_changed (TfeTextView *tv, GtkNotebook *nb) { + GFile *file; + char *filename; + GtkWidget *scr; + GtkWidget *label; + + file = tfe_text_view_get_file (tv); + scr = gtk_widget_get_parent (GTK_WIDGET (tv)); + if (G_IS_FILE (file)) + filename = g_file_get_basename (file); + else + filename = get_untitled (); + label = gtk_label_new (filename); + gtk_notebook_set_tab_label (nb, scr, label); + g_object_unref (file); + g_free (filename); +} + +/* Save the contents in the current page */ +void +notebook_page_save(GtkNotebook *nb) { + gint i; + GtkWidget *scr; + GtkWidget *tv; + + i = gtk_notebook_get_current_page (nb); + scr = gtk_notebook_get_nth_page (nb, i); + tv = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scr)); + tfe_text_view_save (TFE_TEXT_VIEW (tv)); +} + +static void +notebook_page_build (GtkNotebook *nb, GtkWidget *tv, char *filename) { + GtkWidget *scr; + GtkNotebookPage *nbp; + GtkWidget *lab; + gint i; + scr = gtk_scrolled_window_new (); + + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + lab = gtk_label_new (filename); + i = gtk_notebook_append_page (nb, scr, lab); + nbp = gtk_notebook_get_page (nb, scr); + g_object_set (nbp, "tab-expand", TRUE, NULL); + gtk_notebook_set_current_page (nb, i); + g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb); +} + +static void +open_response (TfeTextView *tv, gint response, GtkNotebook *nb) { + GFile *file; + char *filename; + + if (response != TFE_OPEN_RESPONSE_SUCCESS) + g_object_unref (tv); + else if (! G_IS_FILE (file = tfe_text_view_get_file (tv))) + g_object_unref (tv); + else { + filename = g_file_get_basename (file); + g_object_unref (file); + notebook_page_build (nb, GTK_WIDGET (tv), filename); + } +} + +void +notebook_page_open (GtkNotebook *nb) { + g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + + GtkWidget *tv; + + tv = tfe_text_view_new (); + g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb); + tfe_text_view_open (TFE_TEXT_VIEW (tv)); +} + +void +notebook_page_new_with_file (GtkNotebook *nb, GFile *file) { + g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + g_return_if_fail(G_IS_FILE (file)); + + GtkWidget *tv; + char *filename; + + if ((tv = tfe_text_view_new_with_file (file)) == NULL) + return; /* read error */ + filename = g_file_get_basename (file); + notebook_page_build (nb, tv, filename); +} + +void +notebook_page_new (GtkNotebook *nb) { + g_return_if_fail(GTK_IS_NOTEBOOK (nb)); + + GtkWidget *tv; + char *filename; + + tv = tfe_text_view_new (); + filename = get_untitled (); + notebook_page_build (nb, tv, filename); +} + diff --git a/src/tfe5/tfenotebook.h b/src/tfe5/tfenotebook.h new file mode 100644 index 0000000..ab30489 --- /dev/null +++ b/src/tfe5/tfenotebook.h @@ -0,0 +1,12 @@ +void +notebook_page_save(GtkNotebook *nb); + +void +notebook_page_open (GtkNotebook *nb); + +void +notebook_page_new_with_file (GtkNotebook *nb, GFile *file); + +void +notebook_page_new (GtkNotebook *nb); + diff --git a/src/tfe5/tfetextview.c b/src/tfe5/tfetextview.c new file mode 100644 index 0000000..05149b8 --- /dev/null +++ b/src/tfe5/tfetextview.c @@ -0,0 +1,218 @@ +#include "tfe.h" + +struct _TfeTextView +{ + GtkTextView parent; + GtkTextBuffer *tb; + GFile *file; + gboolean changed; +}; + +G_DEFINE_TYPE (TfeTextView, tfe_text_view, GTK_TYPE_TEXT_VIEW); + +enum { + CHANGE_FILE, + OPEN_RESPONSE, + NUMBER_OF_SIGNALS +}; + +static guint tfe_text_view_signals[NUMBER_OF_SIGNALS]; + +/* Signal handler */ +static void +on_changed (GtkTextBuffer *tb, TfeTextView *tv) { + tv->changed=TRUE; +} + +static void +tfe_text_view_dispose (GObject *gobject) { + TfeTextView *tv = TFE_TEXT_VIEW (gobject); + + if (G_IS_FILE (tv->file)) + g_clear_object (&tv->file); + + G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject); +} + +static void +tfe_text_view_init (TfeTextView *tv) { + tv->tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + tv->file = NULL; + tv->changed = FALSE; + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + g_signal_connect (tv->tb, "changed", G_CALLBACK (on_changed), tv); +} + +static void +tfe_text_view_class_init (TfeTextViewClass *class) { + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = tfe_text_view_dispose; + tfe_text_view_signals[CHANGE_FILE] = g_signal_newv ("change-file", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + NULL /* closure */, + NULL /* accumulator */, + NULL /* accumulator data */, + NULL /* C marshaller */, + G_TYPE_NONE /* return_type */, + 0 /* n_params */, + NULL /* param_types */); + GType param_types[] = {G_TYPE_INT}; + tfe_text_view_signals[OPEN_RESPONSE] = g_signal_newv ("open-response", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + NULL /* closure */, + NULL /* accumulator */, + NULL /* accumulator data */, + NULL /* C marshaller */, + G_TYPE_NONE /* return_type */, + 1 /* n_params */, + param_types); +} + +GFile * +tfe_text_view_get_file (TfeTextView *tv) { + g_return_val_if_fail (TFE_IS_TEXT_VIEW (tv), NULL); + + return g_file_dup (tv->file); +} + +static void +open_dialog_response(GtkWidget *dialog, gint response, TfeTextView *tv) { + GFile *file; + char *contents; + gsize length; + GtkWidget *message_dialog; + GError *err = NULL; + + if (response != GTK_RESPONSE_ACCEPT) + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL); + else if (! G_IS_FILE (file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)))) + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + else if (! g_file_load_contents (file, NULL, &contents, &length, NULL, &err)) { /* read error */ + if (G_IS_FILE (file)) + g_object_unref (file); + message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "%s.\n", err->message); + g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL); + gtk_widget_show (message_dialog); + g_error_free (err); + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); + } else { + gtk_text_buffer_set_text (tv->tb, contents, length); + g_free (contents); + tv->file = file; +/* tv->changed = FALSE;*/ + g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS); + } + gtk_window_destroy (GTK_WINDOW (dialog)); +} + +void +tfe_text_view_open (TfeTextView *tv) { + g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + + GtkWidget *dialog; + + dialog = gtk_file_chooser_dialog_new ("Open file", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, + "Cancel", GTK_RESPONSE_CANCEL, + "Open", GTK_RESPONSE_ACCEPT, + NULL); + g_signal_connect (dialog, "response", G_CALLBACK (open_dialog_response), tv); + gtk_widget_show (dialog); +} + +static void +saveas_dialog_response (GtkWidget *dialog, gint response, TfeTextView *tv) { + GFile *file; + + if (response == GTK_RESPONSE_ACCEPT) { + file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); + if (G_IS_FILE(file)) { + tv->file = file; + tv->changed = TRUE; + g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + tfe_text_view_save (TFE_TEXT_VIEW (tv)); + } + } + gtk_window_destroy (GTK_WINDOW (dialog)); +} + +void +tfe_text_view_save (TfeTextView *tv) { + g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + + GtkTextIter start_iter; + GtkTextIter end_iter; + gchar *contents; + GtkWidget *message_dialog; + GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW); + GError *err = NULL; + + if (! tv->changed) + return; /* no necessary to save it */ + else if (tv->file == NULL) + tfe_text_view_saveas (tv); + else { + gtk_text_buffer_get_bounds (tv->tb, &start_iter, &end_iter); + contents = gtk_text_buffer_get_text (tv->tb, &start_iter, &end_iter, FALSE); + if (g_file_replace_contents (tv->file, contents, strlen (contents), NULL, TRUE, G_FILE_CREATE_NONE, NULL, NULL, &err)) + tv->changed = FALSE; + else { +/* It is possible that tv->file is broken. */ +/* It is a good idea to set tv->file to NULL. */ + if (G_IS_FILE (tv->file)) + g_object_unref (tv->file); + tv->file =NULL; + g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0); + tv->changed = TRUE; + message_dialog = gtk_message_dialog_new (GTK_WINDOW (win), GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "%s.\n", err->message); + g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL); + gtk_widget_show (message_dialog); + g_error_free (err); + } + } +} + +void +tfe_text_view_saveas (TfeTextView *tv) { + g_return_if_fail (TFE_IS_TEXT_VIEW (tv)); + + GtkWidget *dialog; + GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (tv), GTK_TYPE_WINDOW); + + dialog = gtk_file_chooser_dialog_new ("Save file", GTK_WINDOW (win), GTK_FILE_CHOOSER_ACTION_SAVE, + "_Cancel", GTK_RESPONSE_CANCEL, + "_Save", GTK_RESPONSE_ACCEPT, + NULL); + g_signal_connect (dialog, "response", G_CALLBACK (saveas_dialog_response), tv); + gtk_widget_show (dialog); +} + +GtkWidget * +tfe_text_view_new_with_file (GFile *file) { + g_return_val_if_fail (G_IS_FILE (file), NULL); + + GtkWidget *tv; + char *contents; + gsize length; + + if (! g_file_load_contents (file, NULL, &contents, &length, NULL, NULL)) /* read error */ + return NULL; + + tv = tfe_text_view_new(); + gtk_text_buffer_set_text (TFE_TEXT_VIEW (tv)->tb, contents, length); + g_free (contents); + TFE_TEXT_VIEW (tv)->file = g_file_dup (file); + return tv; +} + +GtkWidget * +tfe_text_view_new (void) { + return gtk_widget_new (TFE_TYPE_TEXT_VIEW, NULL); +} + diff --git a/src/tfe5/tfetextview.h b/src/tfe5/tfetextview.h new file mode 100644 index 0000000..b48a412 --- /dev/null +++ b/src/tfe5/tfetextview.h @@ -0,0 +1,29 @@ +#define TFE_TYPE_TEXT_VIEW tfe_text_view_get_type () +G_DECLARE_FINAL_TYPE (TfeTextView, tfe_text_view, TFE, TEXT_VIEW, GtkTextView) + +/* "open-response" signal response */ +enum +{ + TFE_OPEN_RESPONSE_SUCCESS, + TFE_OPEN_RESPONSE_CANCEL, + TFE_OPEN_RESPONSE_ERROR +}; + +GFile * +tfe_text_view_get_file (TfeTextView *tv); + +void +tfe_text_view_open (TfeTextView *tv); + +void +tfe_text_view_save (TfeTextView *tv); + +void +tfe_text_view_saveas (TfeTextView *tv); + +GtkWidget * +tfe_text_view_new_with_file (GFile *file); + +GtkWidget * +tfe_text_view_new (void); + diff --git a/src/tfv1.c b/src/tfv1.c new file mode 100644 index 0000000..f6dd45e --- /dev/null +++ b/src/tfv1.c @@ -0,0 +1,46 @@ +#include + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + GtkWidget *tv; + GtkTextBuffer *tb; + gchar *text; + + text = +"Once upon a time, there was an old man who was called Taketori-no-Okina." +"It is a japanese word that means a man whose work is making bamboo baskets.\n" +"One day, he went into a mountain and found a shining bamboo." +"\"What a mysterious bamboo it is!,\" he said." +"He cuts it, then there was a small cute baby girl in it." +"The girl was shining faintly." +"He thought this baby girl is a gift from Heaven and took her home.\n" +"His wife was surprized at his tale." +"They were very happy because they had no children." +; + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "Taketori"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + tv = gtk_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_buffer_set_text (tb, text, -1); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + + gtk_window_set_child (GTK_WINDOW (win), tv); + + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfv1", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfv2.c b/src/tfv2.c new file mode 100644 index 0000000..6edd635 --- /dev/null +++ b/src/tfv2.c @@ -0,0 +1,50 @@ +#include + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win; + GtkWidget *scr; + GtkWidget *tv; + GtkTextBuffer *tb; + gchar *text; + + text = +"Once upon a time, there was an old man who was called Taketori-no-Okina." +"It is a japanese word that means a man whose work is making bamboo baskets.\n" +"One day, he went into a mountain and found a shining bamboo." +"\"What a mysterious bamboo it is!,\" he said." +"He cuts it, then there was a small cute baby girl in it." +"The girl was shining faintly." +"He thought this baby girl is a gift from Heaven and took her home.\n" +"His wife was surprized at his tale." +"They were very happy because they had no children." +; + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "Taketori"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + scr = gtk_scrolled_window_new (); + gtk_window_set_child (GTK_WINDOW (win), scr); + + tv = gtk_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_buffer_set_text (tb, text, -1); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfv2", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfv3.c b/src/tfv3.c new file mode 100644 index 0000000..92fe1ac --- /dev/null +++ b/src/tfv3.c @@ -0,0 +1,56 @@ +#include + +static void +on_activate (GApplication *app, gpointer user_data) { + g_print ("You need a filename argument.\n"); +} + +static void +on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + GtkWidget *win; + GtkWidget *scr; + GtkWidget *tv; + GtkTextBuffer *tb; + char *contents; + gsize length; + char *filename; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + + scr = gtk_scrolled_window_new (); + gtk_window_set_child (GTK_WINDOW (win), scr); + + tv = gtk_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + + if (g_file_load_contents (files[0], NULL, &contents, &length, NULL, NULL)) { + gtk_text_buffer_set_text (tb, contents, length); + g_free (contents); + filename = g_file_get_basename (files[0]); + gtk_window_set_title (GTK_WINDOW (win), filename); + g_free (filename); + gtk_widget_show (win); + } else { + filename = g_file_get_path (files[0]); + g_print ("No such file: %s.\n", filename); + gtk_window_destroy (GTK_WINDOW (win)); + } +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/tfv4.c b/src/tfv4.c new file mode 100644 index 0000000..c0b26f6 --- /dev/null +++ b/src/tfv4.c @@ -0,0 +1,71 @@ +#include + +static void +on_activate (GApplication *app, gpointer user_data) { + g_print ("You need a filename argument.\n"); +} + +static void +on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { + GtkWidget *win; + GtkWidget *nb; + GtkWidget *lab; + GtkNotebookPage *nbp; + GtkWidget *scr; + GtkWidget *tv; + GtkTextBuffer *tb; + char *contents; + gsize length; + char *filename; + int i; + + win = gtk_application_window_new (GTK_APPLICATION (app)); + gtk_window_set_title (GTK_WINDOW (win), "file viewer"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 300); + gtk_window_maximize (GTK_WINDOW (win)); + + nb = gtk_notebook_new (); + gtk_window_set_child (GTK_WINDOW (win), nb); + + for (i = 0; i < n_files; i++) { + if (g_file_load_contents (files[i], NULL, &contents, &length, NULL, NULL)) { + scr = gtk_scrolled_window_new (); + tv = gtk_text_view_new (); + tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR); + gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv); + + gtk_text_buffer_set_text (tb, contents, length); + g_free (contents); + filename = g_file_get_basename (files[i]); + lab = gtk_label_new (filename); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), scr, lab); + nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); + g_object_set (nbp, "tab-expand", TRUE, NULL); + g_free (filename); + } else { + filename = g_file_get_path (files[i]); + g_print ("No such file: %s.\n", filename); + g_free (filename); + } + } + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) + gtk_widget_show (win); + else + gtk_window_destroy (GTK_WINDOW (win)); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.tfv4", G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src2md.rb b/src2md.rb new file mode 100755 index 0000000..29730f2 --- /dev/null +++ b/src2md.rb @@ -0,0 +1,21 @@ +#!/bin/sh +exec ruby -x "$0" "$@" +#!ruby + +# src2md.rb + +require_relative 'lib/lib_src2md.rb' + +def usage + $stderr.print "Usage: ruby srcd2md.rb src.md_file md_file\n" +end + +if ARGV.size != 2 + usage + exit 1 +end + +srcmd = ARGV[0] +md = ARGV[1] +src2md srcmd, md +