mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
Latex and pdf file generation is supported.
This commit is contained in:
parent
63434371c3
commit
568ecd439c
33 changed files with 251 additions and 46 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
||||||
insertfunc.rb
|
insertfunc.rb
|
||||||
pickoutfunc.rb
|
pickoutfunc.rb
|
||||||
src/img.rb
|
src/img.rb
|
||||||
|
src/imgsize.rb
|
||||||
src/toi.rb
|
src/toi.rb
|
||||||
src/misc/a.out
|
src/misc/a.out
|
||||||
src/tfv/a.out
|
src/tfv/a.out
|
||||||
|
|
74
Rakefile
74
Rakefile
|
@ -3,7 +3,6 @@ require 'rake/clean'
|
||||||
require_relative 'lib/lib_sec_file.rb'
|
require_relative 'lib/lib_sec_file.rb'
|
||||||
require_relative 'lib/lib_src2md.rb'
|
require_relative 'lib/lib_src2md.rb'
|
||||||
|
|
||||||
|
|
||||||
srcfiles = []
|
srcfiles = []
|
||||||
FileList['src/*.src.md'].each do |file|
|
FileList['src/*.src.md'].each do |file|
|
||||||
srcfiles << Sec_file.new(file)
|
srcfiles << Sec_file.new(file)
|
||||||
|
@ -15,6 +14,12 @@ mdfilenames = srcfiles.map {|srcfile| srcfile.to_md}
|
||||||
htmlfilenames = srcfiles.map {|srcfile| "html/"+srcfile.to_html}
|
htmlfilenames = srcfiles.map {|srcfile| "html/"+srcfile.to_html}
|
||||||
texfilenames = srcfiles.map {|srcfile| "latex/"+srcfile.to_tex}
|
texfilenames = srcfiles.map {|srcfile| "latex/"+srcfile.to_tex}
|
||||||
|
|
||||||
|
["html", "latex"].each do |d|
|
||||||
|
if ! Dir.exist?(d)
|
||||||
|
Dir.mkdir(d)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
CLEAN.append(*mdfilenames)
|
CLEAN.append(*mdfilenames)
|
||||||
CLEAN << "Readme.md"
|
CLEAN << "Readme.md"
|
||||||
|
|
||||||
|
@ -72,6 +77,26 @@ You should be careful because there exists bugs, errors or mistakes.
|
||||||
<ul>
|
<ul>
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
|
# Preamble for latex files.
|
||||||
|
|
||||||
|
main = <<'EOS'
|
||||||
|
\documentclass[a4paper]{article}
|
||||||
|
\include{helper.tex}
|
||||||
|
\title{Gtk4 tutorial for beginners}
|
||||||
|
\author{Toshio Sekiya}
|
||||||
|
\begin{document}
|
||||||
|
\maketitle
|
||||||
|
\tableofcontents
|
||||||
|
EOS
|
||||||
|
|
||||||
|
helper = <<'EOS'
|
||||||
|
\usepackage[pdftex]{graphicx}
|
||||||
|
\usepackage[colorlinks=true,linkcolor=black]{hyperref}
|
||||||
|
\usepackage[margin=2.4cm]{geometry}
|
||||||
|
\providecommand{\tightlist}{%
|
||||||
|
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
|
||||||
|
EOS
|
||||||
|
|
||||||
# tasks
|
# tasks
|
||||||
|
|
||||||
task default: :md
|
task default: :md
|
||||||
|
@ -93,7 +118,7 @@ end
|
||||||
|
|
||||||
0.upto(srcfiles.size - 1) do |i|
|
0.upto(srcfiles.size - 1) do |i|
|
||||||
file srcfiles[i].to_md => (srcfiles[i].c_files << srcfiles[i].path) do
|
file srcfiles[i].to_md => (srcfiles[i].c_files << srcfiles[i].path) do
|
||||||
src2md srcfiles[i].path, srcfiles[i].to_md
|
src2md srcfiles[i].path, srcfiles[i].to_md, -1
|
||||||
if srcfiles.size == 1
|
if srcfiles.size == 1
|
||||||
nav = "Up: [Readme.md](Readme.md)\n"
|
nav = "Up: [Readme.md](Readme.md)\n"
|
||||||
elsif i == 0
|
elsif i == 0
|
||||||
|
@ -116,7 +141,7 @@ file "html/index.html" do
|
||||||
0.upto(srcfiles.size-1) do |i|
|
0.upto(srcfiles.size-1) do |i|
|
||||||
h = File.open(srcfiles[i].path) { |file| file.readline }
|
h = File.open(srcfiles[i].path) { |file| file.readline }
|
||||||
h = h.gsub(/^#* */,"").chomp
|
h = h.gsub(/^#* */,"").chomp
|
||||||
file_index = file_index + "<li> <a href=\"#{srcfiles[i].to_html}\">#{h}</a> </li>\n"
|
file_index += "<li> <a href=\"#{srcfiles[i].to_html}\">#{h}</a> </li>\n"
|
||||||
end
|
end
|
||||||
file_index += ("</ul>\n" + tail)
|
file_index += ("</ul>\n" + tail)
|
||||||
IO.write("html/index.html",file_index)
|
IO.write("html/index.html",file_index)
|
||||||
|
@ -124,7 +149,12 @@ end
|
||||||
|
|
||||||
0.upto(srcfiles.size - 1) do |i|
|
0.upto(srcfiles.size - 1) do |i|
|
||||||
file "html/"+srcfiles[i].to_html => (srcfiles[i].c_files << srcfiles[i].path) do
|
file "html/"+srcfiles[i].to_html => (srcfiles[i].c_files << srcfiles[i].path) do
|
||||||
src2md srcfiles[i].path, "html/"+srcfiles[i].to_md
|
src2md srcfiles[i].path, "html/"+srcfiles[i].to_md, -1
|
||||||
|
buf = IO.readlines "html/"+srcfiles[i].to_md
|
||||||
|
buf.each do |line|
|
||||||
|
line.gsub!(/(\[[^\]]*\])\((sec\d+)\.md\)/,"\\1(\\2.html)")
|
||||||
|
end
|
||||||
|
IO.write "html/"+srcfiles[i].to_md, buf.join
|
||||||
sh "pandoc -o html/#{srcfiles[i].to_html} html/#{srcfiles[i].to_md}"
|
sh "pandoc -o html/#{srcfiles[i].to_html} html/#{srcfiles[i].to_md}"
|
||||||
File.delete("html/#{srcfiles[i].to_md}")
|
File.delete("html/#{srcfiles[i].to_md}")
|
||||||
if srcfiles.size == 1
|
if srcfiles.size == 1
|
||||||
|
@ -147,7 +177,41 @@ end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
task pdf: "latex" do
|
||||||
|
sh "cd latex; pdflatex main.tex"
|
||||||
|
sh "cd latex; pdflatex main.tex"
|
||||||
|
sh "mv latex/main.pdf latex/gtk4_tutorial.pdf"
|
||||||
|
end
|
||||||
|
|
||||||
|
task latex: texfilenames+["latex/main.tex"]
|
||||||
|
|
||||||
|
file "latex/main.tex" do
|
||||||
|
0.upto(srcfiles.size-1) do |i|
|
||||||
|
main += " \\input{#{srcfiles[i].to_tex}}\n"
|
||||||
|
end
|
||||||
|
main += "\\end{document}\n"
|
||||||
|
IO.write("latex/main.tex", main)
|
||||||
|
IO.write("latex/helper.tex", helper)
|
||||||
|
end
|
||||||
|
|
||||||
|
0.upto(srcfiles.size - 1) do |i|
|
||||||
|
file "latex/"+srcfiles[i].to_tex => (srcfiles[i].c_files << srcfiles[i].path) do
|
||||||
|
src2md srcfiles[i].path, "latex/"+srcfiles[i].to_md, 80
|
||||||
|
sh "pandoc -o latex/#{srcfiles[i].to_tex} latex/#{srcfiles[i].to_md}"
|
||||||
|
File.delete("latex/#{srcfiles[i].to_md}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
task :clean
|
task :clean
|
||||||
task :cleanhtml do
|
task :cleanhtml do
|
||||||
sh "rm html/*"
|
if Dir.exist?("html") && (! Dir.empty?("html"))
|
||||||
|
sh "rm html/*"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
task :cleanlatex do
|
||||||
|
if Dir.exist?("latex") && (! Dir.empty?("latex"))
|
||||||
|
sh "rm latex/*"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
task cleanall: [:clean, :cleanhtml, :cleanlatex]
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,61 @@
|
||||||
# lib_src2md.rb
|
# lib_src2md.rb
|
||||||
|
require 'pathname'
|
||||||
|
|
||||||
def src2md srcmd, md
|
# The method 'src2md' convert .src.md file into .md file.
|
||||||
|
# The output .md file is fit for the final format, which is one of markdown, html and latex.
|
||||||
|
# - Links to relative URL are removed for latex. Otherwise, it remains.
|
||||||
|
# See "Hyperref and relative link" below for further explanation.
|
||||||
|
# - Width and height for images are removed for markdown and html. it remains for latex.
|
||||||
|
# ![sample](sample_image){width=10cm height=5cm} => ![sample](sample_image) for markdown and html
|
||||||
|
|
||||||
|
# ---- Hyperref and relative link ----
|
||||||
|
# Hyperref package makes internal link possible.
|
||||||
|
# The target of the link is made with '\hypertarget' command.
|
||||||
|
# And the link is made with '\hyperlink' command.
|
||||||
|
# For example,
|
||||||
|
# (sec11.tex)
|
||||||
|
# \hyperlink{tfeapplication.c}{Section 13}
|
||||||
|
# ... ...
|
||||||
|
# (sec13.tex)
|
||||||
|
# \hypertarget{tfeapplication.c}{%
|
||||||
|
# \section{tfeapplication.c}\label{tfeapplication.c}}
|
||||||
|
# If you click the text 'Section 13' in sec11.tex, then you can move to '13 tfeapplication.c', which is section 13 in sec13.tex.
|
||||||
|
|
||||||
|
# The following lines are the original one in sec11.md and the result in sec11.tex, which is generated by pandoc.
|
||||||
|
# (sec11.md)
|
||||||
|
# All the source files are listed in [Section 13](sec13.tex).
|
||||||
|
# (sec11.tex)
|
||||||
|
# All the source files are listed in \href{sec13.tex}{Section 13}.
|
||||||
|
# Therefore, if you want to correct the link in sec11.tex, you need to do the followings.
|
||||||
|
# 1. Look at the first line of sec13.md and get the section heading (tfeapplication.c).
|
||||||
|
# 2. substitute "\hyperlink{tfeapplication.c}{Section 13}" for "\href{sec13.tex}{Section 13}".
|
||||||
|
|
||||||
|
# The following lines are another conversion case by pandoc.
|
||||||
|
# (sec7.md)
|
||||||
|
# The source code of `tfe3.c` is stored in [src/tfe](../src/tfe) directory.
|
||||||
|
# (sec7.tex)
|
||||||
|
# The source code of \texttt{tfe3.c} is stored in \href{../src/tfe}{src/tfe} directory.
|
||||||
|
# The pdf file generated by pdflatex recognizes that the link 'href{../src/tfe}' points a pdf file '../src/tfe.pdf'.
|
||||||
|
# To avoid generating such incorrect links, it is good to remove the links from the original markdown file.
|
||||||
|
|
||||||
|
# If the target is full URL, which means absolute URL begins with "http", no problem happens.
|
||||||
|
|
||||||
|
# This Rakefile just remove the links if its target is relative URL.
|
||||||
|
# If you want to revive the link with relative URL, refer the description above.
|
||||||
|
|
||||||
|
# ---- Folding verbatim lines ----
|
||||||
|
# When C sourcefiles or subshell output are included, the lines are folded to fit in 'width'.
|
||||||
|
# Before they are folded, four space characters are prepended to the line.
|
||||||
|
# Therefore, 'width' must be at least five.
|
||||||
|
# Otherwise the lines are not folded.
|
||||||
|
|
||||||
|
def src2md srcmd, md, width
|
||||||
src_buf = IO.readlines srcmd
|
src_buf = IO.readlines srcmd
|
||||||
src_dir = File.dirname srcmd
|
src_dir = File.dirname srcmd
|
||||||
|
md_dir = File.dirname md
|
||||||
|
# type is 'the type of the target', which is one of "markdown", "html" and "latex".
|
||||||
|
type = md_dir == "." ? "markdown" : md_dir
|
||||||
|
|
||||||
md_buf = []
|
md_buf = []
|
||||||
comflag = false
|
comflag = false
|
||||||
src_buf.each do |line|
|
src_buf.each do |line|
|
||||||
|
@ -55,16 +108,53 @@ def src2md srcmd, md
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
width = tmp_buf.size.to_s.length
|
ln_width = tmp_buf.size.to_s.length
|
||||||
n = 1
|
n = 1
|
||||||
tmp_buf.each do |l|
|
tmp_buf.each do |l|
|
||||||
md_buf << sprintf(" %#{width}d %s", n, l)
|
l = sprintf(" %#{ln_width}d %s", n, l)
|
||||||
|
md_buf << l
|
||||||
n += 1
|
n += 1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
md_buf << line.gsub(/(!\[[^\]]*\])\(..\/([^\)]*)\)/, "\\1(\\2)")
|
md_buf << change_rel_link(line, src_dir, File.dirname(md))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
tmp_buf = md_buf
|
||||||
|
md_buf = []
|
||||||
|
tmp_buf.each do |line|
|
||||||
|
if line =~ /^ / && width.instance_of?(Integer) && width >= 5
|
||||||
|
indent = line =~ /^( *\d+ +)/ ? " "*$1.length : " "
|
||||||
|
while line.instance_of?(String) && line.length > width
|
||||||
|
md_buf << line[0, width]+"\n"
|
||||||
|
line = line[width .. -1].gsub(/^/,indent)
|
||||||
|
end
|
||||||
|
elsif type == "latex"
|
||||||
|
line.gsub!(/(^|[^!])\[([^\]]*)\]\((?~http)\)/,"\\1\\2") # remove link
|
||||||
|
else # type == "markdown" or "html"
|
||||||
|
line.gsub!(/(!\[[^\]]*\]\([^\)]*\)) *{width *= *\d*(|\.\d*)cm *height *= *\d*(|\.\d*)cm}/,"\\1")
|
||||||
|
end
|
||||||
|
md_buf << line
|
||||||
|
end
|
||||||
IO.write(md,md_buf.join)
|
IO.write(md,md_buf.join)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def change_rel_link line, src_dir, basedir
|
||||||
|
p_basedir = Pathname.new basedir
|
||||||
|
left = ""
|
||||||
|
right = line
|
||||||
|
while right =~ /(!?\[[^\]]*\])\((.*)\)/
|
||||||
|
left = $`
|
||||||
|
right = $'
|
||||||
|
name = $1
|
||||||
|
link = $2
|
||||||
|
if name =~ /\[(S|s)ection (\d+)\]/
|
||||||
|
link = "sec#{$2}.md"
|
||||||
|
elsif ! (link =~ /^(http|\/)/)
|
||||||
|
p_link = Pathname.new "#{src_dir}/#{link}"
|
||||||
|
link = p_link.relative_path_from(p_basedir).to_s
|
||||||
|
end
|
||||||
|
left += "#{name}(#{link})"
|
||||||
|
end
|
||||||
|
left + right
|
||||||
|
end
|
||||||
|
|
||||||
|
|
2
sec1.md
2
sec1.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Next: [Section 2](sec2.md)
|
Up: [Readme.md](Readme.md), Next: [Section 2](sec2.md)
|
||||||
|
|
||||||
# Prerequisite and Licence
|
# Prerequisite and Licence
|
||||||
|
|
||||||
## Prerequisite
|
## Prerequisite
|
||||||
|
@ -51,4 +52,5 @@ as published by the Free Software Foundation; either version 3 of the License, o
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
See the [GNU General Public License](https://www.gnu.org/licenses/gpl-3.0.html) for more details.
|
See the [GNU General Public License](https://www.gnu.org/licenses/gpl-3.0.html) for more details.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Next: [Section 2](sec2.md)
|
Up: [Readme.md](Readme.md), Next: [Section 2](sec2.md)
|
||||||
|
|
2
sec10.md
2
sec10.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 9](sec9.md), Next: [Section 11](sec11.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 9](sec9.md), Next: [Section 11](sec11.md)
|
||||||
|
|
||||||
# Signals
|
# Signals
|
||||||
|
|
||||||
## Signals
|
## Signals
|
||||||
|
@ -160,4 +161,5 @@ The following is extract from `tfetexties.c`.
|
||||||
- "open-response" signal has one parameter.
|
- "open-response" signal has one parameter.
|
||||||
The fourth parameter is the parameter.
|
The fourth parameter is the parameter.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 9](sec9.md), Next: [Section 11](sec11.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 9](sec9.md), Next: [Section 11](sec11.md)
|
||||||
|
|
4
sec11.md
4
sec11.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 10](sec10.md), Next: [Section 12](sec12.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 10](sec10.md), Next: [Section 12](sec12.md)
|
||||||
|
|
||||||
# Functions in TfeTextView
|
# Functions in TfeTextView
|
||||||
|
|
||||||
In this section I will explain each function in TfeTextView object.
|
In this section I will explain each function in TfeTextView object.
|
||||||
|
@ -356,6 +357,7 @@ Otherwise, if the caller free the GFile object, `tv->file` is no more guaranteed
|
||||||
|
|
||||||
## Source file of tfetextview.c
|
## Source file of tfetextview.c
|
||||||
|
|
||||||
All the source files are listed in [Section 13](https://github.com/ToshioCP/Gtk4-tutorial/blob/main/sec13.md).
|
All the source files are listed in [Section 14](sec14.md).
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 10](sec10.md), Next: [Section 12](sec12.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 10](sec10.md), Next: [Section 12](sec12.md)
|
||||||
|
|
12
sec12.md
12
sec12.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 11](sec11.md), Next: [Section 13](sec13.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 11](sec11.md), Next: [Section 13](sec13.md)
|
||||||
|
|
||||||
# Functions with GtkNotebook
|
# Functions with GtkNotebook
|
||||||
|
|
||||||
GtkNotebook is a very important object in the text file editor `tfe`.
|
GtkNotebook is a very important object in the text file editor `tfe`.
|
||||||
|
@ -26,7 +27,15 @@ The GFile `file` is copied and set in the TfeTextView object.
|
||||||
- 4-5: `notebook_page_open` shows a file chooser dialog. Then, user chooses a file and the file is set into GtkTextBuffer.
|
- 4-5: `notebook_page_open` shows a file chooser dialog. Then, user chooses a file and the file is set into GtkTextBuffer.
|
||||||
- 1-2: `notebook_page_save` saves the contents in GtkTextBuffer into the file, which has been set in the TfeTextView.
|
- 1-2: `notebook_page_save` saves the contents in GtkTextBuffer into the file, which has been set in the TfeTextView.
|
||||||
|
|
||||||
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.
|
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`
|
||||||
|
- `tfe_text_view_save`
|
||||||
|
|
||||||
|
respectively.
|
||||||
|
|
||||||
There are two layers.
|
There are two layers.
|
||||||
One of them is `tfe_text_view ...`, which is the lower level layer.
|
One of them is `tfe_text_view ...`, which is the lower level layer.
|
||||||
The other is `note_book ...`, which is the higher level layer.
|
The other is `note_book ...`, which is the higher level layer.
|
||||||
|
@ -208,4 +217,5 @@ Otherwise (file is NULL), assign untitled string to `filename`.
|
||||||
- 16-17: Free `filename` and unref `file`.
|
- 16-17: Free `filename` and unref `file`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 11](sec11.md), Next: [Section 13](sec13.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 11](sec11.md), Next: [Section 13](sec13.md)
|
||||||
|
|
2
sec13.md
2
sec13.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 12](sec12.md), Next: [Section 14](sec14.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 12](sec12.md), Next: [Section 14](sec14.md)
|
||||||
|
|
||||||
# tfeapplication.c
|
# tfeapplication.c
|
||||||
|
|
||||||
`tfeapplication.c` includes all the code other than `tfetxtview.c` and `tfenotebook.c`.
|
`tfeapplication.c` includes all the code other than `tfetxtview.c` and `tfenotebook.c`.
|
||||||
|
@ -267,4 +268,5 @@ First, get the top level window and call `gtk_window_destroy`.
|
||||||
|
|
||||||
In this file, just the source file names are modified.
|
In this file, just the source file names are modified.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 12](sec12.md), Next: [Section 14](sec14.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 12](sec12.md), Next: [Section 14](sec14.md)
|
||||||
|
|
8
sec14.md
8
sec14.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 13](sec13.md), Next: [Section 15](sec15.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 13](sec13.md), Next: [Section 15](sec15.md)
|
||||||
|
|
||||||
# tfe5 source files
|
# tfe5 source files
|
||||||
|
|
||||||
The followings are the source files of tfe5.
|
The followings are the source files of tfe5.
|
||||||
|
@ -219,7 +220,7 @@ The followings are the source files of tfe5.
|
||||||
116 }
|
116 }
|
||||||
117
|
117
|
||||||
|
|
||||||
### tfenotebook.h
|
## tfenotebook.h
|
||||||
|
|
||||||
1 void
|
1 void
|
||||||
2 notebook_page_save(GtkNotebook *nb);
|
2 notebook_page_save(GtkNotebook *nb);
|
||||||
|
@ -608,7 +609,7 @@ The followings are the source files of tfe5.
|
||||||
|
|
||||||
## Total number of lines, words and charcters
|
## 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
|
$ LANG=C 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
|
10 17 279 tfe5/meson.build
|
||||||
117 348 3576 tfe5/tfeapplication.c
|
117 348 3576 tfe5/tfeapplication.c
|
||||||
6 9 153 tfe5/tfe.gresource.xml
|
6 9 153 tfe5/tfe.gresource.xml
|
||||||
|
@ -618,5 +619,6 @@ The followings are the source files of tfe5.
|
||||||
218 635 7769 tfe5/tfetextview.c
|
218 635 7769 tfe5/tfetextview.c
|
||||||
29 49 561 tfe5/tfetextview.h
|
29 49 561 tfe5/tfetextview.h
|
||||||
64 105 2266 tfe5/tfe.ui
|
64 105 2266 tfe5/tfe.ui
|
||||||
576 1507 17864 合計
|
576 1507 17864 total
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 13](sec13.md), Next: [Section 15](sec15.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 13](sec13.md), Next: [Section 15](sec15.md)
|
||||||
|
|
2
sec15.md
2
sec15.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 14](sec14.md), Next: [Section 16](sec16.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 14](sec14.md), Next: [Section 16](sec16.md)
|
||||||
|
|
||||||
# Menu and action
|
# Menu and action
|
||||||
|
|
||||||
## Menu
|
## Menu
|
||||||
|
@ -213,4 +214,5 @@ The structure of the menu is shown in the diagram below.
|
||||||
|
|
||||||
![Screenshot of menu1](image/menu1_screenshot.png)
|
![Screenshot of menu1](image/menu1_screenshot.png)
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 14](sec14.md), Next: [Section 16](sec16.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 14](sec14.md), Next: [Section 16](sec16.md)
|
||||||
|
|
2
sec16.md
2
sec16.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 15](sec15.md), Next: [Section 17](sec17.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 15](sec15.md), Next: [Section 17](sec17.md)
|
||||||
|
|
||||||
# Stateful action
|
# Stateful action
|
||||||
|
|
||||||
Some actions have states.
|
Some actions have states.
|
||||||
|
@ -368,4 +369,5 @@ Other GtkLabel have no effect from this.
|
||||||
The provider is added to GdkDisplay.
|
The provider is added to GdkDisplay.
|
||||||
- 90: Show the window.
|
- 90: Show the window.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 15](sec15.md), Next: [Section 17](sec17.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 15](sec15.md), Next: [Section 17](sec17.md)
|
||||||
|
|
2
sec17.md
2
sec17.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 16](sec16.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 16](sec16.md)
|
||||||
|
|
||||||
# Ui file for menu and action entries
|
# Ui file for menu and action entries
|
||||||
|
|
||||||
## Ui file for menu
|
## Ui file for menu
|
||||||
|
@ -336,4 +337,5 @@ meson.build
|
||||||
9
|
9
|
||||||
10 executable('menu3', sourcefiles, resources, dependencies: gtkdep)
|
10 executable('menu3', sourcefiles, resources, dependencies: gtkdep)
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 16](sec16.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 16](sec16.md)
|
||||||
|
|
2
sec2.md
2
sec2.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 1](sec1.md), Next: [Section 3](sec3.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 1](sec1.md), Next: [Section 3](sec3.md)
|
||||||
|
|
||||||
# GtkApplication and GtkApplicationWindow
|
# GtkApplication and GtkApplicationWindow
|
||||||
|
|
||||||
## GtkApplication
|
## GtkApplication
|
||||||
|
@ -282,4 +283,5 @@ 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".
|
Compile it and run `a.out`, then you will see a bigger window with its title "pr4".
|
||||||
|
|
||||||
![Screenshot of the window](image/screenshot_pr4.png)
|
![Screenshot of the window](image/screenshot_pr4.png)
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 1](sec1.md), Next: [Section 3](sec3.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 1](sec1.md), Next: [Section 3](sec3.md)
|
||||||
|
|
2
sec3.md
2
sec3.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 2](sec2.md), Next: [Section 4](sec4.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 2](sec2.md), Next: [Section 4](sec4.md)
|
||||||
|
|
||||||
# Widgets (1)
|
# Widgets (1)
|
||||||
|
|
||||||
## GtkLabel, GtkButton and Gtkbox
|
## GtkLabel, GtkButton and Gtkbox
|
||||||
|
@ -313,4 +314,5 @@ Then, these two buttons are appended to the box.
|
||||||
The handler corresponds to `btn1` changes its label.
|
The handler corresponds to `btn1` changes its label.
|
||||||
The handler corresponds to `btn2` destroys the top-level window and the application quits.
|
The handler corresponds to `btn2` destroys the top-level window and the application quits.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 2](sec2.md), Next: [Section 4](sec4.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 2](sec2.md), Next: [Section 4](sec4.md)
|
||||||
|
|
2
sec4.md
2
sec4.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 3](sec3.md), Next: [Section 5](sec5.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 3](sec3.md), Next: [Section 5](sec5.md)
|
||||||
|
|
||||||
# Widgets (2)
|
# Widgets (2)
|
||||||
|
|
||||||
## GtkTextView, GtkTextbuffer and GtkScrolledWindow
|
## GtkTextView, GtkTextbuffer and GtkScrolledWindow
|
||||||
|
@ -162,4 +163,5 @@ Now compile and run it.
|
||||||
This time the window doesn't extend even if you type a lot of characters.
|
This time the window doesn't extend even if you type a lot of characters.
|
||||||
It just scrolls.
|
It just scrolls.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 3](sec3.md), Next: [Section 5](sec5.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 3](sec3.md), Next: [Section 5](sec5.md)
|
||||||
|
|
2
sec5.md
2
sec5.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 4](sec4.md), Next: [Section 6](sec6.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 4](sec4.md), Next: [Section 6](sec6.md)
|
||||||
|
|
||||||
# Widgets (3)
|
# Widgets (3)
|
||||||
|
|
||||||
## Open signal
|
## Open signal
|
||||||
|
@ -302,4 +303,5 @@ The numbers at the left of the following items are line numbers in the source co
|
||||||
- 46: free the memory pointed by `filename`
|
- 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.
|
- 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](Readme.md), Prev: [Section 4](sec4.md), Next: [Section 6](sec6.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 4](sec4.md), Next: [Section 6](sec6.md)
|
||||||
|
|
2
sec6.md
2
sec6.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 5](sec5.md), Next: [Section 7](sec7.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 5](sec5.md), Next: [Section 7](sec7.md)
|
||||||
|
|
||||||
# Define Child object
|
# Define Child object
|
||||||
|
|
||||||
## Very simple editor
|
## Very simple editor
|
||||||
|
@ -347,4 +348,5 @@ It's not smart.
|
||||||
We need more features like open, save, saveas, change font and so on.
|
We need more features like open, save, saveas, change font and so on.
|
||||||
We will add them in the next section and after.
|
We will add them in the next section and after.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 5](sec5.md), Next: [Section 7](sec7.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 5](sec5.md), Next: [Section 7](sec7.md)
|
||||||
|
|
6
sec7.md
6
sec7.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 6](sec6.md), Next: [Section 8](sec8.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 6](sec6.md), Next: [Section 8](sec8.md)
|
||||||
|
|
||||||
# Ui file and GtkBuiler
|
# Ui file and GtkBuiler
|
||||||
|
|
||||||
## New, open and save button
|
## New, open and save button
|
||||||
|
@ -343,9 +344,9 @@ Only functions `on_open` are shown as follows.
|
||||||
47 gtk_window_destroy (GTK_WINDOW (win));
|
47 gtk_window_destroy (GTK_WINDOW (win));
|
||||||
48 }
|
48 }
|
||||||
|
|
||||||
The source code of `tfe3.c` is stored in [src/tfe](https://github.com/ToshioCP/Gtk4-tutorial/tree/main/src/tfe) directory.
|
The source code of `tfe3.c` is stored in [src/tfe](src/tfe) directory.
|
||||||
If you want to see it, click the link above.
|
If you want to see it, click the link above.
|
||||||
In the same way, you can get the source files below in the directory [src/tfe](https://github.com/ToshioCP/Gtk4-tutorial/tree/main/src/tfe).
|
In the same way, you can get the source files below in the directory [src/tfe](src/tfe).
|
||||||
|
|
||||||
### Using ui string
|
### Using ui string
|
||||||
|
|
||||||
|
@ -450,4 +451,5 @@ Modify tfe3.c and save it as tfe3_r.c
|
||||||
Then, compile and run it.
|
Then, compile and run it.
|
||||||
The window appears and it is the same as the screenshot at the beginning of this page.
|
The window appears and it is the same as the screenshot at the beginning of this page.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 6](sec6.md), Next: [Section 8](sec8.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 6](sec6.md), Next: [Section 8](sec8.md)
|
||||||
|
|
2
sec8.md
2
sec8.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 7](sec7.md), Next: [Section 9](sec9.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 7](sec7.md), Next: [Section 9](sec9.md)
|
||||||
|
|
||||||
# Build system
|
# Build system
|
||||||
|
|
||||||
## What do we need to think about to manage big source files?
|
## What do we need to think about to manage big source files?
|
||||||
|
@ -423,4 +424,5 @@ 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.
|
We divided a file into some categorized files and used a build tool.
|
||||||
This method is used by many developers.
|
This method is used by many developers.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 7](sec7.md), Next: [Section 9](sec9.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 7](sec7.md), Next: [Section 9](sec9.md)
|
||||||
|
|
2
sec9.md
2
sec9.md
|
@ -1,4 +1,5 @@
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 8](sec8.md), Next: [Section 10](sec10.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 8](sec8.md), Next: [Section 10](sec10.md)
|
||||||
|
|
||||||
# Instance and class
|
# Instance and class
|
||||||
|
|
||||||
This section and the following four sections are explanations about the next version of the text file editor (tfe).
|
This section and the following four sections are explanations about the next version of the text file editor (tfe).
|
||||||
|
@ -416,4 +417,5 @@ And `gobject` is a pointer to TfeTextView instance which is casted as a GObject
|
||||||
After that, `dh3` calls `dh2`, and `dh2` calls `dh1`.
|
After that, `dh3` calls `dh2`, and `dh2` calls `dh1`.
|
||||||
Finally all the references are released.
|
Finally all the references are released.
|
||||||
|
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 8](sec8.md), Next: [Section 10](sec10.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 8](sec8.md), Next: [Section 10](sec10.md)
|
||||||
|
|
|
@ -108,7 +108,7 @@ The buttons are Cancel and Save.
|
||||||
- 1-16: `saveas_dialog_response` signal handler.
|
- 1-16: `saveas_dialog_response` signal handler.
|
||||||
- 6-14: 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`, turn on the modified bit of the GtkTextBuffer, emits "change-file" signal then call `tfe_text_view_save` to save the buffer to the file.
|
- 6-14: 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`, turn on the modified bit of the GtkTextBuffer, emits "change-file" signal then call `tfe_text_view_save` to save the buffer to the file.
|
||||||
|
|
||||||
![Saveas process](../image/saveas.png)
|
![Saveas process](../image/saveas.png){width=10.7cm height=5.16cm}
|
||||||
|
|
||||||
When you use GtkFileChooserDialog, you need to divide the program into two parts.
|
When you use GtkFileChooserDialog, you need to divide the program into two parts.
|
||||||
They are a function which generates GtkFileChooserDialog and the signal handler.
|
They are a function which generates GtkFileChooserDialog and the signal handler.
|
||||||
|
@ -159,7 +159,7 @@ In Gtk3, `gtk_dialog_run` function is available.
|
||||||
It simplifies the process.
|
It simplifies the process.
|
||||||
However, in Gtk4, `gtk_dialog_run`is unavailable any more.
|
However, in Gtk4, `gtk_dialog_run`is unavailable any more.
|
||||||
|
|
||||||
![Caller and TfeTextView](../image/open.png)
|
![Caller and TfeTextView](../image/open.png){width=12.405cm height=9.225cm}
|
||||||
|
|
||||||
1. A caller get a pointer `tv` to TfeTextView by calling `tfe_text_view_new`.
|
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".
|
2. The caller connects the handler (left bottom in the diagram) and the signal "open-response".
|
||||||
|
@ -179,5 +179,5 @@ Otherwise, if the caller free the GFile object, `tv->file` is no more guaranteed
|
||||||
|
|
||||||
## Source file of tfetextview.c
|
## Source file of tfetextview.c
|
||||||
|
|
||||||
All the source files are listed in [Section 13](https://github.com/ToshioCP/Gtk4-tutorial/blob/main/sec13.md).
|
All the source files are listed in [Section 14](sec14.src.md).
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,15 @@ The GFile `file` is copied and set in the TfeTextView object.
|
||||||
- 4-5: `notebook_page_open` shows a file chooser dialog. Then, user chooses a file and the file is set into GtkTextBuffer.
|
- 4-5: `notebook_page_open` shows a file chooser dialog. Then, user chooses a file and the file is set into GtkTextBuffer.
|
||||||
- 1-2: `notebook_page_save` saves the contents in GtkTextBuffer into the file, which has been set in the TfeTextView.
|
- 1-2: `notebook_page_save` saves the contents in GtkTextBuffer into the file, which has been set in the TfeTextView.
|
||||||
|
|
||||||
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.
|
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`
|
||||||
|
- `tfe_text_view_save`
|
||||||
|
|
||||||
|
respectively.
|
||||||
|
|
||||||
There are two layers.
|
There are two layers.
|
||||||
One of them is `tfe_text_view ...`, which is the lower level layer.
|
One of them is `tfe_text_view ...`, which is the lower level layer.
|
||||||
The other is `note_book ...`, which is the higher level layer.
|
The other is `note_book ...`, which is the higher level layer.
|
||||||
|
|
|
@ -22,7 +22,7 @@ The followings are the source files of tfe5.
|
||||||
|
|
||||||
@@@ tfe5/tfeapplication.c
|
@@@ tfe5/tfeapplication.c
|
||||||
|
|
||||||
### tfenotebook.h
|
## tfenotebook.h
|
||||||
|
|
||||||
@@@ tfe5/tfenotebook.h
|
@@@ tfe5/tfenotebook.h
|
||||||
|
|
||||||
|
@ -41,5 +41,5 @@ The followings are the source files of tfe5.
|
||||||
## Total number of lines, words and charcters
|
## 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
|
LANG=C 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
|
||||||
$$$
|
$$$
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
Users often use menus to tell the command to the computer.
|
Users often use menus to tell the command to the computer.
|
||||||
It is like this:
|
It is like this:
|
||||||
|
|
||||||
![Menu](../image/menu.png)
|
![Menu](../image/menu.png){width=5.985cm height=5.055cm}
|
||||||
|
|
||||||
Now let's analyze the menu above.
|
Now let's analyze the menu above.
|
||||||
There are two types of object.
|
There are two types of object.
|
||||||
|
@ -18,7 +18,7 @@ They are called "menu".
|
||||||
Menu is an ordered list of items.
|
Menu is an ordered list of items.
|
||||||
They are similar to arrays.
|
They are similar to arrays.
|
||||||
|
|
||||||
![Menu structure](../image/menu_structure.png)
|
![Menu structure](../image/menu_structure.png){width=10.23cm height=3.57cm}
|
||||||
|
|
||||||
- Menubar is a menu which has three items, which are "File", "Edit" and "View".
|
- 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.
|
- The menu item labeled "Edit" has a link to the submenu which has two items.
|
||||||
|
@ -162,7 +162,7 @@ The structure of the menu is shown in the diagram below.
|
||||||
- 30: Set GtkApplicationWindow to show the menubar.
|
- 30: Set GtkApplicationWindow to show the menubar.
|
||||||
- 31: Show the window.
|
- 31: Show the window.
|
||||||
|
|
||||||
![menu and action](../image/menu1.png)
|
![menu and action](../image/menu1.png){width=12.555cm height=3.285cm}
|
||||||
|
|
||||||
![Screenshot of menu1](../image/menu1_screenshot.png)
|
![Screenshot of menu1](../image/menu1_screenshot.png){width=6.0cm height=5.115cm}
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,7 @@ It is the string "s" given at the generation time.
|
||||||
The following code includes stateful actions above.
|
The following code includes stateful actions above.
|
||||||
This program has menus like this:
|
This program has menus like this:
|
||||||
|
|
||||||
![menu2](../image/menu2.png)
|
![menu2](../image/menu2.png){width=6.03cm height=5.115cm}
|
||||||
|
|
||||||
- Fullscreen menu toggles the size of the window between maximum and non-maximum.
|
- 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.
|
If the window is maximum size, which is called full screen, then a check mark is put before "fullscreen" label.
|
||||||
|
|
|
@ -57,7 +57,7 @@ So, we usually prefer the former ui file style.
|
||||||
The following is a screenshot of the sample program in this section.
|
The following is a screenshot of the sample program in this section.
|
||||||
Its name is `menu3`.
|
Its name is `menu3`.
|
||||||
|
|
||||||
![menu3](../image/menu3.png)
|
![menu3](../image/menu3.png){width=6.0cm height=5.055cm}
|
||||||
|
|
||||||
The following is the ui file of the menu in `menu3`.
|
The following is the ui file of the menu in `menu3`.
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ And GtkWidget is a base object from which all the GUI objects derive.
|
||||||
|
|
||||||
GtkWindow includes GtkWidget at the top of its object.
|
GtkWindow includes GtkWidget at the top of its object.
|
||||||
|
|
||||||
![GtkWindow and GtkWidget](../image/window_widget.png)
|
![GtkWindow and GtkWidget](../image/window_widget.png){width=9.0cm height=6.0cm}
|
||||||
|
|
||||||
The function `gtk_window_new` is defined as follows.
|
The function `gtk_window_new` is defined as follows.
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ Save the program as `pr3.c` and compile and run it.
|
||||||
|
|
||||||
A small window appears.
|
A small window appears.
|
||||||
|
|
||||||
![Screenshot of the window](../image/screenshot_pr3.png)
|
![Screenshot of the window](../image/screenshot_pr3.png){width=3.3cm height=3.825cm}
|
||||||
|
|
||||||
Click on the close button then the window disappears and the program finishes.
|
Click on the close button then the window disappears and the program finishes.
|
||||||
|
|
||||||
|
@ -235,4 +235,4 @@ 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.
|
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".
|
Compile it and run `a.out`, then you will see a bigger window with its title "pr4".
|
||||||
|
|
||||||
![Screenshot of the window](../image/screenshot_pr4.png)
|
![Screenshot of the window](../image/screenshot_pr4.png){width=6.3cm height=5.325cm}
|
||||||
|
|
|
@ -19,7 +19,7 @@ Then compile and run it.
|
||||||
|
|
||||||
A window with a message "Hello." appears.
|
A window with a message "Hello." appears.
|
||||||
|
|
||||||
![Screenshot of the label](../image/screenshot_lb1.png)
|
![Screenshot of the label](../image/screenshot_lb1.png){width=6.3cm height=5.325cm}
|
||||||
|
|
||||||
There's only a little change between `pr4.c` and `lb1.c`.
|
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 is a good program to know the difference between two files.
|
||||||
|
@ -69,7 +69,7 @@ The suffix cb means "call back".
|
||||||
Name the program `lb2.c` and save it.
|
Name the program `lb2.c` and save it.
|
||||||
Now compile and run it.
|
Now compile and run it.
|
||||||
|
|
||||||
![Screenshot of the label](../image/screenshot_lb2.png)
|
![Screenshot of the label](../image/screenshot_lb2.png){width=11.205cm height=6.945cm}
|
||||||
|
|
||||||
A window with the button appears.
|
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.
|
Click the button (it is a large button, you can click everywhere inside the window), then a string "Clicked." appears on the shell terminal.
|
||||||
|
@ -115,7 +115,7 @@ The following procedure shows the way to add two buttons in a window.
|
||||||
|
|
||||||
After this, the Widgets are connected as following diagram.
|
After this, the Widgets are connected as following diagram.
|
||||||
|
|
||||||
![Parent-child relationship](../image/box.png)
|
![Parent-child relationship](../image/box.png){width=7.725cm height=2.055cm}
|
||||||
|
|
||||||
Now, code it.
|
Now, code it.
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ 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.
|
After that, two buttons `btn1` and `btn2` are generated and the signal handlers are set.
|
||||||
Then, these two buttons are appended to the box.
|
Then, these two buttons are appended to the box.
|
||||||
|
|
||||||
![Screenshot of the box](../image/screenshot_lb4.png)
|
![Screenshot of the box](../image/screenshot_lb4.png){width=6.3cm height=5.325cm}
|
||||||
|
|
||||||
The handler corresponds to `btn1` changes its label.
|
The handler corresponds to `btn1` changes its label.
|
||||||
The handler corresponds to `btn2` destroys the top-level window and the application quits.
|
The handler corresponds to `btn2` destroys the top-level window and the application quits.
|
||||||
|
|
|
@ -23,7 +23,7 @@ In line 30, `tv` is set to `win` as a child.
|
||||||
|
|
||||||
Now compile and run it.
|
Now compile and run it.
|
||||||
|
|
||||||
![GtkTextView](../image/screenshot_tfv1.png)
|
![GtkTextView](../image/screenshot_tfv1.png){width=6.3cm height=5.325cm}
|
||||||
|
|
||||||
There's an I-beam pointer in the window.
|
There's an I-beam pointer in the window.
|
||||||
You can add or delete any characters on GtkTextview.
|
You can add or delete any characters on GtkTextview.
|
||||||
|
|
|
@ -95,7 +95,7 @@ Then compile and run it.
|
||||||
$ comp tfv3
|
$ comp tfv3
|
||||||
$ ./a.out tfv3.c
|
$ ./a.out tfv3.c
|
||||||
|
|
||||||
![File viewer](../image/screenshot_tfv3.png)
|
![File viewer](../image/screenshot_tfv3.png){width=6.3cm height=5.325cm}
|
||||||
|
|
||||||
Now I want to explain the program `tfv3.c`.
|
Now I want to explain the program `tfv3.c`.
|
||||||
First, the function `main` changes in only two lines.
|
First, the function `main` changes in only two lines.
|
||||||
|
@ -142,7 +142,7 @@ If it fails, it outputs an error message and destroys the window.
|
||||||
|
|
||||||
GtkNotebook is a container widget that contains multiple children with tabs in it.
|
GtkNotebook is a container widget that contains multiple children with tabs in it.
|
||||||
|
|
||||||
![GtkNotebook](../image/screenshot_gtk_notebook.png)
|
![GtkNotebook](../image/screenshot_gtk_notebook.png){width=13.2cm height=5.325cm}
|
||||||
|
|
||||||
Look at the screenshots above.
|
Look at the screenshots above.
|
||||||
The left one is a window at the startup.
|
The left one is a window at the startup.
|
||||||
|
|
|
@ -39,7 +39,7 @@ What we are thinking about now is "child object".
|
||||||
A child object includes its parent object.
|
A child object includes its parent object.
|
||||||
And a child object derives everything from the parent object.
|
And a child object derives everything from the parent object.
|
||||||
|
|
||||||
![Child widget of GtkTwxtView](../image/child.png)
|
![Child widget of GtkTwxtView](../image/child.png){width=9.675cm height=4.89cm}
|
||||||
|
|
||||||
We will define TfeTextView as a child object of GtkTextView.
|
We will define TfeTextView as a child object of GtkTextView.
|
||||||
It has everything that GtkTextView has.
|
It has everything that GtkTextView has.
|
||||||
|
|
|
@ -9,7 +9,7 @@ It is better to make "New", "Open", "Save" and "Close" buttons.
|
||||||
This section describes how to put those buttons into the window.
|
This section describes how to put those buttons into the window.
|
||||||
Signals and handlers will be explained later.
|
Signals and handlers will be explained later.
|
||||||
|
|
||||||
![Screenshot of the file editor](../image/screenshot_tfe2.png)
|
![Screenshot of the file editor](../image/screenshot_tfe2.png){width=9.3cm height=6.825cm}
|
||||||
|
|
||||||
The screenshot above shows the layout.
|
The screenshot above shows the layout.
|
||||||
The function `on_open` in the source code `tfe2.c` is as follows.
|
The function `on_open` in the source code `tfe2.c` is as follows.
|
||||||
|
@ -97,9 +97,9 @@ Only functions `on_open` are shown as follows.
|
||||||
|
|
||||||
@@@ tfe/tfe3.c on_open
|
@@@ tfe/tfe3.c on_open
|
||||||
|
|
||||||
The source code of `tfe3.c` is stored in [src/tfe](https://github.com/ToshioCP/Gtk4-tutorial/tree/main/src/tfe) directory.
|
The source code of `tfe3.c` is stored in [src/tfe](tfe) directory.
|
||||||
If you want to see it, click the link above.
|
If you want to see it, click the link above.
|
||||||
In the same way, you can get the source files below in the directory [src/tfe](https://github.com/ToshioCP/Gtk4-tutorial/tree/main/src/tfe).
|
In the same way, you can get the source files below in the directory [src/tfe](tfe).
|
||||||
|
|
||||||
### Using ui string
|
### Using ui string
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ This is very important.
|
||||||
It guarantees a child widget to derive all the features from ancestors.
|
It guarantees a child widget to derive all the features from ancestors.
|
||||||
The structure of `TfeTextView` is like the following diagram.
|
The structure of `TfeTextView` is like the following diagram.
|
||||||
|
|
||||||
![The structure of the instance TfeTextView](../image/TfeTextView.png)
|
![The structure of the instance TfeTextView](../image/TfeTextView.png){width=14.39cm height=2.16cm}
|
||||||
|
|
||||||
|
|
||||||
## Generate TfeTextView instance
|
## Generate TfeTextView instance
|
||||||
|
@ -186,7 +186,7 @@ Override is rewriting ancestors' class methods in the descendent class.)
|
||||||
TfeTextViewClass includes its ancsestors' class in it.
|
TfeTextViewClass includes its ancsestors' class in it.
|
||||||
It is illustrated in the following diagram.
|
It is illustrated in the following diagram.
|
||||||
|
|
||||||
![The structure of TfeTextView Class](../image/TfeTextViewClass.png)
|
![The structure of TfeTextView Class](../image/TfeTextViewClass.png){width=16.02cm height=8.34cm}
|
||||||
|
|
||||||
## Destruction of TfeTextView
|
## Destruction of TfeTextView
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ At this moment, no object refers C and the reference count of C is zero.
|
||||||
This means C is no longer useful.
|
This means C is no longer useful.
|
||||||
Then C destructs itself and finally the memories allocated to C is freed.
|
Then C destructs itself and finally the memories allocated to C is freed.
|
||||||
|
|
||||||
![Reference count of B](../image/refcount.png)
|
![Reference count of B](../image/refcount.png){width=15.855cm height=2.475cm}
|
||||||
|
|
||||||
The idea above is based on an assumption that an object refered by nothing has reference count of zero.
|
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.
|
When the reference count drops to zero, the object starts its destruction process.
|
||||||
|
@ -238,7 +238,7 @@ Look at the following diagram.
|
||||||
There are four classes -- GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass.
|
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`.
|
Each class has its own dispose handler -- `dh1`, `dh2`, `dh3` and `tfe_text_view_dispose`.
|
||||||
|
|
||||||
![dispose handers](../image/dispose_handler.png)
|
![dispose handers](../image/dispose_handler.png){width=14.925cm height=4.455cm}
|
||||||
|
|
||||||
Now, look at the `tfe_text_view_dispose` program above.
|
Now, look at the `tfe_text_view_dispose` program above.
|
||||||
It first releases the reference to GFile object pointed by `tv->file`.
|
It first releases the reference to GFile object pointed by `tv->file`.
|
||||||
|
|
Loading…
Reference in a new issue