diff --git a/_config.yml b/_config.yml index 885c0454b..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/_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..910dfbf99 --- /dev/null +++ b/_includes/book.svg @@ -0,0 +1,55 @@ + + + + + + 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/crates.html b/_includes/crates.html new file mode 100644 index 000000000..77139f631 --- /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..c0276c2e4 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -1,53 +1,10 @@ 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/_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..45ea69f0d 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -2,85 +2,90 @@ * 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; + padding-left: 1rem; + + transition: 0.2s; + transition-property: transform, opacity; + + &::before { + background-size: contain; + background-repeat: no-repeat; + display: inline-block; + height: 110px; + width: 110px; + background-image: url('/logo.svg'); + content: ''; + vertical-align: middle; + margin-right: 1.6rem; + } &: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 +101,7 @@ height: 15px; path { - fill: $grey-color-dark; + fill: white; } } } @@ -110,11 +115,6 @@ display: block; padding-bottom: 5px; } - - .page-link { - display: block; - padding: 5px 10px; - } } } @@ -124,127 +124,92 @@ * 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; -} + 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; + + ul { + margin: 0; + } -.contact-list, -.social-media-list { - list-style: none; - margin-left: 0; -} + a { + color: white; -.intro-col-wrapper { - margin-left: -$spacing-unit / 2; - @extend %clearfix; -} + &:hover { + color: #CCC; + } + } -.intro-col { - float: left; - margin-bottom: $spacing-unit / 2; - padding-left: $spacing-unit / 2; -} -.intro-col-1 { - width: calc(60% - (#{$spacing-unit} / 2)); -} + & > a { + font-size: 0.8em; + display: inline-block; + text-decoration: none; -.intro-col-2 { - width: calc(40% - (#{$spacing-unit} / 2)); -} + img { + width: auto; + height: 5rem; + display: block; + padding-top: 0.3em; + transition: opacity 0.3s; + } -@include media-query($on-laptop) { - .intro-col { - float: none; - width: calc(100% - (#{$spacing-unit} / 2)); + &:hover img { + opacity: 0.8; + } + } } } -.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)); -} +ul.contact { -.footer-col-3 { - width: calc(45% - (#{$spacing-unit} / 2)); -} - -@include media-query($on-laptop) { - .footer-col-1, - .footer-col-2 { - width: calc(50% - (#{$spacing-unit} / 2)); + li { + list-style: none; } - .footer-col-3 { - width: calc(100% - (#{$spacing-unit} / 2)); - } - .page-content { - /* 88px is the footer size */ - min-height: calc(100vh - #{$header-line-height} - #{$header-borders} - (#{$content-padding} * 2) - 88px); - } -} + a { + line-height: 2em; + display: inline-flex; + text-decoration: none; -@include media-query($on-palm) { - .footer-col { - float: none; - width: calc(100% - (#{$spacing-unit} / 2)); - } + svg { + width: 1.2em; + padding-top: 1px; + margin-right: 0.6em; + path { + fill: currentcolor; + } + } - .page-content { - /* 126px is the footer size */ - min-height: calc(100vh - #{$header-line-height} - #{$header-borders} - (#{$content-padding} * 2) - 126px); + &:hover { + text-decoration: none; + } } } - - /** * 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-heading { - font-size: 20px; +.page-content { + padding: $content-padding 0; + min-height: calc(100vh - 300px); } .post-list { @@ -256,18 +221,50 @@ } } +.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; + margin: 1.3em 0.8em 0; + vertical-align: top; + padding: 0.8em 0.6em 1em; + + font-weight: bold; + font-family: $headings-font-family; + + .post-meta { + color: $header-text-color; + font-size: $small-font-size; + } + + * { + display: inline-block; + margin: 0.3em 0; + } + } +} + .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 +282,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; } +} + +.with-logo { + display: flex; + flex-wrap: wrap; - h4 { - font-size: 20px; + svg { + flex-shrink: 0; + flex-basis: 7em; + margin: 0.3em 1em 0.5em 0; + height: 120px; - @include media-query($on-laptop) { - font-size: 18px; + 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-evenly; + margin-left: 0; + } - > img { - border-radius: 50%; - } + li { + list-style: none; + display: inline-block; + } - &:hover { - background-color: #e5f4ff; - } + + a, a:visited { + @extend .box-design; + font-family: $headings-font-family; + font-weight: 600; + + padding: 0 1em; + 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 --- -
- -

+

Blog @@ -25,11 +23,7 @@

{% for post in site.posts %}
  • - -

    {{ post.title }} -

  • {% endfor %} -

    diff --git a/contact.md b/contact.md new file mode 100644 index 000000000..76d0487d6 --- /dev/null +++ b/contact.md @@ -0,0 +1,13 @@ +--- +layout: default +--- + +# Contact + +For general support use the GNOME Discourse or the Matrix chat. + +{% include contact.html %} + +### 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/faq.md b/docs-src/faq.md deleted file mode 100644 index 544887f4e..000000000 --- a/docs-src/faq.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -layout: default ---- - -# Frequently Asked Questions - -Here are some questions we answered a few times. If one is missing, don't hesitate to open an issue/pull request on the [repository](https://github.com/gtk-rs/gtk-rs.github.io) so it can be added later on. - -## 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! - -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? - -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. - -## I want more **Gtk-rs** examples! - -Please open an issue on the [`gtk-rs` repository](https://github.com/gtk-rs/gtk-rs/). - -## I didn't understand something and the tutorials don't talk about. - -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. - -## Why is documentation just a copy of the C one? - -Considering the massive amount of documentation that would need to be written if we intended to do it ourselves (which is just impossible), we decided to reuse the C one directly. A few improvements are being performed (like generating links between types for instance) and a few more will come later on. - -## 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. - -Currently, documentation is generated as follows: - - * When generating the crate, we also generate its documentation thanks to the GIR files. - * Then we remove all that documentation (using the [rustdoc-stripper](https://github.com/GuillaumeGomez/rustdoc-stripper) tool) from the source files and move it into the [lgpl-docs](https://github.com/gtk-rs/lgpl-docs) repository. - -If you want to have it locally, you'll have to run this command: - -``` -cargo doc --features embed-lgpl-docs -``` - -Don't forget to add the version you're using currently (depending on the crate of course). For example: - -``` -cargo doc --features embed-lgpl-docs v3_22_20 -``` 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/faq.md b/faq.md new file mode 100644 index 000000000..682e9e63b --- /dev/null +++ b/faq.md @@ -0,0 +1,53 @@ +--- +layout: default +--- + +# Frequently Asked Questions + +Here are some questions we answered a few times. If one is missing, don't hesitate to open an issue/pull request on the [repository](https://github.com/gtk-rs/gtk-rs.github.io) so it can be added later on. + +## 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! + +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? + +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! + +You can find more examples in the corresponding respositories + +- [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) + +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? + +Considering the massive amount of documentation that would need to be written if we intended to do it ourselves (which is just impossible), we decided to reuse the C one directly. A few improvements are being performed (like generating links between types for instance) and a few more will come later on. + +## 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. + +Currently, documentation is generated as follows: + + * When generating the crate, we also generate its documentation thanks to the GIR files. + * Then we remove all that documentation (using the [rustdoc-stripper](https://github.com/GuillaumeGomez/rustdoc-stripper) tool) from the source files and move it into the [lgpl-docs](https://github.com/gtk-rs/lgpl-docs) repository. + +If you want to have it locally, you'll have to run this command: + +```sh +cargo install rustdoc-stripper +./generator.py --embed-docs +``` + +You will need rust nightly to build the docs. + +``` +cargo +nightly doc --features dox --no-deps --open +``` diff --git a/gtk.png b/gtk.png deleted file mode 100644 index cb1167554..000000000 Binary files a/gtk.png and /dev/null differ diff --git a/index.md b/index.md index 605031a32..4c15a665a 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 -
    -
    -
    -

    Announcements

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

    - {{ post.title }} -

    - {% endfor %} -
    -
    +
    +{% 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 | +

    +[![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 -## Using +The following table contains the most popular crates of *gtk-rs*. More information on all existing crates is available under the corresponding *Project* links. -First, prepare your system by taking a look at the [GTK installation page](https://www.gtk.org/docs/installations/). +{% include crates.html %} -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 introductory book -__The code is stable and feature complete, but the APIs might change in the future.__ + +
    +
    -fn main() { - let application = Application::new( - Some("com.github.gtk-rs.examples.basic"), - Default::default(), - ).expect("failed to initialize GTK application"); +## Sponsors - application.connect_activate(|app| { - let window = ApplicationWindow::new(app); - window.set_title("First GTK Program"); - window.set_default_size(350, 70); +Thanks to everyone supporting us on [open collective][opencollective]! A list of all sponsors can be seen on our [open collective page][opencollective]. - let button = Button::with_label("Click me!"); - button.connect_clicked(|_| { - println!("Clicked!"); - }); - window.add(&button); - window.show_all(); - }); + - application.run(&[]); -} -~~~ +[opencollective]: https://opencollective.com/gtk-rs -## Using latest, not published version +## Projects using gtk-rs -Include `gtk` in your `Cargo.toml` not as crate but from git: +
    +{% capture projects %}{% include projects.md %}{% endcapture %} +{{ projects | markdownify }} +
    -~~~toml -[dependencies.gtk] -git = "https://github.com/gtk-rs/gtk" -features = ["v3_16"] -~~~ +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. -## 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! +
    diff --git a/logo.svg b/logo.svg new file mode 100644 index 000000000..68da8a1e3 --- /dev/null +++ b/logo.svg @@ -0,0 +1,35 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + +