From 9cf03df906632ead446fb1d2f3ed189517d5c6af Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Sat, 5 Jun 2021 23:15:22 +0200 Subject: [PATCH 1/5] Overhaul website design and content --- _config.yml | 2 +- _data/crates.json | 42 +- _includes/badges.html | 24 - _includes/book.svg | 13 + _includes/crates.html | 25 ++ _includes/footer.html | 59 +-- _includes/header.html | 18 +- _includes/projects.md | 43 ++ _layouts/{wide.html => no-wrapper.html} | 4 +- _sass/_base.scss | 112 +++-- _sass/_layout.scss | 450 ++++++++++--------- _sass/_syntax-highlighting.scss | 42 +- _sass/_variables.scss | 43 ++ blog/index.html | 8 +- contact.md | 14 + css/main.scss | 71 +-- docs-src/contact.md | 19 - docs-src/index.md | 48 -- docs-src/sponsors.md | 37 -- docs-src/tutorial/closures.md | 156 ------- docs-src/tutorial/cross-linux-arch.md | 40 -- docs-src/tutorial/cross.md | 182 -------- docs-src/tutorial/gir_tutorial.md | 558 ------------------------ docs-src/tutorial/glade.md | 140 ------ docs-src/tutorial/gnome_and_rust.md | 68 --- docs-src/tutorial/index.md | 32 -- docs-src/tutorial/object_oriented.md | 70 --- docs-src/tutorial/rust_and_gtk.md | 59 --- docs-src/tutorial/version.md | 62 --- docs-src/useful-links.md | 16 - docs-src/faq.md => faq.md | 29 +- images/gtk-rs.png | Bin 0 -> 22620 bytes index.md | 244 ++++------- 33 files changed, 607 insertions(+), 2123 deletions(-) delete mode 100644 _includes/badges.html create mode 100644 _includes/book.svg create mode 100644 _includes/crates.html create mode 100644 _includes/projects.md rename _layouts/{wide.html => no-wrapper.html} (67%) create mode 100644 _sass/_variables.scss create mode 100644 contact.md delete mode 100644 docs-src/contact.md delete mode 100644 docs-src/index.md delete mode 100644 docs-src/sponsors.md delete mode 100644 docs-src/tutorial/closures.md delete mode 100644 docs-src/tutorial/cross-linux-arch.md delete mode 100644 docs-src/tutorial/cross.md delete mode 100644 docs-src/tutorial/gir_tutorial.md delete mode 100644 docs-src/tutorial/glade.md delete mode 100644 docs-src/tutorial/gnome_and_rust.md delete mode 100644 docs-src/tutorial/index.md delete mode 100644 docs-src/tutorial/object_oriented.md delete mode 100644 docs-src/tutorial/rust_and_gtk.md delete mode 100644 docs-src/tutorial/version.md delete mode 100644 docs-src/useful-links.md rename docs-src/faq.md => faq.md (60%) create mode 100644 images/gtk-rs.png diff --git a/_config.yml b/_config.yml index 885c0454b..923d2e2b9 100644 --- a/_config.yml +++ b/_config.yml @@ -1,5 +1,5 @@ # Site settings -title: Gtk-rs +title: GTK-rs description: > # this means to ignore newlines until "baseurl:" Rust bindings for GTK and GLib-based libraries baseurl: "" # the subpath of your site, e.g. /blog/ diff --git a/_data/crates.json b/_data/crates.json index 2c7c1dc18..cc6afe9b5 100644 --- a/_data/crates.json +++ b/_data/crates.json @@ -1,38 +1,38 @@ [ { + "section": "Core", + "name": "cairo-rs", - "max_version": "0.9.0" - }, - { - "name": "gdk", - "max_version": "0.13.0" - }, - { - "name": "gdk-pixbuf", - "max_version": "0.9.0" - }, - { - "name": "gdk-x11", - "max_version": "0.9.0" + "max_version": "0.14.0", + "repo": "gtk-rs-core" }, { "name": "gio", - "max_version": "0.9.0" + "max_version": "0.14.0", + "repo": "gtk-rs-core" }, { "name": "glib", - "max_version": "0.10.0" + "max_version": "0.14.0", + "repo": "gtk-rs-core" }, { - "name": "gtk", - "max_version": "0.9.0" + "name": "pango", + "max_version": "0.14.0", + "repo": "gtk-rs-core" }, { - "name": "pango", - "max_version": "0.9.0" + "section": "GTK 3", + + "name": "gtk", + "max_version": "0.14.0", + "repo": "gtk3-rs" }, { - "name": "sourceview", - "max_version": "0.9.0" + "section": "GTK 4", + + "name": "gtk4", + "max_version": "0.1.0", + "repo": "gtk4-rs" } ] diff --git a/_includes/badges.html b/_includes/badges.html deleted file mode 100644 index d1f5d1fa5..000000000 --- a/_includes/badges.html +++ /dev/null @@ -1,24 +0,0 @@ -{% for crate in site.data.crates %} - - - - - - - - - - - - - - {{crate.name}} - {{crate.name}} - v{{crate.max_version}} - v{{crate.max_version}} - - - - -{% endfor %} diff --git a/_includes/book.svg b/_includes/book.svg new file mode 100644 index 000000000..ae329aab7 --- /dev/null +++ b/_includes/book.svg @@ -0,0 +1,13 @@ + + + + + + image/svg+xml + + + + + + + diff --git a/_includes/crates.html b/_includes/crates.html new file mode 100644 index 000000000..9eae8d927 --- /dev/null +++ b/_includes/crates.html @@ -0,0 +1,25 @@ + + + + + +{% for crate in site.data.crates %} + + + + + + +{% endfor %} + +
ProjectCrateDocs
+ {{crate.section}} + + + {{crate.name}} + + + v{{crate.max_version}} + + 🕮 +
diff --git a/_includes/footer.html b/_includes/footer.html index 8424c687c..2bcdfde55 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -1,53 +1,18 @@ diff --git a/_includes/header.html b/_includes/header.html index d2b90f08e..b5dcc9045 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -1,9 +1,7 @@ diff --git a/_includes/projects.md b/_includes/projects.md new file mode 100644 index 000000000..be68bee06 --- /dev/null +++ b/_includes/projects.md @@ -0,0 +1,43 @@ +* [Banner Viewer](https://gitlab.gnome.org/World/design/banner-viewer) +* [BrewStillery](https://gitlab.com/MonkeyLog/BrewStillery) +* [Cigale](https://github.com/emmanueltouzery/cigale) +* [color_blinder_gtk](https://gitlab.com/dns2utf8/color_blinder_gtk) +* [Contrast](https://gitlab.gnome.org/World/design/contrast) +* [Cookbook](https://github.com/MacKarp/Cookbook) +* [Czkawka](https://github.com/qarmin/czkawka) +* [Epicwar Downloader](https://github.com/ab0v3g4me/epicwar-downloader) +* [Font Finder](https://github.com/mmstick/fontfinder) +* [Fractal](https://gitlab.gnome.org/GNOME/fractal) +* [Garta](https://github.com/zaari/garta) +* [Gattii](https://gitlab.com/susurrus/gattii) +* [GNvim](https://github.com/vhakulinen/gnvim) +* [gled](https://gitlab.com/pentagonum/gled) +* [glide](https://github.com/philn/glide) +* [gpsami](https://gitlab.gnome.org/hub/gpsami) +* [gtktranslate](https://github.com/skylinecc/gtktranslate) +* [Icon Library](https://gitlab.gnome.org/World/design/icon-library) +* [Iridium](https://github.com/matze/iridium) +* [lognplot](https://github.com/windelbouwman/lognplot) +* [Marmoset](https://github.com/sprang/marmoset) +* [mcmmtk](https://github.com/pwil3058/mcmmtk) +* [media-toc](https://github.com/fengalin/media-toc) +* [Myxer](https://github.com/Aurailus/Myxer) +* [neovim-gtk](https://github.com/daa84/neovim-gtk) +* [noaa-apt](https://github.com/martinber/noaa-apt) +* [pcatk](https://github.com/pwil3058/pcatk) +* [Pika Backup](https://gitlab.gnome.org/World/pika-backup) +* [PNMixer-rs](https://github.com/hasufell/pnmixer-rust) +* [Podcasts](https://gitlab.gnome.org/World/podcasts) +* [Popsicle](https://github.com/pop-os/popsicle/) +* [process-viewer](https://github.com/GuillaumeGomez/process-viewer) +* [Projectpad](https://github.com/emmanueltouzery/projectpad2) +* [relm](https://github.com/antoyo/relm) +* [rrun](https://github.com/buster/rrun) +* [Shortwave](https://gitlab.gnome.org/World/Shortwave) +* [Social](https://gitlab.gnome.org/World/Social) +* [SolidOak](https://github.com/oakes/SolidOak) +* [systemd-manager](https://gitlab.com/mmstick/systemd-manager) +* [Tau](https://gitlab.gnome.org/World/Tau) +* [tv-renamer](https://github.com/mmstick/tv-renamer) +* [Whatschanging](https://github.com/mothsART/whatschanging) + diff --git a/_layouts/wide.html b/_layouts/no-wrapper.html similarity index 67% rename from _layouts/wide.html rename to _layouts/no-wrapper.html index c511bb511..27ab0b0cc 100644 --- a/_layouts/wide.html +++ b/_layouts/no-wrapper.html @@ -7,10 +7,8 @@ {% include header.html %} -
-
+
{{ content }} -
{% include footer.html %} diff --git a/_sass/_base.scss b/_sass/_base.scss index 42c286e03..66d9c0653 100644 --- a/_sass/_base.scss +++ b/_sass/_base.scss @@ -83,27 +83,60 @@ li { } +table { + margin: 1em auto; + border-collapse: collapse; + + td, th { + border: none; + padding: 0.3em 0.7em; + } + + .section { + font-weight: bold; + text-align: right; + } + + th { + border-bottom: 1px solid $text-color; + } +} /** * Headings */ h1, h2, h3, h4, h5, h6 { - font-weight: 300; + font-weight: 600; + font-family: $headings-font-family; + color: $headings-color; +} + +h1, h2 { + margin-bottom: 0.4em; } +h1 { + font-size: 34px; + text-align: center; + margin-top: 0.4em; +} +h2 { + font-size: 26px; + margin-top: 1.2em; +} + +h3, h4 { + margin-top: 1em; +} /** * Links */ -a { +.page-content a { color: $brand-color; text-decoration: none; - &:visited { - color: darken($brand-color, 15%); - } - &:hover { color: $text-color; text-decoration: underline; @@ -114,6 +147,17 @@ a.badge { text-decoration: none; } +td.docs { + text-align: center; + + a:hover { + text-decoration: none; + transform: scale(1.3); + transition-property: transform; + transition: 0.2s; + display: inline-block; + } +} /** @@ -137,58 +181,52 @@ blockquote { /** * Code formatting */ -pre, -code { +pre { font-size: 15px; - border: 1px solid $grey-color-light; - border-radius: 3px; - background-color: #eef; -} - -code { - padding: 1px 5px; -} + border: none; + border-radius: 5px; + background: $box-background; + color: white; -pre { - padding: 8px 12px; + margin: 1em; + padding: 1em; overflow-x: auto; - > code { - border: 0; - padding-right: 0; - padding-left: 0; + pre, code { + background: none; + border: none; + padding: 0; + color: inherit; + font-weight: inherit; + font-size: inherit; } } - +code { + font-weight: bold; + color: darken($text-color, 20%); + font-size: 0.85em; +} /** * Wrapper */ .wrapper { - max-width: calc(800px - (#{$spacing-unit} * 2)); - margin-right: auto; - margin-left: auto; - padding-right: $spacing-unit; - padding-left: $spacing-unit; - @extend %clearfix; - border-radius: 5px; - background-color: $elem-background; + padding-left: calc(50vw - 400px); + padding-right: calc(50vw - 400px); @include media-query($on-laptop) { - max-width: calc(800px - (#{$spacing-unit})); padding-right: $spacing-unit / 2; padding-left: $spacing-unit / 2; } } -.wide-wrapper { - max-width: calc(1000px - (#{$spacing-unit} * 2)); - padding-top: 10px; +section { + padding-top: 0.1rem; + padding-bottom: 2rem; + @extend .wrapper; } - - /** * Clearfix */ diff --git a/_sass/_layout.scss b/_sass/_layout.scss index 183c51fd6..1334fd26d 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -2,85 +2,83 @@ * Site header */ .site-header { - border-top: 5px solid $grey-color-dark; - border-bottom: 1px solid $grey-color-light; - // Positioning context for the mobile navigation icon position: relative; - background-color: $elem-background; + background: linear-gradient(120deg, $header-color-1, $header-color-2, lighten($header-color-1, 2%), $header-color-1); + font-family: $headings-font-family; } .site-title { - font-size: 26px; - line-height: $header-line-height; - letter-spacing: -1px; - margin-bottom: 0; - float: left; + font-size: 40px; + font-weight: 800; - &, - &:visited { - color: $grey-color-dark; - } -} + margin: 2.5rem 1.5rem; + display: inline-block; -#support-button { - position: absolute; - right: 6px; - top: 11px; - border-radius: 7px; - background-color: #fff; - padding: 4px; - text-decoration: none; - width: initial; - color: #000; - cursor: pointer; - border: 1px solid #ddd; + background-size: contain; + background-repeat: no-repeat; + padding-left: 120px; + line-height: 100px; + + transition: 0.2s; + transition-property: transform, opacity; + + background-image: url('../images/gtk-rs.png'); &:hover { - background-color: #e3ffff; + opacity: 0.9; } - > svg { - fill: #ff0b9e; - vertical-align: middle; - font-size: 12px; - line-height: 20px; + &:active { + transform: scale(1.05); } } -@include media-query($title-on-palm) { - #support-button { - right: 85px; - } +.site-header a { + color: $header-text-color; + text-decoration: none; } .site-nav { float: right; - line-height: 56px; + + .trigger { + display: flex; + justify-content: flex-end; + margin-right: 1.5rem; + } .menu-icon { display: none; } .page-link { - color: $text-color; - line-height: $base-line-height; + color: $header-text-color; + line-height: 3em; + margin: 0 1rem; + font-weight: bold; + transition: 0.3s; + transition-property: color; + border-radius: 7px; + } - // Gaps between nav items, but not on the first one - &:not(:first-child) { - margin-left: 20px; - } + .page-link:hover { + color: white; } - @include media-query($title-on-palm) { + @include media-query($on-laptop) { position: absolute; - top: 9px; - right: 30px; - background-color: $background-color; - border: 1px solid $grey-color-light; + top: 1.5em; + right: 1.5em; + border: 1px solid white; border-radius: 5px; - text-align: right; - z-index: 1; // to go over the "support us" button + background: $box-background; + + .page-link { + float: none; + display: block; + padding: 0 1.5em; + } .menu-icon { display: block; @@ -96,7 +94,7 @@ height: 15px; path { - fill: $grey-color-dark; + fill: white; } } } @@ -110,11 +108,6 @@ display: block; padding-bottom: 5px; } - - .page-link { - display: block; - padding: 5px 10px; - } } } @@ -124,123 +117,77 @@ * Site footer */ .site-footer { - border-top: 1px solid $grey-color-light; - padding-top: 12px; - background-color: $elem-background; -} - -.footer-heading { - font-size: 18px; - margin-bottom: $spacing-unit / 2; -} - -.contact-list, -.social-media-list { - list-style: none; - margin-left: 0; -} - -.intro-col-wrapper { - margin-left: -$spacing-unit / 2; - @extend %clearfix; -} - -.intro-col { - float: left; - margin-bottom: $spacing-unit / 2; - padding-left: $spacing-unit / 2; -} - -.intro-col-1 { - width: calc(60% - (#{$spacing-unit} / 2)); -} - -.intro-col-2 { - width: calc(40% - (#{$spacing-unit} / 2)); -} - -@include media-query($on-laptop) { - .intro-col { - float: none; - width: calc(100% - (#{$spacing-unit} / 2)); + margin-top: 1em; + background: $box-background; + color: white; + font-family: $headings-font-family; + font-weight: bold; + font-size: 0.95em; + + .wrapper { + padding-top: 1.7em; + padding-bottom: 1.7em; + display: flex; + flex-wrap: wrap; + justify-content: space-around; + align-items: center; } -} -.footer-col-wrapper { - font-size: 15px; - color: $grey-color; - margin-left: -$spacing-unit / 2; - @extend %clearfix; -} - -.footer-col { - float: left; - padding-left: $spacing-unit / 2; -} - -.footer-col-1 { - width: calc(35% - (#{$spacing-unit} / 2)); -} - -.footer-col-2 { - width: calc(20% - (#{$spacing-unit} / 2)); -} + svg { + width: 1.2em; + margin-right: 0.6em; + display: inline-block; + path { + fill: white; + } + } -.footer-col-3 { - width: calc(45% - (#{$spacing-unit} / 2)); -} + a { + color: white; + text-decoration: none; + line-height: 2em; + display: flex; -@include media-query($on-laptop) { - .footer-col-1, - .footer-col-2 { - width: calc(50% - (#{$spacing-unit} / 2)); - } + &:hover { + color: #CCC; - .footer-col-3 { - width: calc(100% - (#{$spacing-unit} / 2)); + svg { + path { + fill: #CCC; + } + } + } } - .page-content { - /* 88px is the footer size */ - min-height: calc(100vh - #{$header-line-height} - #{$header-borders} - (#{$content-padding} * 2) - 88px); + li { + list-style: none; } -} -@include media-query($on-palm) { - .footer-col { - float: none; - width: calc(100% - (#{$spacing-unit} / 2)); + .wrapper > div { + font-size: 0.8em; + line-height: 0; } - .page-content { - /* 126px is the footer size */ - min-height: calc(100vh - #{$header-line-height} - #{$header-borders} - (#{$content-padding} * 2) - 126px); + img { + height: 5em; + width: auto; + margin-left: auto; + display: block; + padding-top: 1em; } } - - /** * Page content */ -.page-content { - padding: $content-padding 0; - /* 51px is the footer size */ - min-height: calc(100vh - #{$header-line-height} - #{$header-borders} - (#{$content-padding} * 2) - 51px); -} -@include media-query($on-laptop) { - .page-content { - /* 88px is the footer size */ - min-height: calc(100vh - #{$header-line-height} - #{$header-borders} - (#{$content-padding} * 2) - 88px); - } +section.special { + background: #deddda; } -@include media-query($on-palm) { - .page-content { - /* 126px is the footer size */ - min-height: calc(100vh - #{$header-line-height} - #{$header-borders} - (#{$content-padding} * 2) - 126px); - } +.page-content { + padding: $content-padding 0; + min-height: calc(100vh - 300px); } .page-heading { @@ -256,18 +203,46 @@ } } +.post-overview { + text-align: center; + padding: 0.7rem 0; + + a, a:visited { + @extend .box-design; + max-width: 10em; + padding: 0.5em; + margin: 1.5em 1em 0; + line-height: 3em; + vertical-align: top; + min-height: 7em; + + .post-meta { + color: #f6f5f4; + font-weight: 800; + font-family: $headings-font-family; + } + + * { + display: inline-block; + line-height: 1em; + } + } +} + .post-meta { font-size: $small-font-size; - color: $grey-color; + font-family: $headings-font-family; + font-weight: bold; + text-align: center; } .post-link { + font-family: $headings-font-family; + font-weight: bold; display: block; - font-size: 24px; + font-size: 20px; } - - /** * Posts */ @@ -285,88 +260,135 @@ } } -.post-content { - margin-bottom: $spacing-unit; +/** + * Special + */ - h2 { - font-size: 32px; +.box-design { + transition: 0.5s; + transition-property: opacity; + background: $box-background; + border-radius: 7px; + color: white; + display: inline-block; - @include media-query($on-laptop) { - font-size: 28px; - } + &:hover { + text-decoration: none; + opacity: 0.9; + color: white; + transition: 0.2s; } +} - h3 { - font-size: 26px; +.no-wrapper h2 { + text-align: center; + padding-bottom: 0.1em; +} - @include media-query($on-laptop) { - font-size: 22px; - } +.badgets { + text-align: center; + margin-top: 1.5rem; + img { + border-radius: 5px; } +} - h4 { - font-size: 20px; +.with-logo { + display: flex; + flex-wrap: wrap; - @include media-query($on-laptop) { - font-size: 18px; + svg { + flex-shrink: 0; + flex-basis: 7em; + margin: 0.3em 0.7em 0.5em 0; + height: 120px; + + path { + fill: $text-color; } } -} -.blog, .crates, .sponsors { - border-radius: 5px; - padding: 7px; + div { + flex-basis: 10em; flex-shrink: 1; flex-grow: 1; + } } -.crates, .sponsors { - margin-bottom: 7px; -} +.sponsor-tiers { + display: inline-block; + margin: 1em; + font-family: $headings-font-family; -.crates { - background-color: #E6F5F9; -} + a { + @extend .box-design; + max-width: 10em; + text-align: center; + text-decoration: none; + vertical-align: top; + min-height: 8em; + font-weight: bold; -.sponsors { - text-align: center; - background-color: #fff0de; + > * { + padding: 1em; + display: block; + } - > div { - display: inline-flex; + > *:first-child { + padding-bottom: 0; + } - > svg { - height: 25px; + img { + border-radius: 50%; + width: 5em; + margin: auto; + border: 3px solid white; } - } -} -.blog { - background-color: #F7F5D7; -} + .metal { + border-radius: inherit; + border-top-left-radius: 0; + border-top-right-radius: 0; + } -.thanks-sponsors { - padding-top: 15px; - font-size: 20px; - padding-bottom: 25px; + .gold { + background: linear-gradient(0deg, #cb7401, #ecd56f); + color: darken(#cb7401, 20%); + } + + .bronze { + background: linear-gradient(0deg, #b37a4f, #f5caa7); + color: darken(#b37a4f, 20%); + } + } } -.sponsor-tiers { - margin-bottom: 20px; +.projects-overview { + padding-top: 0.5em; - > a { - display: block; - max-width: 75px; + ul { text-align: center; - border: 1px solid #ccc; - border-radius: 4px; - padding: 5px; - text-decoration: none; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + } - > img { - border-radius: 50%; - } + li { + list-style: none; + display: inline-block; + flex-grow: 1; + } - &:hover { - background-color: #e5f4ff; - } + + a, a:visited { + @extend .box-design; + font-family: $headings-font-family; + font-weight: 600; + + padding: 0 0.8em; + margin: 0.15em 0.3em; + line-height: 3em; + vertical-align: center; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } } diff --git a/_sass/_syntax-highlighting.scss b/_sass/_syntax-highlighting.scss index 4fb4239fa..5fc59c3fd 100644 --- a/_sass/_syntax-highlighting.scss +++ b/_sass/_syntax-highlighting.scss @@ -20,7 +20,7 @@ .gi { color: #000; background-color: #dfd } // Generic.Inserted .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific .go { color: #888 } // Generic.Output - .gp { color: #555 } // Generic.Prompt + .gp { color: #ffa348 } // Generic.Prompt .gs { font-weight: bold } // Generic.Strong .gu { color: #aaa } // Generic.Subheading .gt { color: #a00 } // Generic.Traceback @@ -29,38 +29,38 @@ .kp { font-weight: bold } // Keyword.Pseudo .kr { font-weight: bold } // Keyword.Reserved .kt { color: #458; font-weight: bold } // Keyword.Type - .m { color: #099 } // Literal.Number - .s { color: #d14 } // Literal.String + .m { color: #33d17a } // Literal.Number + .s { color: #99c1f1 } // Literal.String .na { color: #008080 } // Name.Attribute .nb { color: #0086B3 } // Name.Builtin .nc { color: #458; font-weight: bold } // Name.Class .no { color: #008080 } // Name.Constant .ni { color: #800080 } // Name.Entity - .ne { color: #900; font-weight: bold } // Name.Exception - .nf { color: #900; font-weight: bold } // Name.Function - .nn { color: #555 } // Name.Namespace - .nt { color: #000080 } // Name.Tag + .ne { color: #ed333b; font-weight: bold } // Name.Exception + .nf { color: #ed333b; } // Name.Function + .nn { color: #ffa348; } // Name.Namespace + .nt { color: #f66151 } // Name.Tag .nv { color: #008080 } // Name.Variable .ow { font-weight: bold } // Operator.Word .w { color: #bbb } // Text.Whitespace - .mf { color: #099 } // Literal.Number.Float - .mh { color: #099 } // Literal.Number.Hex - .mi { color: #099 } // Literal.Number.Integer - .mo { color: #099 } // Literal.Number.Oct - .sb { color: #d14 } // Literal.String.Backtick - .sc { color: #d14 } // Literal.String.Char - .sd { color: #d14 } // Literal.String.Doc - .s2 { color: #d14 } // Literal.String.Double - .se { color: #d14 } // Literal.String.Escape - .sh { color: #d14 } // Literal.String.Heredoc - .si { color: #d14 } // Literal.String.Interpol - .sx { color: #d14 } // Literal.String.Other + .mf { color: #33d17a } // Literal.Number.Float + .mh { color: #33d17a } // Literal.Number.Hex + .mi { color: #33d17a } // Literal.Number.Integer + .mo { color: #33d17a } // Literal.Number.Oct + .sb { color: #99c1f1 } // Literal.String.Backtick + .sc { color: #99c1f1 } // Literal.String.Char + .sd { color: #99c1f1 } // Literal.String.Doc + .s2 { color: #99c1f1 } // Literal.String.Double + .se { color: #99c1f1 } // Literal.String.Escape + .sh { color: #99c1f1 } // Literal.String.Heredoc + .si { color: #99c1f1 } // Literal.String.Interpol + .sx { color: #99c1f1 } // Literal.String.Other .sr { color: #009926 } // Literal.String.Regex - .s1 { color: #d14 } // Literal.String.Single + .s1 { color: #99c1f1 } // Literal.String.Single .ss { color: #990073 } // Literal.String.Symbol .bp { color: #999 } // Name.Builtin.Pseudo .vc { color: #008080 } // Name.Variable.Class .vg { color: #008080 } // Name.Variable.Global .vi { color: #008080 } // Name.Variable.Instance - .il { color: #099 } // Literal.Number.Integer.Long + .il { color: #33d17a } // Literal.Number.Integer.Long } diff --git a/_sass/_variables.scss b/_sass/_variables.scss new file mode 100644 index 000000000..7150c9eba --- /dev/null +++ b/_sass/_variables.scss @@ -0,0 +1,43 @@ +// Our variables +$base-font-family: Helvetica, Arial, sans-serif; +$base-font-size: 17px; +$small-font-size: $base-font-size * 0.875; +$base-line-height: 1.3; + +$headings-font-family: Cantarell, Helvetica, Arial, sans-serif; +$headings-color: #3d3846; + +$spacing-unit: 25px; + +$text-color: #3d3846; +$background-color: #f6f5f4; +$brand-color: #813d9c; + +$grey-color: #828282; +$grey-color-light: lighten($grey-color, 40%); + +$on-palm: 675px; +$on-laptop: 820px; + +$header-borders: 6px; +$header-line-height: 56px; +$content-padding: 10px; + +$header-color-1: #241f31; +$header-color-2: #3d3846; +$header-text-color: #dc8add; + +$box-background: linear-gradient(150deg, #241f31, #3d3846); + +// Using media queries with like this: +// @include media-query($palm) { +// .wrapper { +// padding-right: $spacing-unit / 2; +// padding-left: $spacing-unit / 2; +// } +// } +@mixin media-query($device) { + @media screen and (max-width: $device) { + @content; + } +} diff --git a/blog/index.html b/blog/index.html index 543677cb5..bd8d3e123 100644 --- a/blog/index.html +++ b/blog/index.html @@ -3,9 +3,7 @@ title: Blog --- - diff --git a/contact.md b/contact.md new file mode 100644 index 000000000..e755ad735 --- /dev/null +++ b/contact.md @@ -0,0 +1,14 @@ +--- +layout: default +--- + +# Contact + +For general support use the GNOME Discourse or the Matrix chat. + +- GNOME Discourse **[discourse.gnome.org](https://discourse.gnome.org)** +- Matrix channel **[#rust:gnome.org](https://matrix.to/#/#rust:gnome.org)** + +### Contact Gtk-rs developers + +If you want to contact the Gtk-rs developers directly, there are multiple ways, either you can go on matrix as shown above or you can also just open an issue on our [repositories on GitHub](https://github.com/gtk-rs). However, please keep in mind that issues on GitHub should be used for bug reports or feature requests and not for general support. diff --git a/css/main.scss b/css/main.scss index e09996d1d..dfb82f39d 100755 --- a/css/main.scss +++ b/css/main.scss @@ -1,81 +1,12 @@ --- -# Only the main Sass file needs front matter (the dashes are enough) --- @charset "utf-8"; - - -// Our variables -$base-font-family: Helvetica, Arial, sans-serif; -$base-font-size: 16px; -$small-font-size: $base-font-size * 0.875; -$base-line-height: 1.5; - -$spacing-unit: 30px; - -$text-color: #111; -$background-color: #fdfdfd; -$brand-color: #2a7ae2; -$elem-background: #f7f7f7; - -$grey-color: #828282; -$grey-color-light: lighten($grey-color, 40%); -$grey-color-dark: darken($grey-color, 25%); - -$on-palm: 675px; -$title-on-palm: 1064px; -$on-laptop: 800px; - -$header-borders: 6px; -$header-line-height: 56px; -$content-padding: 10px; - -// Using media queries with like this: -// @include media-query($palm) { -// .wrapper { -// padding-right: $spacing-unit / 2; -// padding-left: $spacing-unit / 2; -// } -// } -@mixin media-query($device) { - @media screen and (max-width: $device) { - @content; - } -} - - - // Import partials from `sass_dir` (defaults to `_sass`) @import + "variables", "base", "layout", "syntax-highlighting" ; -div.footer { - width:100%; - padding-top: 10px; - min-height: 25px; - margin-bottom: 8px; -} - -div.footer > div { - float: left; - margin: 0; - width: 33.3%; - text-align: center; - min-height: 5px; -} - -table { - width: 100%; - text-align: left; - border-collapse: collapse; -} -th { - text-align: center; -} -th, td { - border: 1px solid #ddd; - padding: 2px 8px; -} diff --git a/docs-src/contact.md b/docs-src/contact.md deleted file mode 100644 index 492ec3a12..000000000 --- a/docs-src/contact.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -layout: default ---- - -For general support use the GNOME Discourse or IRC/Matrix. - -## Discourse - -[discourse.gnome.org](https://discourse.gnome.org). - -## Matrix - -You can connect using: **[#rust:gnome.org][]**. - -[#rust:gnome.org]: https://matrix.to/#/#rust:gnome.org - -# Contact Gtk-rs developers - -However, if you want to contact the `Gtk-rs` developers directly, there are multiple ways, either you can go on matrix as shown above or you can also just open an issue on our [repositories](https://github.com/gtk-rs) on github. However, please keep in mind that issues on `gtk-rs` should be for bug reports or feature requests and not general support. diff --git a/docs-src/index.md b/docs-src/index.md deleted file mode 100644 index 26224bca0..000000000 --- a/docs-src/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -layout: default ---- -# Gtk-rs documentation - -## Requirements - -First, prepare your system by taking a look at the [GTK installation page](https://www.gtk.org/docs/installations/). - -## Crate API docs - - - [**atk**](../docs/atk/) - - [**cairo**](../docs/cairo/) - - [**gdk**](../docs/gdk/) - - [**gdk-pixbuf**](../docs/gdk_pixbuf/) - - [**gdk-x11**](../docs/gdkx11/) - - [**gio**](../docs/gio/) - - [**glib**](../docs/glib/) - - [**glib-macros**](../docs/glib_macros/) - - [**gtk**](../docs/gtk/) - - [**pango**](../docs/pango/) - - [**pangocairo**](../docs/pangocairo/) - - [**sourceview**](../docs/sourceview/) - -## [The GTK Project documentation](https://www.gtk.org/docs/) - -## Versions - -By default the `gtk` crate provides only GTK 3.14 APIs. You can access more -modern APIs by selecting one of the following features: `v3_16`, `v3_18`, `v3_20`, `v3_22`, `v3_24`, `v3_26`, `v3_28`, `v3_30`. - -`Cargo.toml` example: - -~~~toml -[dependencies.gtk] -version = "{{ gtk[0].max_version }}" -features = ["v3_16"] -~~~ - -**Take care when choosing the version to target: some of your users might -not have easy access to the latest ones.** The higher the version, the fewer -users will have it installed. - -## Tutorials and examples - - * [Tutorials](/docs-src/tutorial). - * [Examples directory in the `gtk-rs` repository](https://github.com/gtk-rs/gtk-rs). - * [Projects using `gtk-rs`](/#projects-using-gtk-rs). diff --git a/docs-src/sponsors.md b/docs-src/sponsors.md deleted file mode 100644 index 4add4bb89..000000000 --- a/docs-src/sponsors.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -layout: default ---- - -

Thanks to everyone supporting us on opencollective!

- -## Platinum tier - -No sponsors in this tier yet. - -## Gold tier - - - -## Silver tier - -No sponsors in this tier yet. - -## Bronze tier - - - -## Other sponsors - -Other sponsors can be seen on our [opencollective][opencollective] page. - -[opencollective]: https://opencollective.com/gtk-rs diff --git a/docs-src/tutorial/closures.md b/docs-src/tutorial/closures.md deleted file mode 100644 index 35b6d1ec2..000000000 --- a/docs-src/tutorial/closures.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -layout: default ---- - -# Callbacks and closures - -It's very common in GUI libraries to have callbacks (or equivalent) in order to perform an action when a specific event happens. Let's see how you can do it with `Gtk-rs`. - -## Closures! - -Closures, unlike functions-pointer, keep their environment, which is very useful to not have to send any argument you need into it. However, a closure's lifetime is difficult to track. In `Gtk-rs`, it requires a `static` lifetime to be **_sure_** that any objects captured by the closure will still be alive, whatever the moment the closure is invoked. - -Now that you have all information, let's take a look to an example: - -In C, youll write: - -```C -#include - -void callback_clicked(GtkWidget *widget, gpointer data) { - gtk_button_set_label(GTK_BUTTON(widget), "Window"); -} - -GtkWidget *button = gtk_button_new_with_label("Click me!"); -g_signal_connect(button, "clicked", G_CALLBACK(callback_clicked), NULL); -``` - -It now becomes: - -```rust -use gtk::{Button, ButtonExt}; - -let button = Button::with_label("Click me!"); -button.connect_clicked(|but| { - but.set_label("I've been clicked!"); -}); -``` - -As simple as that! Now comes the less funny part. Let's say you want to update another widget when the button is clicked and use it after: - -```rust -use gtk::{Box, Button, ButtonExt, ContainerExt, WidgetExt}; - -// First we create a layout. -let container = Box::new(gtk::Orientation::Vertical, 5); -// the label which will be modified inside the closure. -let label = gtk::Label::new(""); -let button = Button::with_label("Click me!"); -button.connect_clicked(move |_| { - label.set_label("Button has been clicked!"); -}); - -container.add(&button); -container.add(&label); -``` - -If you try to compile this code, you'll get the following error: - -``` -error[E0382]: use of moved value: `label` -``` - -To make it work, just clone label before sending it into the closure: - -```rust -use gtk::{Box, Button, ButtonExt, ContainerExt, WidgetExt}; - -// First we create a layout. -let container = Box::new(gtk::Orientation::Vertical, 5); -// the label which will be modified inside the closure. -let label = gtk::Label::new(""); -let button = Button::with_label("Click me!"); -// We clone label so we can send it into the closure. -let label_clone = label.clone(); -button.connect_clicked(move |_| { - label_clone.set_label("Button has been clicked!"); -}); - -container.add(&button); -container.add(&label); -``` - -Now it works, as simple as that! Remember: cloning a `Gtk-rs` object only costs a pointer copy, so it's not a problem. - -## Using non-`Gtk-rs` object into a `Gtk-rs` closure - -That's where things get a bit more complicated. Let's say you want to write a multi-window program and want to keep track of your windows so you can access them from multiple closures. - -One way to do it is using [`Rc`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html) and [`RefCell`](https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html) structs from Rust standard library. Now let's see this into action in a short example: - -```rust -use gtk::{Button, ButtonExt, Window}; - -use std::cell::RefCell; -use std::collections::HashMap; -use std::rc::Rc; - -let windows: Rc>> = Rc::new(RefCell::new(HashMap::new())); -let button = Button::with_label("Click me!"); -// We copy the reference to the cell containing the hashmap. -let windows_clone = windows.clone(); -button.connect_clicked(move |_| { - // create_window functions creates a window and return the following tuple: (usize, Window). - let (window_id, window) = create_window(); - windows_clone.borrow_mut().unwrap().insert(window_id, window); -}); - - ... - -another_button.connect_clicked(move |_| { - let id_to_remove = get_id_to_remove(); - windows.borrow_mut().unwrap().remove(&id_to_remove); -}); -``` - -A bit annoying to write. To give a simple explanation on how `Rc>` works: - - * [`Rc`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html) is just a reference counter, so it keeps count of the number of instances of the object it holds and then drop it and there is no more reference. - * [`RefCell`](https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html) is a bit more complicated. It allows to make an object mutable when/where it shouldn't. For more information, take a look at its documentation. - -However, a macro can make your life a bit easier to do this (you can take a look at the code but it's not mandatory to understand how it works): - -```rust -macro_rules! clone { - (@param _) => ( _ ); - (@param $x:ident) => ( $x ); - ($($n:ident),+ => move || $body:expr) => ( - { - $( let $n = $n.clone(); )+ - move || $body - } - ); - ($($n:ident),+ => move |$($p:tt),+| $body:expr) => ( - { - $( let $n = $n.clone(); )+ - move |$(clone!(@param $p),)+| $body - } - ); -} -``` - -And then you can use it as follow: - -```rust -let windows: Rc>> = Rc::new(RefCell::new(HashMap::new())); -button.connect_clicked(clone!(windows => move |_| { - let (window_id, window) = create_window(); - windows.borrow_mut().unwrap().insert(window_id, window); -})); -``` - - diff --git a/docs-src/tutorial/cross-linux-arch.md b/docs-src/tutorial/cross-linux-arch.md deleted file mode 100644 index d978d4a7e..000000000 --- a/docs-src/tutorial/cross-linux-arch.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -layout: default ---- - -# Crosscompiling on Linux - -It's a good idea to test your application on arches other than what you have (usually x86_64), e.g. to ensure what your application also works on ARMv7/AArch64, which is used in some portable devices (e.g. the Librem phone). -This guide assumes that you use Debian/Ubuntu for your CI work, as it's somewhat simple to get crosscompiling working on these. - -First we have to add the architecture we want to crosscompile to. Refer to [Debian's supported architectures page](https://wiki.debian.org/SupportedArchitectures) to see supported architectures. - -~~~bash -> sudo dpkg --add-architecture armhf -~~~ - -This will install some base packages for `armhf`. Replace `armhf` with whatever arch you want to test (and be mindful to also replace it in the following commands!). - -Next we have to install `gcc` for that arch to act as linker for Rust and `libgtk-3-dev` which we need to link our application against. We also need to install pkg-config in order for our build process to be able to discover gtk3. - -~~~bash -> sudo apt-get install -y gcc-arm-linux-gnueabihf -> sudo apt-get install -y libgtk-3-dev:armhf -> sudo apt-get install pkg-config -~~~ - -Next up we have to add support for our target to Rust. Assuming you're using rustup it's as easy as: - -~~~bash -> rustup target add armv7-unknown-linux-gnueabihf -~~~ - -Following that we have to set some environment variables: - -~~~bash -> export PKG_CONFIG_ALLOW_CROSS=1 PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig/ CARGO_BUILD_TARGET=armv7-unkown-linux-gnueabihf CARGO_TARGET_ARMV7_UNKOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc -~~~ - -the first two environment variables set the location of our `pkg-config` binary and allow crosscompiling with it. The third one sets what Rust target we're building for. The triplet has to match the one you've added previously with `rustup target add ...`. Finally, we have to set the linker for our crosstarget. Note that you can also set this in cargo's config file, but at least for CI work it's more convinient to work with environment variables. Refer to [cargo's documentation](https://doc.rust-lang.org/cargo/reference/config.html) for more info on that. - -We're now all setup! Now it should be as easy as running `cargo build` to build your application. diff --git a/docs-src/tutorial/cross.md b/docs-src/tutorial/cross.md deleted file mode 100644 index a1c013295..000000000 --- a/docs-src/tutorial/cross.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -layout: default ---- - -# Preparing rust - -First install Rust normally with rustup. The next step will install the Windows toolchain. - - rustup target add x86_64-pc-windows-gnu - -Then set up the target in `~/.cargo/config`. - - [target.x86_64-pc-windows-gnu] - linker = "x86_64-w64-mingw32-gcc" - ar = "x86_64-w64-mingw32-gcc-ar" - -## Mingw and GTK installation - -### Arch Linux - -The mingw packages are in the AUR, you can either install manually or use a helper. These instructions use the pacaur helper. The packages take a while to compile. - - pacaur -S mingw-w64-gcc mingw-w64-freetype2-bootstrap mingw-w64-cairo-bootstrap - pacaur -S mingw-w64-harfbuzz - pacaur -S mingw-w64-pango - pacaur -S mingw-w64-poppler - pacaur -S mingw-w64-gtk3 - -### Fedora - -Fedora provides pre-compiled Mingw and GTK packages through its repositories. Both 64 and 32 bits are available (`mingw64-*` vs `mingw32-*`), of which you probably want the 64 bits packages. - - dnf install mingw64-gcc mingw64-pango mingw64-poppler mingw64-gtk3 mingw64-winpthreads-static - -### openSUSE - -### Be advised that the windows:mingw:win64 project only provides mingw64-gtk3 at version 3.22-15, you will only be able to compile programs requiring GTK features v3_22-15 and lower. - -openSUSE is similar to fedora with differences on the packages to install - -## Tumbleweed - zypper addrepo https://download.opensuse.org/repositories/windows:mingw:win64/openSUSE_Tumbleweed/windows:mingw:win64.repo - -## Leap 15.2 - zypper addrepo https://download.opensuse.org/repositories/windows:mingw:win64/openSUSE_Leap_15.2/windows:mingw:win64.repo - -## Leap 15.1 - zypper addrepo https://download.opensuse.org/repositories/windows:mingw:win64/openSUSE_Leap_15.1/windows:mingw:win64.repo - - zypper refresh - zypper in mingw64-gtk3-devel mingw64-cross-gcc - -### Other distributions - -GTK doesn't offer Windows binaries for download anymore, so for distributions that don't package their own Mingw-GTK packages, cross-compiling is much harder. In general the steps are: - -1. Download 64 bit Mingw GTK libraries. -2. Unzip it in a folder. For example, to install it in `/opt/gtkwin`: `mkdir -p /opt/gtkwin && unzip -d /opt/gtkwin`. -3. You have to set-up the library to match the installation folder: - - cd /opt/gtkwin - find -name '*.pc' | while read pc; do sed -e "s@^prefix=.*@prefix=$PWD@" -i "$pc"; done - -Finding some place to download the libraries is the challenge however, and there is no ideal solution. Three options are: (1) Getting the most versions from the Fedora RPMs, which can be downloaded [here](https://pkgs.org/search/?q=mingw64); (2) Using the ancient GTK 3.6 available [here](http://www.tarnyko.net/dl/gtk.htm); (3) Delving into GTK's own [recommendations](https://www.gtk.org/docs/installations/windows) for Windows. Be sure to check your own distribution's repository first however. - -## Compiling - -Now create your project using gtk-rs (and relm, it's great). if you don't want a terminal window to pop up when running add the following to the top of your `main.rs`. - - #![windows_subsystem = "windows"] - -Once you get it working on Linux you can compile for Windows following these steps. `PKG_CONFIG_PATH` should point to your Mingw's pkgconfig directory, while `MINGW_PREFIX` should point to Mingw's root installation. For Arch for example: - - export PKG_CONFIG_ALLOW_CROSS=1 - export MINGW_PREFIX=/usr/x86_64-w64-mingw32 - export PKG_CONFIG_PATH=$MINGW_PREFIX/lib/pkgconfig - cargo build --target=x86_64-pc-windows-gnu --release - -For Fedora Mingw's prefix is `/usr/x86_64-w64-mingw32/sys-root/mingw/`. For other distributions it is `/opt/gtkwin` or wherever you installed the precompiled binaries. - -If you have some problems while compiling, you might want to consider rebooting since this has solved some problem on my side. -Also, you should be careful when using Glade with gtk-rs. Make sure that the version requested by Glade is at most equal to the version installed on your system. Otherwise it will fail to execute. - -## Packaging - -We will reuse the `MINGW_PREFIX` path here to copy over relevant files to package it up: - - mkdir /wherever/release - cp target/x86_64-pc-windows-gnu/release/*.exe /wherever/release - cp $MINGW_PREFIX/bin/*.dll /wherever/release - mkdir -p /wherever/release/share/glib-2.0/schemas - cp $MINGW_PREFIX/share/glib-2.0/schemas/gschemas.compiled /wherever/release/share/glib-2.0/schemas/gschemas.compiled - cp -r $MINGW_PREFIX/share/icons /wherever/release/share/icons - -After that you can zip up the contents of the `/wherever/release` folder and distribute it. - -## Optional Extras - -### Icon and version info - -These steps are for adding an icon to your program. First make a rc file showing where the icon is and the version info. Change "path/to/my.ico" to your icon". The BLOCK "040904E4" and VALUE "Translation", 0x409, 1252 are for US english, if you would like something different refer to https://msdn.microsoft.com/library/aa381058 - -src/program.rc: - - id ICON "path/to/my.ico" - 1 VERSIONINFO - FILEVERSION 1,0,0,0 - PRODUCTVERSION 1,0,0,0 - BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904E4" - BEGIN - VALUE "CompanyName", "My Company Name" - VALUE "FileDescription", "My excellent application" - VALUE "FileVersion", "1.0" - VALUE "InternalName", "my_app" - VALUE "LegalCopyright", "My Name" - VALUE "OriginalFilename", "my_app.exe" - VALUE "ProductName", "My App" - VALUE "ProductVersion", "1.0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END - END - -now to have the linker include it you'll need to make a build script, first add the following to your Cargo.toml: - - [package] - build = "build.rs" - -then in your build.rs - - use std::process::Command; - use std::env; - use std::path::Path; - - fn main() { - let out_dir = env::var("OUT_DIR").unwrap(); - Command::new("x86_64-w64-mingw32-windres") - .args(&["src/program.rc"]) - .arg(&format!("{}/program.o", out_dir)) - .status().unwrap(); - - Command::new("x86_64-w64-mingw32-gcc-ar") - .args(&["crus", "libprogram.a", "program.o"]) - .current_dir(&Path::new(&out_dir)) - .status().unwrap(); - - println!("cargo:rustc-link-search=native={}", out_dir); - println!("cargo:rustc-link-lib=static=program"); - } - -You'll need to comment out both prints when building for linux. - -### Windows 10 theme - -If you'd like the program to have a more native look you can set the theme to windows 10. - - mkdir /wherever/release/share/themes - mkdir /wherever/release/share/gtk-3.0 - -edit /wherever/release/share/gtk-3.0/settings.ini - - [Settings] - gtk-theme-name = Windows10 - gtk-font-name = Segoe UI 10 - gtk-xft-rgba = rgb - -then download the windows 10 them from [https://b00merang.weebly.com/windows-10.html](https://b00merang.weebly.com/windows-10.html). - - unzip Windows-10-master.zip - mv Windows-10-master /wherever/release/share/themes/Windows10 - - diff --git a/docs-src/tutorial/gir_tutorial.md b/docs-src/tutorial/gir_tutorial.md deleted file mode 100644 index f13ea44ca..000000000 --- a/docs-src/tutorial/gir_tutorial.md +++ /dev/null @@ -1,558 +0,0 @@ ---- -layout: default ---- - -# Generating a GNOME library using gir crate - -In this tutorial, we'll see how to generate a GNOME library using the [gir] crate. A few things to note first: - - * It only works on GObject-based libraries. - * You need `.gir` files. - -A little explanation about those requirements: the [gir] crate needs `.gir` files to generate the library API. You can generally find them alongside the library header files (as you can see [here](https://packages.debian.org/stretch/amd64/libgtk-3-dev/filelist) for example, look for ".gir"). - -The `.gir` files "describes" the library API (objects, arguments, even ownership!). This is where the [gir] crate comes in: it reads those `.gir` files and generates the Rust crates from them. You can learn more about the GIR format [here](https://gi.readthedocs.io/en/latest/). - -A little note about the `.gir` files: it often happens that they are invalid (missing or invalid annotations for example). We have a small script to fix the `.gir` files we're using (and only them!) available in the [gir-files repository](https://github.com/gtk-rs/gir-files/blob/master/fix.sh). You can run it like this (at the same level of the `.gir` files you want to patch): - -```bash -> sh fix.sh -``` - -All `gtk-rs` generated crates come in two parts: the `sys` part which contains all the C functions and types definitions (direct mapping, everything is unsafe) and the "high-level" part which contains the nice, completely safe and idiomatic Rust API on top of the `sys` part. - -As an example, we'll generate the `sourceview` library bindings. So first, let's generate the `sys` part! - -## Generating the sys-library - -First, you'll need to download [gir]: - -```bash -> git clone https://github.com/gtk-rs/gir -> cd gir -> cargo install --path . # so we can use gir binary directly -``` - -Then the `.gir` files (luckily for you, we have a repository which contains all the ones you need for sourceview!): - -```bash -> git clone https://github.com/gtk-rs/gir-files -``` - -If you look into `gir-files`, you'll see a file named `GtkSource-3.0.gir`. That's the one for sourceview. - -Now let's create a new project for our `sourceview` crate: - -```bash -> cargo new sourceview --lib -``` - -Then let's create a folder inside the newly created `sourceview` folder for the `sys` part: - -```bash -> cd sourceview -> cargo new sourceview-sys --lib -``` - -To indicate to [gir] what to generate, we'll need a `Gir.toml` file (inside the `sourceview-sys` folder) containing: - -```toml -[options] -library = "GtkSource" -version = "3.0" -target_path = "." -min_cfg_version = "3.0" -``` - - * `library` stands for the library we want to generate. - * `version` stands for the version of the library to be used. - * `target_path` stands for the location where the files will be generated. - * `min_cfg_version` will be the minimum version supported by the generated bindings. - -You should now have a folder looking like this: - -```text -sourceview/ - | - |---- Cargo.toml - |---- sourceview-sys/ - | | - | |---- Cargo.toml - | |---- Gir.toml - | |---- src/ - | | - | |---- lib.rs - |---- src/ - | - |---- lib.rs -``` - -Let's generate the `sys` crate now: - -```bash -> cd sourceview-sys -# Run gir in "sys" mode (the "-m" option) and we give the gir files path (the "-d" option) -> gir -m sys -d ../../gir-files/ -``` - -(In case a failure happens at this point, and you can't figure out what's going on, don't hesitate to reach us so we can give you a hand!) - -You should now see new files (and a new folder): - - * `build.rs` - * `Cargo.toml` - * `src/lib.rs` - * `tests/` - -Now let's try to build it: - -```bash -> cargo build -``` - -Surprise! It doesn't build at all and you should see a loooooot of errors. Well, that was expected. We need to add some dependencies (you can find which ones in the `.gir` files) in order to make it work. Let's update our `Gir.toml` file to make it look like this: - -```toml -[options] -library = "GtkSource" -version = "3.0" -target_path = "." -min_cfg_version = "3.0" - -external_libraries = [ - "Cairo", - "Gdk", - "GdkPixbuf", - "Gio", - "GLib", - "GObject", - "Gtk", -] -``` - -Now we regenerate it then rebuild it: - -```bash -> rm Cargo.* # we remove Cargo files -> gir -m sys -d ../../gir-files/ -> cargo build -``` - -Should work just fine! - -We can cleanup the command line a bit now. You can actually give the work mode ("-m" option) and the gir files repository through the `Gir.toml` file using "work_mode" and "girs_dir" options: - -```toml -[options] -library = "GtkSource" -version = "3.0" -target_path = "." -min_cfg_version = "3.0" -work_mode = "sys" -girs_dir = "../../gir-files/" - -external_libraries = [ - "Cairo", - "Gdk", - "GdkPixbuf", - "Gio", - "GLib", - "GObject", - "Gtk", -] -``` - -Now, if you want to regenerate, just run: - -```bash -> gir -``` - -Now we have a working `sys` containing all functions and objects definition. Just to be sure everything was correctly generated, we can run some tests (graciously generated by [gir] as well): - -```bash -> cargo test -``` - -Normally, all tests passed. If you get an error when running those tests, it's very likely that the `sys` generation is invalid and/or incomplete. - -Time to generate the high-level Rust API! - -## Generating the high-level Rust API - -Time to go back to the "global" sourceview folder: - -```bash -> cd .. -``` - -As you certainly guessed, we'll need a new `Gir.toml` file. Let's write it: - -```toml -[options] -girs_dir = "../gir-files" -library = "GtkSource" -version = "3.0" -min_cfg_version = "3.0" -target_path = "." -work_mode = "normal" -generate_safety_asserts = true -deprecate_by_min_version = true -single_version_file = true - -generate = [] -``` - -A few new things in here. Let's take a look at them: - - * "work_mode" value is now set to "normal", it means it'll generate the high-level Rust api instead of the sys-level. - * "generate_safety_asserts" is used to generates checks to ensure that, or any other kind of initialization needed before being able to use the library. - * "deprecate_by_min_version" is used to generate a [Rust "#[deprecated]"](https://doc.rust-lang.org/edition-guide/rust-2018/the-compiler/an-attribute-for-deprecation.html) attribute based on the deprecation information provided by the `.gir` file. - * "single_version_file" is a very useful option when you have a lot of generated files (like we'll have). Instead of generating the gir hash commit used for the generation in the header of all generated files, it'll just write it inside one file, removing `git diff` noise **a lot**. - * "generate = []": this line currently does nothing. We say to [gir] to generate nothing. We'll fulfill it later on. - -Let's make a first generation of our high-level Rust API! - -```bash -> gir -``` - -Now if you take a look around, you'll see a new "auto" folder inside "src". Doesn't contain much though. Which makes sense since we're generating nothing. Time to introduce you to a whole new [gir] mode: not_bound. Let's give it a try: - -```bash -> gir -m not_bound -[NOT GENERATED] GtkSource.Buffer -[NOT GENERATED PARENT] Gtk.TextBuffer -[NOT GENERATED] GtkSource.Language -[NOT GENERATED] GtkSource.Mark -[NOT GENERATED PARENT] Gtk.TextMark -[NOT GENERATED] GtkSource.StyleScheme -[NOT GENERATED] GtkSource.UndoManager -[NOT GENERATED] GtkSource.SortFlags -[NOT GENERATED] GtkSource.Completion -[NOT GENERATED PARENT] Gtk.Buildable -[NOT GENERATED] GtkSource.CompletionProvider -[NOT GENERATED] GtkSource.CompletionContext -[NOT GENERATED PARENT] GObject.InitiallyUnowned -[NOT GENERATED] GtkSource.CompletionInfo -[NOT GENERATED PARENT] Gtk.Window -[NOT GENERATED PARENT] Gtk.Bin -[NOT GENERATED PARENT] Gtk.Container -[NOT GENERATED PARENT] Gtk.Widget -[NOT GENERATED PARENT] Atk.ImplementorIface -[NOT GENERATED] GtkSource.View -[NOT GENERATED PARENT] Gtk.TextView -[NOT GENERATED PARENT] Gtk.Scrollable -[NOT GENERATED] GtkSource.CompletionActivation -[NOT GENERATED] GtkSource.CompletionProposal -[NOT GENERATED] GtkSource.CompletionError -[NOT GENERATED] GtkSource.CompletionItem -[NOT GENERATED PARENT] GtkSource.CompletionProposal -[NOT GENERATED] GtkSource.CompletionWords -[NOT GENERATED PARENT] GtkSource.CompletionProvider -[NOT GENERATED] GtkSource.DrawSpacesFlags (deprecated in 3.24) -[NOT GENERATED] GtkSource.Encoding -[NOT GENERATED] GtkSource.File -[NOT GENERATED] GtkSource.MountOperationFactory -[NOT GENERATED] GtkSource.FileLoader -[NOT GENERATED] GtkSource.FileLoaderError -[NOT GENERATED] GtkSource.FileSaver -[NOT GENERATED] GtkSource.FileSaverFlags -[NOT GENERATED] GtkSource.FileSaverError -[NOT GENERATED] GtkSource.Gutter -[NOT GENERATED] GtkSource.GutterRenderer -[NOT GENERATED] GtkSource.GutterRendererState -[NOT GENERATED] GtkSource.GutterRendererAlignmentMode -[NOT GENERATED] GtkSource.GutterRendererPixbuf -[NOT GENERATED PARENT] GtkSource.GutterRenderer -[NOT GENERATED] GtkSource.GutterRendererText -[NOT GENERATED] GtkSource.LanguageManager -[NOT GENERATED] GtkSource.Map -[NOT GENERATED PARENT] GtkSource.View -[NOT GENERATED] GtkSource.MarkAttributes -[NOT GENERATED] GtkSource.PrintCompositor -[NOT GENERATED] GtkSource.Region -[NOT GENERATED] GtkSource.RegionIter -[NOT GENERATED] GtkSource.SearchContext -[NOT GENERATED] GtkSource.SearchSettings -[NOT GENERATED] GtkSource.Style -[NOT GENERATED] GtkSource.SpaceDrawer -[NOT GENERATED] GtkSource.SpaceTypeFlags -[NOT GENERATED] GtkSource.SpaceLocationFlags -[NOT GENERATED] GtkSource.StyleSchemeChooser -[NOT GENERATED] GtkSource.StyleSchemeChooserButton -[NOT GENERATED PARENT] Gtk.Button -[NOT GENERATED PARENT] Gtk.Actionable -[NOT GENERATED PARENT] Gtk.Activatable -[NOT GENERATED PARENT] GtkSource.StyleSchemeChooser -[NOT GENERATED] GtkSource.StyleSchemeChooserInterface -[NOT GENERATED] GtkSource.StyleSchemeChooserWidget -[NOT GENERATED] GtkSource.StyleSchemeManager -[NOT GENERATED] GtkSource.Tag -[NOT GENERATED PARENT] Gtk.TextTag -[NOT GENERATED] GtkSource.ViewGutterPosition -``` - -We now have the list of all the non-yet generated items. Quite convenient! You can also see that we have two kinds of not generated items: - - * `[NOT GENERATED]` - * `[NOT GENERATED PARENT]` - -`[NOT GENERATED PARENT]` means that this object lives in a dependency of the current library. We'll come back on how to add them a bit later. - -Let's start by generating one type. Let's update the "generate" array as follows: - -```toml -generate = [ - "GtkSource.Language", -] -``` - -Another `gir` run: - -```bash -> gir -``` - -(Again, if you do it on another library and it fails and you can't figure out why, don't hesitate to reach us!) - -We now have a `src/auto/language.rs` file. We need to include all `auto` files in our library. To do so, let's update the `src/lib.rs` file as follows: - -```rust -pub use auto::*; - -mod auto; -``` - -Let's compile: - -```bash -> cargo build -``` - -It completely failed with a lot of errors. Yeay! - -You guessed it, we need to add a few dependencies to make it work. A lot of those errors were about the fact that the `Language` type didn't exist. Which is weird since we generated it, right? Well, if you take a look at the `src/auto/language.rs` file, you'll see this at the top: - -```rust -glib_wrapper! { - pub struct Language(Object); - - match fn { - get_type => || gtk_source_sys::gtk_source_language_get_type(), - } -} -``` - -This macro comes from the `glib` crate. We didn't import it, therefore the Rust compiler can't find it. We'll also need its `sys` part (the case of `glib` is a bit special). - -Another issue that will arise is that we didn't import the `sourceview-sys` crate either. Alongside those two (three if we count `glib-sys`!), we'll need both `libc` and `bitflags`. Let's fix all of those issues at once! For that, we need to update the `Cargo.toml`: - -```toml -[package] -name = "sourceview" -version = "0.1.0" -authors = ["Guillaume Gomez "] - -[dependencies] -libc = "0.2" -bitflags = "1.0" - -[dependencies.gtk-source-sys] -path = "./sourceview-sys" - -[dependencies.glib] -git = "https://github.com/gtk-rs/glib" - -[dependencies.glib-sys] -git = "https://github.com/gtk-rs/sys" # all gtk-rs sys crates are in the sys repository -``` - -And to import those crates into `src/lib.rs`: - -```rust -#[macro_use] -extern crate glib; -extern crate glib_sys; -extern crate gtk_source_sys; - -extern crate libc; -#[macro_use] -extern crate bitflags; - -pub use auto::*; - -mod auto; -``` - -Let's try to rebuild: - -```bash -> cargo build -``` - -It worked! We have generated the `Language` item! I'll let you take a look at the `src/auto/language.rs` file, then we can continue. - -Again, if you encounter any issue at this stage (if the generated code is invalid for example), don't hesitate to reach us so we can give you a hand! - -We'll now generate the `GtkSource.Region` type. Why this one? Well, I don't want to spoil the surprise so just wait for a bit! - -First, we need to add it into the types to generate into our `Gir.toml` file: - -```toml -generate = [ - "GtkSource.Language", - "GtkSource.Region", -] -``` - -We regenerate: - -```bash -> gir -``` - -We rebuild: - -```bash -> cargo build -``` - -Everything works, yeay! Now if we take a look at our newly generated `src/auto/region.rs`, we'll see code like this: - -```rust -//#[cfg(any(feature = "v3_22", feature = "dox"))] -//fn add_subregion(&self, _start: /*Ignored*/>k::TextIter, _end: /*Ignored*/>k::TextIter); - -//#[cfg(any(feature = "v3_22", feature = "dox"))] -//fn get_buffer(&self) -> /*Ignored*/Option; -``` - -Some functions are commented. Why so? The reason is simple: we need to tell to `gir` that those types have been generated and that it can generate code using them. We can do it by adding the type into the "manual" list. To put it simply, when [gir] sees an item into this "manual" list, it means to it "this type has been generated somewhere else, you can use it just like the others". - -Let's update our `Gir.toml` file once again: - -```toml -generate = [ - "GtkSource.Language", - "GtkSource.Region", -] - -manual = [ - "Gtk.TextIter", - "Gtk.TextBuffer", -] -``` - -We'll also need to import the `gtk` crate. Let's add it into our `Cargo.toml` file: - -```toml -[dependencies.gtk] -git = "https://github.com/gtk-rs/gtk" -``` - -And import it into our `src/lib.rs`: - -```rust -extern crate gtk; -``` - -We regenerate and rebuild: - -```bash -> gir -> cargo build -``` - -Everything is working, yeay! If you take another look at `src/auto/region.rs`, you'll see a lot less commented functions. Amongst the remaining ones, you'll see this one: - -```rust -//#[cfg(any(feature = "v3_22", feature = "dox"))] -//fn get_start_region_iter(&self, iter: /*Ignored*/RegionIter); -``` - -If a type name isn't prepend by `[crate_name]::`, then it means it comes from the current crate. To add it, just put it into the "generate" list of `Gir.toml`. - -At this point, you should have almost everything you need. There is just one last case we need to talk about. - -## Generation errors - -There are a few kinds of errors (not much luckily) which can happen with [gir] generation. Let's take a look at them. - -### Missing memory management functions - -If [gir] generation fails (for whatever reason), it means you'll have to implement the type yourself. Just like types from other `gtk-rs` crates, you'll need to put it into the "manual" list. Then you need to put the type into the `src` folder (or inside a subfolder, you know how Rust works). - -/!\ Don't forget to reexport the type inside your `src/lib.rs` file! For example, let's take a look at the [requisition.rs](https://github.com/gtk-rs/gtk/blob/master/src/requisition.rs) file from the `gtk` crate. - -Since it's a "simple" type (no pointer, therefore no memory management to do), [gir] doesn't know how to generate it. You'll need to implement some traits by hand like `ToGlibPtr` or `ToGlibPtrMut` (depending on your needs). - -### Bad function generation - -In some cases, the generated code isn't correct (array parameters are often an issue). In such cases, it's better to just make the implementation yourself. As an example, let's say you want to implement `Region::is_empty` yourself. A few changes have to be made. Let's start with `Gir.toml`: - -```toml -generate = [ - "GtkSource.Language", -] - -[[object]] -name = "GtkSource.Region" -status = "generate" - [[object.function]] - name = "is_empty" - ignore = true -``` - -So to sum up what I wrote above: we removed "GtkSource.Region" from the "generate" list and we created a new entry for it. Then we say to [gir] that it should generate (through `status = "generate"`). However, we also tell it that we don't want the "is_empty" to be generated. - -Now that we've done that, we need to reimplement it. Let's create a `src/region.rs` file: - -```rust -use glib::object::IsA; -use glib::translate::*; -use Region; - -pub trait RegionExtManual: 'static { - pub fn is_empty(&self) -> bool; -} - -impl> RegionExtManual for O { - pub fn is_empty(&self) -> bool { - // blablabla - true - } -} -``` - -You might wonder: "why not just implementing it on the `Region` type directly?". Because like this, a subclass will also be able to use this trait easily as long as it implements `IsA`. For instance, in gtk, everything that implements `IsA` (so almost every GTK types) can use those methods. - -As usual, don't forget to reexport the trait. A little tip about reexporting manual traits: in `gtk-rs`, we create a `src/prelude.rs` file which reexports all traits (both manual and generated ones), making it simpler for users to use them through `use [DEPENDENCY]::prelude::*`. It looks like this: - -```rust -pub use auto::traits::*; - -pub use region::RegionExtManual; -``` - -Then it's reexported as follows from the `src/lib.rs` file: - -```rust -pub mod prelude; - -pub use prelude::*; -``` - -### Other gir options - -In case a function is badly generated, you don't **always** need to reimplement it. Sometimes, it's just an error in the gir files that you can override in your `Gir.toml` file. I recommend you to take a look at the [gir README file](https://github.com/gtk-rs/gir#the-api-mode-toml-config) to see all available options. - -## Words of the end - -That's it, with this we should be able to generate any GNOME crate you want. Happy coding! - -[gir]: https://github.com/gtk-rs/gir - - diff --git a/docs-src/tutorial/glade.md b/docs-src/tutorial/glade.md deleted file mode 100644 index 65d8a0172..000000000 --- a/docs-src/tutorial/glade.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -layout: default ---- - -# Glade - -[Glade](https://glade.gnome.org/) is a tool which allows to easily write `Gtk` applications. Let's see how you can use it with `Gtk-rs`. - -## Example - -There isn't much to explain in here. If you don't know how to use [Glade](https://glade.gnome.org/), take a look at their website directly. So first, let's see a simple and short example: - -```xml - - - - - Builder Basics - 320 - 240 - - - Big Useless Button - - - - - False - dialog - - - msgdialog - 300 - False - Thank you for trying this example - immediate - vertical - 2 - - - False - end - - - - - - False - True - end - 0 - - - - - True - False - You have pressed the button - end - 40 - 1 - - - False - True - 2 - - - - - - -``` - -So in this file, we created a [`Window`](https://gtk-rs.org/docs/gtk/struct.Window.html) containing a [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html), as simple as that. It also created a [`MessageDialog`](https://gtk-rs.org/docs/gtk/struct.MessageDialog.html) containing a message and a [`Label`](https://gtk-rs.org/docs/gtk/struct.Label.html). Like I said, quite simple. - -Now let's see how you can use this in your Rust code: - -```rust -// First we get the file content. -let glade_src = include_str!("builder_basics.glade"); -// Then we call the Builder call. -let builder = gtk::Builder::from_string(glade_src); - -// We start the gtk main loop. -gtk::main(); -``` - -Simple isn't it? However, just this code won't show anything. You need to call [`show_all`](https://gtk-rs.org/docs/gtk/trait.WidgetExt.html#tymethod.show_all) method on the [`Window`](https://gtk-rs.org/docs/gtk/struct.Window.html). But for that, you need to get the [`Window`](https://gtk-rs.org/docs/gtk/struct.Window.html) first: - -```rust -// Our window id is "window1". -let window: gtk::Window = builder.get_object("window1").unwrap(); -window.show_all(); -``` - -And that's all. If you need to add signal handlings, you need to do the same. For example, we want to show the [`MessageDialog`](https://gtk-rs.org/docs/gtk/struct.MessageDialog.html) when the [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html) is clicked. Let's add it: - -```rust -let button: gtk::Button = builder.get_object("button1").unwrap(); -let dialog: gtk::MessageDialog = builder.get_object("messagedialog1").unwrap(); - -button.connect_clicked(move |_| { - // We make the dialog window blocks all other windows. - dialog.run(); - // When it finished running, we hide it again. - dialog.hide(); -}); -``` - -Which gives us: - -```rust -if gtk::init().is_err() { - println!("Failed to initialize GTK."); - return; -} -let glade_src = include_str!("builder_basics.glade"); -let builder = gtk::Builder::from_string(glade_src); - -let window: gtk::Window = builder.get_object("window1").unwrap(); -let button: gtk::Button = builder.get_object("button1").unwrap(); -let dialog: gtk::MessageDialog = builder.get_object("messagedialog1").unwrap(); - -button.connect_clicked(move |_| { - dialog.run(); - dialog.hide(); -}); - -window.show_all(); - -gtk::main(); -``` - - diff --git a/docs-src/tutorial/gnome_and_rust.md b/docs-src/tutorial/gnome_and_rust.md deleted file mode 100644 index a68d75ca5..000000000 --- a/docs-src/tutorial/gnome_and_rust.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -layout: default ---- - -# Gnome libraries and Rust - -Currently, the `Gtk-rs` organization provides the bindings for the following libraries: - - * Gtk (the widget toolkit) - * Gdk (low-level functions provided by the underlying windowing and graphics systems) - * Gdk-pixbuf (image loading and manipulation) - * Cairo (vector graphic API) - * Glib (data structures and utilities for dealing with them) - * Gio (file system abstractions) - * Pango (layout engine, text and font handling) - -The goal is to provide a safe abstraction using Rust paradigms. - -## Objects - -First thing to note (it's very important!) is that the `Gtk-rs` objects can be cloned and it costs **nothing** more than copying a pointer, so basically nothing. The reason is quite simple (and I suppose you already guessed it): it's simply because `Gtk-rs` structs only contains a pointer to the corresponding `Gnome` objects. - -Now: why is cloning safe? One thing to note before going any further: it's not thread safe (and you shouldn't try to call a `Gnome` library function inside another thread). Otherwise, when a struct is dropped, it calls internally the [`g_object_unref`](https://gtk-rs.org/docs/gobject_sys/fn.g_object_unref.html) function and calls the [`g_object_ref`](https://gtk-rs.org/docs/gobject_sys/fn.g_object_ref.html) function when you call `clone()`. - -To put it simply: `Gnome` handles the resources allocation/removal for us. - -## Trait hierarchy - -In Gtk, there is a widget hierarchy. In Rust, it's implemented through "traits inheritance" and enforced by the compiler at compile-time. So, what does that mean exactly? Let's take an example: - -You have a [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html). As says the [gnome documentation](https://developer.gnome.org/gtk3/stable/GtkButton.html), a [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html) inheritance tree (a bit simplified) looks like this: - -``` - GObject - ╰── GtkWidget - ╰── GtkContainer - ╰── GtkBin - ╰── GtkButton -``` - -Which means that a [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html) can use methods from any of its parents. - -So basically, you just need to import a parent's trait to be able to use its methods: - -```rust -// we import Widget's methods. -use gtk::WidgetExt; - -// we create a button -let button = gtk::Button::with_label("Click me!"); - -// we use the method from the widget -button.show_all(); -``` - -As easy as that! - -## Interfaces - -The same goes for interfaces. The [gnome documentation](https://developer.gnome.org/gtk3/stable/GtkButton.html) also says that a [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html) implements the following interfaces: `GtkBuildable`, `GtkActionable` and `GtkActivatable`. Just like parents' methods, import the corresponding interface and then you'll be able to use the methods. - -I think that with this, you'll be able to write anything you want without too much difficulties. Now it's time to go deeper into `Gtk-rs` usage! - - diff --git a/docs-src/tutorial/index.md b/docs-src/tutorial/index.md deleted file mode 100644 index a19f8df19..000000000 --- a/docs-src/tutorial/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: default ---- - -# Tutorial - -## Introduction - -Here's an introduction to `Gtk-rs` crates. For the users who already know Rust and Gtk, just skip this part. - - * [Rust and `Gtk-rs`](rust_and_gtk): This part explains how to add dependencies on the `Gtk-rs` crates, depending on your needs. - * [Gnome libraries and Rust](gnome_and_rust): This part explains a bit how the bindings of the Gnome libraries work in Rust. - -## Full usage of `Gtk-rs` crates - -In this part we'll go deeper into the mechanisms of the `Gtk-rs` crates. If you're not sure about your Rust or Gnome libraries knowledge, we recommend you to take a look at the previous tutorials first. - - * [Specifying version](version). - * [Callbacks and closures](closures). - * [Object-oriented Rust](object_oriented). - * [Glade](glade). - * [Cross compiling from Linux to Windows](cross). - * [Cross compiling to different arches on Linux](cross-linux-arch). - -## Generating GNOME crate Rust API using `gir` - -A tutorial is available [here](gir_tutorial) if you want to generate your own GNOME crate binding. - -## Going further - -Make sure to check the examples directory in the [`gtk-rs` repository](https://github.com/gtk-rs/gtk-rs). -Also you can take a look at the source code of [projects using `gtk-rs`](/#projects-using-gtk-rs). diff --git a/docs-src/tutorial/object_oriented.md b/docs-src/tutorial/object_oriented.md deleted file mode 100644 index f8e1b57bd..000000000 --- a/docs-src/tutorial/object_oriented.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -layout: default ---- - -# Object-oriented Rust - -Since there is an inheritance system in Gtk, it's only logical to have one as well in `Gtk-rs`. Normally, most people won't need this, but understanding how things work can help navigating the documentation a lot. - -Each GTK class is split into a struct named after that class, and a trait with the same name and the suffix `Ext`, see for example [WidgetExt](https://gtk-rs.org/docs/gtk/prelude/trait.WidgetExt.html). All methods except the constructor(s) are not in the struct, but in that trait. In addition, some other methods can be found in a `…ExtManual` trait, as seen in [WidgetExtManual](https://gtk-rs.org/docs/gtk/prelude/trait.WidgetExtManual.html). This happens for implementation reasons currently. The same principle applies to GTK interfaces as well (have a look at the [Orientable](https://gtk-rs.org/docs/gtk/struct.Orientable.html) interface for an example). There are a few exceptional classes that don't follow this general pattern: one reason for this is that final classes don't need an extension trait because there can't be any subclasses of them, and thus can have their methods defined on the struct itself. - -## Basic inheritance - -Any struct not only implements its `Ext` trait, but also all traits of its super classes. That way you can call methods of super classes directly on a struct. - -The [`IsA`](https://gtk-rs.org/docs/glib/object/trait.IsA.html) trait is used to model the subtype relation of classes between structs. Every struct implements `IsA` for each of its parent classes (and its implemented interfaces). For example [FlowBox](https://gtk-rs.org/docs/gtk/struct.FlowBox.html) implements `IsA`, `IsA`, `IsA`, `IsA`. - -Passing classes as arguments is pretty straightforward. The only rule is that when accepting a class as function argument, take a generic `IsA` instead: [`fn add>(&self, widget: &P)`](https://gtk-rs.org/docs/gtk/trait.ContainerExt.html#tymethod.add). Now the method can be not only called with structs of that type, but also with structs of any subtype (in this case, any Widget). - -## Upcasting - -Upcasting should rarely be necessary due to the subtyping, but sometimes you need a "proper" `Widget` struct (instead of a `WidgetExt` implementor or an `IsA`). This is actually quite simple to achieve: - -```rust -let button = gtk::Button::with_label("Click me!"); -let widget = button.upcast::(); -``` - -Since the [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html) struct implements `IsA`, we can upcast into a [`Widget`](https://gtk-rs.org/docs/gtk/struct.Widget.html). It's important to note that the [`IsA`](https://gtk-rs.org/docs/gtk/trait.IsA.html) trait is implemented on every widget for every of its parents, which, in here, allows to [`upcast`](https://gtk-rs.org/docs/gtk/trait.Cast.html#method.upcast) the [`Button`](https://gtk-rs.org/docs/gtk/struct.Button.html) into a [`Widget`](https://gtk-rs.org/docs/gtk/struct.Widget.html). - -Let's see now a more global usage. - -## Checking if a widget is another widget - -Let's say you want to write a generic function and want to check if a `Widget` is actually a `Box`. First, let's see a bit of code: - -```rust -fn is_a_box + IsA + Clone>(widget: &W) -> bool { - widget.clone().upcast::().is::() -} -``` - -Ok, so what's happening in there? First, you'll note the usage of the [`IsA`](https://gtk-rs.org/docs/gtk/trait.IsA.html) trait. The received `widget` needs to implement both `IsA` and `IsA`. - -We need the [`Object`](https://gtk-rs.org/docs/gtk/struct.Object.html) to be able to use the [`Cast`](https://gtk-rs.org/docs/gtk/trait.Cast.html) trait which contains both [`upcast`](https://gtk-rs.org/docs/gtk/trait.Cast.html#method.upcast) and [`downcast`](https://gtk-rs.org/docs/gtk/trait.Cast.html#method.downcast) methods (take a look to it for other methods as well). - -We don't really need our widget to be a [`Widget`](https://gtk-rs.org/docs/gtk/struct.Widget.html), we just put it here to make things easier (so we can upcast into a [`Widget`](https://gtk-rs.org/docs/gtk/struct.Widget.html) without troubles). - -So the point of this function is to upcast the widget to the highest widget type and then try downcasting it into the wanted object. We could make even more generic like this: - -```rust -fn is_a + IsA + Clone, - T: IsA + IsA>(widget: &W) -> bool { - widget.clone().upcast::().downcast::().is_ok() -} -``` - -Then let's test it: - -```rust -let button = gtk::Button::with_label("Click me!"); - -assert_eq!(is_a::<_, gtk::Container>(&button), true); -assert_eq!(is_a::<_, gtk::Label>(&button), false); -``` - - diff --git a/docs-src/tutorial/rust_and_gtk.md b/docs-src/tutorial/rust_and_gtk.md deleted file mode 100644 index 7c8c85aae..000000000 --- a/docs-src/tutorial/rust_and_gtk.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -layout: default ---- - -# Rust and `Gtk-rs` - -Before going any further, if you don't know Rust at all, we recommend you to read the official [Rust Book](https://doc.rust-lang.org/book/). - -Then we recommend you to learn a bit about [Cargo](https://doc.crates.io/index.html) and check the [GTK requirements](https://www.gtk.org/docs/installations/). - -All done? Perfect! - -## Adding `Gtk-rs` as dependency - -Let's start with the basics. I assume you already created a project with a `Cargo.toml` file in it. To add the `Gtk-rs`' gtk crate as dependency, it's as simple as follow: - -```toml -[dependencies] -gtk = "0.1.0" -``` - -Then from your "main" file (understand the entry point of your program/library), add: - -```rust -extern crate gtk; -``` - -Of course, the same goes for any other `Gtk-rs` crate. Example with glib: - -```toml -[dependencies] -glib = "0.1.0" -``` - -And: - -```rust -extern crate glib; -``` - -## Get last version - -If a new `Gtk-rs` release happens, just go to [crates.io](https://crates.io) and check for the `Gtk-rs` crates version you're using. Update the version to your `Cargo.toml` file: - -```toml -gtk = "0.2.0" -``` - -Then just compile normally, `cargo` will update the dependency by itself. - -## Examples - -Now that you know how to import `Gtk-rs` crates into your code, looking at the examples directory in the [`gtk-rs` repository](https://github.com/gtk-rs/gtk-rs/) could be a great idea! - - diff --git a/docs-src/tutorial/version.md b/docs-src/tutorial/version.md deleted file mode 100644 index 6d967996f..000000000 --- a/docs-src/tutorial/version.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -layout: default ---- - -# Specifying version - -By default, `Gtk-rs` only provides objects and functions for the Gtk 3.4 version. If you want to use newer version, you'll need to specify them through `Cargo` features. - -## Explanations - -If you don't know how `Cargo` features work, I suggest you to take a look at its [documentation](https://doc.crates.io/specifying-dependencies.html#choosing-features) first. - -Now let's take a look at `Gtk-rs/gtk` crate features: - -```toml -v3_6 = ["gtk-sys/v3_6", "gdk/v3_6"] -v3_8 = ["v3_6", "gtk-sys/v3_8", "gdk/v3_8"] -v3_10 = ["v3_8", "gtk-sys/v3_10", "gdk/v3_10"] -v3_12 = ["v3_10", "gtk-sys/v3_12", "gdk/v3_12"] -v3_14 = ["v3_12", "gtk-sys/v3_14", "gdk/v3_14"] -v3_16 = ["v3_14", "gtk-sys/v3_16", "gdk/v3_16"] -v3_18 = ["v3_16", "gtk-sys/v3_18", "gdk/v3_18"] -v3_20 = ["v3_18", "gtk-sys/v3_20", "gdk/v3_20"] -v3_22 = ["v3_20", "gtk-sys/v3_22", "gdk/v3_22"] -``` - -First thing to note, every version feature include all previous ones. So if you use the `v3_10` feature to get the Gtk 3.10 version, you'll also have access to the 3.8, 3.6 and 3.4 versions. - -## Don't use version you don't (yet?) have! - -Very important to note: if you have a Gtk 3.8 version installed on your computer, you won't be able to use newer feature than `v3_8`, otherwise it just won't compile. So before using any feature, don't forget to check if you **can**. - -## Specifying the feature in your crate - -In your `Cargo.toml` file, you can specify which version you want to target like this: - -```toml -[dependencies.gtk] -version = "0.1" -default-features = false # just in case -features = ["v3_18"] -``` - -And if you want to provide a multi-version crate, you'll need to add features on your own: - -```toml -[features] -gtk_3_10 = ["gtk/v3_10"] -gtk_3_14 = ["gtk/v3_14"] -``` - -So when someone has a new enough version of Gtk, it'll be able to build your crate like this: - -``` -> cargo build --features gtk_3_14 -``` - - diff --git a/docs-src/useful-links.md b/docs-src/useful-links.md deleted file mode 100644 index d2b050b91..000000000 --- a/docs-src/useful-links.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -layout: default ---- - -# Useful links - -Here is a list of useful external resources talking about `Gtk-rs`. If you want to go deeper in the project's mechanisms or if you're just curious, it's the place to look at! - -Of course, if you want to add other links as well, just make a [Pull Request](https://github.com/gtk-rs/gtk-rs.github.io/compare?expand=1) for it! - - * [Initial posts about librsvg's C to Rust conversion](https://people.gnome.org/~federico/blog/librsvg-posts.html) - * [How Glib-rs works, part 1: Type conversions](https://people.gnome.org/~federico/blog/how-glib-rs-works-part-1.html) - * [How Glib-rs works, part 2: Transferring lists and arrays](https://people.gnome.org/~federico/blog/how-glib-rs-works-part-2.html) - * [How glib-rs works, part 3: Boxed types](https://people.gnome.org/~federico/blog/how-glib-rs-works-part-3.html) - * [Exporting a GObject C API from Rust code and using it from C, Python, JavaScript and others](https://coaxion.net/blog/2017/09/exporting-a-gobject-c-api-from-rust-code-and-using-it-from-c-python-javascript-and-others/) - * [Gtk-rs release process](https://blog.guillaume-gomez.fr/articles/2017-09-07+Gtk-rs+release+process) diff --git a/docs-src/faq.md b/faq.md similarity index 60% rename from docs-src/faq.md rename to faq.md index 544887f4e..297254117 100644 --- a/docs-src/faq.md +++ b/faq.md @@ -14,25 +14,17 @@ Also, please keep in mind that **Gtk-rs** members and contributors are doing it ## How are **Gtk-rs** maintained crates selected? -This entirely depends on a few criterias: - - * Are they a lot of users asking for it? - * Can it be generated using [gir](https://github.com/gtk-rs/gir)? - * Is anyone interested into maintaining it? - -As long as two of these criterias are fulfilled, we can move to the next step. - -The crate is then proposed to the **Gtk-rs** members. If no one has objections or there are no particular technical issues on writing the binding for this crate, the work can start. +Currenlty we only add crates to the GTK-rs project that are required for the existing stack. A growing collection of other projects that are based on GTK-rs and gir can be found on the [GNOME GitLab](https://gitlab.gnome.org/World/Rust). ## I want more **Gtk-rs** examples! -Please open an issue on the [`gtk-rs` repository](https://github.com/gtk-rs/gtk-rs/). +You can find more examples in the corresponding respositories -## I didn't understand something and the tutorials don't talk about. +- [gtk-rs-core/examples](https://github.com/gtk-rs/gtk-rs-core/tree/master/examples) +- [gtk3-rs/examples](https://github.com/gtk-rs/gtk3-rs/tree/master/examples) +- [gtk4-rs/examples](https://github.com/gtk-rs/gtk4-rs/tree/master/examples) -Open an issue on the [website](https://github.com/gtk-rs/gtk-rs.github.io) repository and please explain what you didn't understand, in which context and what you're trying to do. The more information we have, the better we'll be able to write the tutorial (if any required). - -Also, it's always possible to come ask us directly. Take a look at the [Contact us](/docs-src/contact) page. +or have a look at the source code of the projects listed on our [start page](/#projects-using-gtk-rs). ## Why is documentation just a copy of the C one? @@ -49,12 +41,13 @@ Currently, documentation is generated as follows: If you want to have it locally, you'll have to run this command: -``` -cargo doc --features embed-lgpl-docs +```sh +cargo install rustdoc-stripper +./generator.py --embed-docs ``` -Don't forget to add the version you're using currently (depending on the crate of course). For example: +You will need rust nightly to build the docs. ``` -cargo doc --features embed-lgpl-docs v3_22_20 +cargo +nightly doc --features dox --no-deps --open ``` diff --git a/images/gtk-rs.png b/images/gtk-rs.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa2cced993386e8690bd5eb6362201a82349904 GIT binary patch literal 22620 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 literal 0 HcmV?d00001 diff --git a/index.md b/index.md index 605031a32..ea9f58ae1 100644 --- a/index.md +++ b/index.md @@ -1,173 +1,95 @@ --- -layout: wide +layout: no-wrapper --- -
-
+
-## [Rust] bindings for [GTK 3][GTK], [Cairo], [GtkSourceView] and other [GLib]-compatible libraries +# Unlock the GNOME stack for Rust -[![GTK screenshot](gtk.png)](gtk.png) +

+The GTK-rs project provides safe bindings to the [Rust] language for fundamental libraries from the GNOME stack like [GLib], [Cairo], [GTK 3][GTK] and [GTK 4][GTK]. +

-[Rust]: https://www.rust-lang.org/ -[GLib]: https://developer.gnome.org/glib/stable/ -[GTK]: https://developer.gnome.org/gtk3/stable/ +[Rust]: https://www.rust-lang.org +[GLib]: https://developer.gnome.org/glib +[GTK]: https://gtk.org [Cairo]: https://cairographics.org/documentation/ -[GtkSourceView]: https://wiki.gnome.org/Projects/GtkSourceView -
-
-
-

Crates

- {% include badges.html %} -
-
-
- - - - - Our sponsors -
+
+{% for post in site.categories.front limit:3 %} + + +
{{ post.title }}
+
+{% endfor %} +
+ +

+[![Open Collective backers and sponsors](https://img.shields.io/opencollective/all/gtk-rs?color=%2399c9ff&label=Support%20us%20on%20open%20collective&logo=open-collective&logoColor=white&style=for-the-badge&labelColor=%233385ff)](https://opencollective.com/gtk-rs) +

+ +## Available crates + +The following table contains the most popular crates of GTK-rs. More information on all existing crates is available under the corresponding *Project* links. + +{% include crates.html %} + + + +
+ +## The introductory book + + +
+
+ +## Sponsors + +Thanks to everyone supporting us on [open collective][opencollective]! A list of all sponsors can be seen on our [open collective page][opencollective]. + + +
+ -
-

Announcements

- {% for post in site.categories.front limit:3 %} - -

- {{ post.title }} -

- {% endfor %} + -
-| Crate | Minimum supported version | -|-------|---------------------------| -| [atk](https://crates.io/crates/atk) | 2.30 | -| [cairo](https://crates.io/crates/cairo-rs) | 1.14 | -| [gdk](https://crates.io/crates/gdk) | 3.16 | -| [gdk-pixbuf](https://crates.io/crates/gdk-pixbuf) | 2.32 | -| [gdk-x11](https://crates.io/crates/gdkx11) | 3.14 | -| [gio](https://crates.io/crates/gio) | 2.44 | -| [glib](https://crates.io/crates/glib) | 2.44 | -| [gtk](https://crates.io/crates/gtk) | 3.16 | -| [pango](https://crates.io/crates/pango) | 1.38 | -| [pangocairo](https://crates.io/crates/pangocairo) | 1.0 | -| [sourceview](https://crates.io/crates/sourceview) | 3.0 | - -
- -## Using - -First, prepare your system by taking a look at the [GTK installation page](https://www.gtk.org/docs/installations/). - -Then include `gtk` and `gio` in your `Cargo.toml` and set the minimal GTK version required by your project: -{% assign gtk = site.data.crates | where: "name", "gtk" %} - -~~~toml -[dependencies.gtk] -version = "{{ gtk[0].max_version }}" -features = ["v3_16"] - -[dependencies.gio] -version = "{{ gio[0].max_version }}" -features = ["v2_44"] -~~~ - -__The code is stable and feature complete, but the APIs might change in the future.__ - -Import the `gtk` and `gio` crates and their traits: - -~~~rust -extern crate gtk; -extern crate gio; - -use gtk::prelude::*; -use gio::prelude::*; -~~~ - -Create an application, etc. - -~~~rust -use gtk::{Application, ApplicationWindow, Button}; - -fn main() { - let application = Application::new( - Some("com.github.gtk-rs.examples.basic"), - Default::default(), - ).expect("failed to initialize GTK application"); - - application.connect_activate(|app| { - let window = ApplicationWindow::new(app); - window.set_title("First GTK Program"); - window.set_default_size(350, 70); - - let button = Button::with_label("Click me!"); - button.connect_clicked(|_| { - println!("Clicked!"); - }); - window.add(&button); - - window.show_all(); - }); - - application.run(&[]); -} -~~~ - -## Using latest, not published version - -Include `gtk` in your `Cargo.toml` not as crate but from git: - -~~~toml -[dependencies.gtk] -git = "https://github.com/gtk-rs/gtk" -features = ["v3_16"] -~~~ - -## Projects using gtk-rs -* [Banner Viewer](https://gitlab.gnome.org/World/design/banner-viewer) -* [BrewStillery](https://gitlab.com/MonkeyLog/BrewStillery) -* [Cigale](https://github.com/emmanueltouzery/cigale) -* [color_blinder_gtk](https://gitlab.com/dns2utf8/color_blinder_gtk) -* [Contrast](https://gitlab.gnome.org/World/design/contrast) -* [Cookbook](https://github.com/MacKarp/Cookbook) -* [Czkawka](https://github.com/qarmin/czkawka) -* [Epicwar Downloader](https://github.com/ab0v3g4me/epicwar-downloader) -* [Font Finder](https://github.com/mmstick/fontfinder) -* [Fractal](https://gitlab.gnome.org/GNOME/fractal) -* [Garta](https://github.com/zaari/garta) -* [Gattii](https://gitlab.com/susurrus/gattii) -* [GNvim](https://github.com/vhakulinen/gnvim) -* [gled](https://gitlab.com/pentagonum/gled) -* [glide](https://github.com/philn/glide) -* [gpsami](https://gitlab.gnome.org/hub/gpsami) -* [gtktranslate](https://github.com/skylinecc/gtktranslate) -* [Icon Library](https://gitlab.gnome.org/World/design/icon-library) -* [Iridium](https://github.com/matze/iridium) -* [lognplot](https://github.com/windelbouwman/lognplot) -* [Marmoset](https://github.com/sprang/marmoset) -* [mcmmtk](https://github.com/pwil3058/mcmmtk) -* [media-toc](https://github.com/fengalin/media-toc) -* [Myxer](https://github.com/Aurailus/Myxer) -* [neovim-gtk](https://github.com/daa84/neovim-gtk) -* [noaa-apt](https://github.com/martinber/noaa-apt) -* [pcatk](https://github.com/pwil3058/pcatk) -* [Pika Backup](https://gitlab.gnome.org/World/pika-backup) -* [PNMixer-rs](https://github.com/hasufell/pnmixer-rust) -* [Podcasts](https://gitlab.gnome.org/World/podcasts) -* [Popsicle](https://github.com/pop-os/popsicle/) -* [process-viewer](https://github.com/GuillaumeGomez/process-viewer) -* [Projectpad](https://github.com/emmanueltouzery/projectpad2) -* [relm](https://github.com/antoyo/relm) -* [rrun](https://github.com/buster/rrun) -* [Shortwave](https://gitlab.gnome.org/World/Shortwave) -* [Social](https://gitlab.gnome.org/World/Social) -* [SolidOak](https://github.com/oakes/SolidOak) -* [systemd-manager](https://gitlab.com/mmstick/systemd-manager) -* [Tau](https://gitlab.gnome.org/World/Tau) -* [tv-renamer](https://github.com/mmstick/tv-renamer) -* [Whatschanging](https://github.com/mothsART/whatschanging) - -If you want yours to be added to this list, please create a [Pull Request](https://github.com/gtk-rs/gtk-rs.github.io/edit/master/index.md) for it! +[opencollective]: https://opencollective.com/gtk-rs + +## Projects using GTK-rs + +
+{% capture projects %}{% include projects.md %}{% endcapture %} +{{ projects | markdownify }} +
+ +If you want your app to be added to this list, please create a [Pull Request](https://github.com/gtk-rs/gtk-rs.github.io/edit/master/_includes/projects.md) for it. + +
From 58e7989620a095d959c9a913ab543394a173ea8f Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Sun, 6 Jun 2021 21:38:43 +0200 Subject: [PATCH 2/5] Redesign latest news --- _sass/_layout.scss | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/_sass/_layout.scss b/_sass/_layout.scss index 1334fd26d..4cbf8e38e 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -190,10 +190,6 @@ section.special { min-height: calc(100vh - 300px); } -.page-heading { - font-size: 20px; -} - .post-list { margin-left: 0; list-style: none; @@ -206,25 +202,29 @@ section.special { .post-overview { text-align: center; padding: 0.7rem 0; + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: stretch; a, a:visited { @extend .box-design; max-width: 10em; - padding: 0.5em; - margin: 1.5em 1em 0; - line-height: 3em; + margin: 1.3em 0.8em 0; vertical-align: top; - min-height: 7em; + padding: 0.8em 0.6em 1em; + + font-weight: bold; + font-family: $headings-font-family; .post-meta { - color: #f6f5f4; - font-weight: 800; - font-family: $headings-font-family; + color: $header-text-color; + font-size: $small-font-size; } * { display: inline-block; - line-height: 1em; + margin: 0.3em 0; } } } From 70f45872744a58012e93c10d76ef13d32d9130fc Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Mon, 7 Jun 2021 17:00:12 +0200 Subject: [PATCH 3/5] Add new logo --- _includes/book.svg | 66 +++++++++++++---- _includes/contact.html | 9 +++ _includes/footer.html | 18 ++--- _sass/_layout.scss | 97 +++++++++++++++---------- contact.md | 3 +- gtk.png | Bin 40417 -> 0 bytes images/gtk-rs.png | Bin 22620 -> 0 bytes logo.svg | 159 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 288 insertions(+), 64 deletions(-) create mode 100644 _includes/contact.html delete mode 100644 gtk.png delete mode 100644 images/gtk-rs.png create mode 100644 logo.svg diff --git a/_includes/book.svg b/_includes/book.svg index ae329aab7..910dfbf99 100644 --- a/_includes/book.svg +++ b/_includes/book.svg @@ -1,13 +1,55 @@ - - - - - - image/svg+xml - - - - - - + + + + + + image/svg+xml + + + + + + + diff --git a/_includes/contact.html b/_includes/contact.html new file mode 100644 index 000000000..ec428b7cc --- /dev/null +++ b/_includes/contact.html @@ -0,0 +1,9 @@ + diff --git a/_includes/footer.html b/_includes/footer.html index 2bcdfde55..c0276c2e4 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -1,18 +1,10 @@ diff --git a/_sass/_layout.scss b/_sass/_layout.scss index 4cbf8e38e..e09bd0281 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -15,15 +15,23 @@ margin: 2.5rem 1.5rem; display: inline-block; - background-size: contain; - background-repeat: no-repeat; - padding-left: 120px; - line-height: 100px; + padding-left: 1rem; transition: 0.2s; transition-property: transform, opacity; - background-image: url('../images/gtk-rs.png'); + &::before { + background-size: contain; + background-repeat: no-repeat; + display: inline-block; + height: 110px; + width: 110px; + border-radius: 50%; + background-image: url('/logo.svg'); + content: ''; + vertical-align: middle; + margin-right: 1.6rem; + } &:hover { opacity: 0.9; @@ -131,49 +139,64 @@ flex-wrap: wrap; justify-content: space-around; align-items: center; - } - svg { - width: 1.2em; - margin-right: 0.6em; - display: inline-block; - path { - fill: white; + ul { + margin: 0; } - } - a { - color: white; - text-decoration: none; - line-height: 2em; - display: flex; + a { + color: white; - &:hover { - color: #CCC; + &:hover { + color: #CCC; + } + } - svg { - path { - fill: #CCC; - } + + & > a { + font-size: 0.8em; + display: inline-block; + text-decoration: none; + + img { + width: auto; + height: 5rem; + display: block; + padding-top: 0.3em; + transition: opacity 0.3s; + } + + &:hover img { + opacity: 0.8; } } } +} + +ul.contact { li { list-style: none; } - .wrapper > div { - font-size: 0.8em; - line-height: 0; - } - img { - height: 5em; - width: auto; - margin-left: auto; - display: block; - padding-top: 1em; + a { + line-height: 2em; + display: flex; + text-decoration: none; + + svg { + width: 1.2em; + padding-top: 1px; + margin-right: 0.6em; + path { + fill: currentcolor; + } + } + + &:hover { + text-decoration: none; + } } } @@ -368,13 +391,13 @@ section.special { text-align: center; display: flex; flex-wrap: wrap; - justify-content: space-between; + justify-content: space-evenly; + margin-left: 0; } li { list-style: none; display: inline-block; - flex-grow: 1; } @@ -383,7 +406,7 @@ section.special { font-family: $headings-font-family; font-weight: 600; - padding: 0 0.8em; + padding: 0 1em; margin: 0.15em 0.3em; line-height: 3em; vertical-align: center; diff --git a/contact.md b/contact.md index e755ad735..bceb6c9d2 100644 --- a/contact.md +++ b/contact.md @@ -6,8 +6,7 @@ layout: default For general support use the GNOME Discourse or the Matrix chat. -- GNOME Discourse **[discourse.gnome.org](https://discourse.gnome.org)** -- Matrix channel **[#rust:gnome.org](https://matrix.to/#/#rust:gnome.org)** +{% include contact.html %} ### Contact Gtk-rs developers diff --git a/gtk.png b/gtk.png deleted file mode 100644 index cb116755475d0274feeea7ccd3f0153162df97a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40417 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

>&P*Vh^nR^Xf(Ckmo{_HU_ zY$_V~hf$RPq~%QYT!~*KChV6sY(&Julq9Y!uPeml$Qf3}*D;Jzr}!qZQGV=rpmt(u;7^Gj>IcA$XrG|s!rw62gzlQ#Iel-g zU_4Z`2`%K!G(0U8Z)Ji10T;5|V3iS9aDS3anyD^$Arar_938Bdbbv1~eRRSP;byI# zsP?3tFwHxDQ3z6j(|8_BHBL&jh|BbpPN4Y`2hqI}tXk6OZmpNRjMpv7^{YMM!%_!x z@PC{HU4lDDB8#75<{v@hSYs6_IR9GZRS0?cRnN=bctX_OF8}dCtLakdljOfx|0an`NZ3~X7~7T(o!eq#D!-dZFZ75^yrItxF@@`jACiK?%KuGo<`bX)n+hYJ&j&J zb3N4BJlVC#C}$8=(?-mWCzSOlv2Nkd6lmZk%^miTZ=Tm-OIcg(uM{550Z z0z&&Qs$O@b{^CFGJS`vutVf&AzWU=L>U#R0gQJy~y~_MJtjRj*d5C`gB*t7vn9ewC zNg}$)?*zAbd^-P&v7>)lxZ|W%C@P(^+>}~(EC_tp)pGi>f*U?zcAS+;U%NjtA_9AH zbiM$!+dV)dAFk0jojb?C17td3%xtR_f9t?|x+ELj^6ptN;6c0YIbKcOD&~hM urvcl+wvXNZN1Y58fVW1oKOXO^c<~WWx529773AOEZD5f6+j8eCxBdlflh26& diff --git a/images/gtk-rs.png b/images/gtk-rs.png deleted file mode 100644 index 1aa2cced993386e8690bd5eb6362201a82349904..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22620 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 diff --git a/logo.svg b/logo.svg new file mode 100644 index 000000000..94162ffe4 --- /dev/null +++ b/logo.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 00bb94e8fade616eff752952bdcd0a3c7fd6dcce Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Mon, 7 Jun 2021 17:11:03 +0200 Subject: [PATCH 4/5] Rename project to "gtk-rs" --- _config.yml | 2 +- _sass/_layout.scss | 2 +- contact.md | 4 ++-- faq.md | 12 ++++++------ index.md | 8 ++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/_config.yml b/_config.yml index 923d2e2b9..b232320cc 100644 --- a/_config.yml +++ b/_config.yml @@ -1,5 +1,5 @@ # Site settings -title: GTK-rs +title: gtk-rs description: > # this means to ignore newlines until "baseurl:" Rust bindings for GTK and GLib-based libraries baseurl: "" # the subpath of your site, e.g. /blog/ diff --git a/_sass/_layout.scss b/_sass/_layout.scss index e09bd0281..acdbbedc0 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -323,7 +323,7 @@ section.special { svg { flex-shrink: 0; flex-basis: 7em; - margin: 0.3em 0.7em 0.5em 0; + margin: 0.3em 1em 0.5em 0; height: 120px; path { diff --git a/contact.md b/contact.md index bceb6c9d2..76d0487d6 100644 --- a/contact.md +++ b/contact.md @@ -8,6 +8,6 @@ For general support use the GNOME Discourse or the Matrix chat. {% include contact.html %} -### Contact Gtk-rs developers +### Contact gtk-rs developers -If you want to contact the Gtk-rs developers directly, there are multiple ways, either you can go on matrix as shown above or you can also just open an issue on our [repositories on GitHub](https://github.com/gtk-rs). However, please keep in mind that issues on GitHub should be used for bug reports or feature requests and not for general support. +If you want to contact the *gtk-rs* developers directly, there are multiple ways, either you can go on matrix as shown above or you can also just open an issue on our [repositories on GitHub](https://github.com/gtk-rs). However, please keep in mind that issues on GitHub should be used for bug reports or feature requests and not for general support. diff --git a/faq.md b/faq.md index 297254117..682e9e63b 100644 --- a/faq.md +++ b/faq.md @@ -8,15 +8,15 @@ Here are some questions we answered a few times. If one is missing, don't hesita ## Why are releases so long? -The **Gtk-rs** organization is not just some **GNOME** libraries bindings in Rust but also an ecosystem. A change in a crate can force all other crates to be regenerated! +The *gtk-rs* organization is not just some *GNOME* libraries bindings in Rust but also an ecosystem. A change in a crate can force all other crates to be regenerated! -Also, please keep in mind that **Gtk-rs** members and contributors are doing it **freely** on their **free time**. That slows things down but at least, they're done. :) +Also, please keep in mind that *gtk-rs* members and contributors are doing it **freely** on their **free time**. That slows things down but at least, they're done. :) -## How are **Gtk-rs** maintained crates selected? +## How are gtk-rs maintained crates selected? -Currenlty we only add crates to the GTK-rs project that are required for the existing stack. A growing collection of other projects that are based on GTK-rs and gir can be found on the [GNOME GitLab](https://gitlab.gnome.org/World/Rust). +Currenlty we only add crates to the gtk-rs project that are required for the existing stack. A growing collection of other projects that are based on *gtk-rs* and gir can be found on the [GNOME GitLab](https://gitlab.gnome.org/World/Rust). -## I want more **Gtk-rs** examples! +## I want more **gtk-rs** examples! You can find more examples in the corresponding respositories @@ -32,7 +32,7 @@ Considering the massive amount of documentation that would need to be written if ## Why isn't documentation directly into the source files and how can I have it locally? -Simple answer: because of license issues. **GNOME** is under **LGPL** whereas **Gtk-rs** is under **MIT**. If we included **GNOME** docs directly into the source code, we'd have to switch the license to match the **GNOME** one. +Simple answer: because of license issues. *GNOME* is under *LGPL* whereas *gtk-rs* is under *MIT*. If we included *GNOME* docs directly into the source code, we'd have to switch the license to match the *GNOME* one. Currently, documentation is generated as follows: diff --git a/index.md b/index.md index ea9f58ae1..4c15a665a 100644 --- a/index.md +++ b/index.md @@ -7,7 +7,7 @@ layout: no-wrapper # Unlock the GNOME stack for Rust

-The GTK-rs project provides safe bindings to the [Rust] language for fundamental libraries from the GNOME stack like [GLib], [Cairo], [GTK 3][GTK] and [GTK 4][GTK]. +The *gtk-rs* project provides safe bindings to the [Rust] language for fundamental libraries from the GNOME stack like [GLib], [Cairo], [GTK 3][GTK] and [GTK 4][GTK].

[Rust]: https://www.rust-lang.org @@ -30,7 +30,7 @@ The GTK-rs project provides safe bindings to the [Rust] language for fundamental ## Available crates -The following table contains the most popular crates of GTK-rs. More information on all existing crates is available under the corresponding *Project* links. +The following table contains the most popular crates of *gtk-rs*. More information on all existing crates is available under the corresponding *Project* links. {% include crates.html %} @@ -46,7 +46,7 @@ The following table contains the most popular crates of GTK-rs. More information
Julian Hofer is writing a book titled [*GUI development with Rust and GTK 4*][book]. -We most warmly recommend GTK-rs users to have a look at this book. +We most warmly recommend *gtk-rs* users to have a look at this book. While this book is targeted at GTK 4 developers, it also covers more general aspects of GLib like *GObject Concepts*, *The Main Event Loop* or *GSettings*. @@ -83,7 +83,7 @@ Thanks to everyone supporting us on [open collective][opencollective]! A list of [opencollective]: https://opencollective.com/gtk-rs -## Projects using GTK-rs +## Projects using gtk-rs
{% capture projects %}{% include projects.md %}{% endcapture %} From 3d07d82d59c3ab4d78acb4bea3ad201d9bc52c29 Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Mon, 7 Jun 2021 20:32:18 +0200 Subject: [PATCH 5/5] Use logo as favicon --- _includes/crates.html | 2 +- _includes/head.html | 11 +-- _sass/_layout.scss | 3 +- logo.svg | 190 ++++++++---------------------------------- 4 files changed, 41 insertions(+), 165 deletions(-) diff --git a/_includes/crates.html b/_includes/crates.html index 9eae8d927..77139f631 100644 --- a/_includes/crates.html +++ b/_includes/crates.html @@ -17,7 +17,7 @@ v{{crate.max_version}} - 🕮 + 🕮 {% endfor %} diff --git a/_includes/head.html b/_includes/head.html index 4d7e8f001..754805c39 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -1,11 +1,12 @@ - + - + {% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %} - + - - + + + diff --git a/_sass/_layout.scss b/_sass/_layout.scss index acdbbedc0..45ea69f0d 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -26,7 +26,6 @@ display: inline-block; height: 110px; width: 110px; - border-radius: 50%; background-image: url('/logo.svg'); content: ''; vertical-align: middle; @@ -182,7 +181,7 @@ ul.contact { a { line-height: 2em; - display: flex; + display: inline-flex; text-decoration: none; svg { diff --git a/logo.svg b/logo.svg index 94162ffe4..68da8a1e3 100644 --- a/logo.svg +++ b/logo.svg @@ -1,159 +1,35 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + +