slint 1.4.0

GUI toolkit to efficiently develop fluid graphical user interfaces for embedded devices and desktop applications
Documentation
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Introduction - Slint Memory Game Tutorial (node)</title>


        <!-- Custom HTML head -->
        <!--
            This file is used to add syntax highlighting of the `.slint` snippets in the generated rustdoc, sphinx and mdbook documentation.
            It can be injected via the `--html-in-header slint-docs-highlight.html` option of rustdoc, is included via _templates/layout.html
            in sphinx and via head.hbs in mdbook.
        -->
        <link rel="stylesheet" href="https://slint.dev/resources/highlightjs/11.0.1/default.min.css">
        <script src="https://slint.dev/resources/highlightjs/11.0.1/highlight.min.js"></script>
        <script>
          function highlight_slint(hljs) {
            const KEYWORDS = {
              keyword:
                "animate callback component export for function global if import in in-out inherits out parent private property public pure root self signal states struct transitions",
              literal: "false true",
              built_in:
                "ArcTo Clip Close Colors CubicTo Flickable FocusScope GridLayout HorizontalLayout Image LineTo Math MoveTo Path PopupWindow QuadraticTo Rectangle Row Text TextInput TouchArea VerticalLayout Window animation-tick debug",
              type: "bool duration easing float int length logical_length relative-font-size resource string",
            };
        
            return {
              name: 'slint',
              case_insensitive: false,
              keywords: KEYWORDS,
              contains: [
                hljs.QUOTE_STRING_MODE,
                hljs.C_LINE_COMMENT_MODE,
                hljs.C_BLOCK_COMMENT_MODE,
                hljs.COMMENT('/\\*', '\\*/', {
                  contains: ['self']
                }),
                {
                  className: 'number',
                  begin: '\\b\\d+(\\.\\d+)?(\\w+)?',
                  relevance: 0
                },
                {
                  className: 'title',
                  begin: '\\b[_a-zA-Z][_\\-a-zA-Z0-9]* *:=',
                },
                {
                  className: 'symbol',
                  begin: '\\b[_a-zA-Z][_\\-a-zA-Z0-9]*(:| *=>)',
                },
                {
                  className: 'built_in',
                  begin: '\\b[_a-zA-Z][_\\-a-zA-Z0-9]*!',
                },
              ],
              illegal: /@/
            };
          };
        
          // Tags used in fenced code blocks
          for (let tag of ["slint", "slint,no-preview", "slint,no-auto-preview", "slint,ignore"]) {
            hljs.registerLanguage(tag, highlight_slint);
          }
        
        
          window.addEventListener("DOMContentLoaded", () => {
            const rustDoc = document.querySelector('meta[name="generator"]')?.content == "rustdoc";
            if (rustDoc) {
              // Only highlight .slint blocks, leave the others to rustdoc
              for (slintBlock of document.querySelectorAll("[class*=language-slint]")) {
                hljs.highlightElement(slintBlock)
              }
        
              // Some of the rustdoc selectors require the pre element to have the rust class
              for (codeBlock of document.querySelectorAll(".language-slint.hljs")) {
                codeBlock.parentElement.classList.add("rust")
              }
        
              // Change the hljs generated classes to the rustdoc
              // ones, so that the highlighting adjusts to the theme correctly.
              const highlightJSToRustDoc = [
                ["comment", "comment"],
                ["number", "number"],
                ["symbol", "struct"], // width:
                ["keyword", "kw"],
                ["built_in", "primitive"],
                ["string", "string"],
                ["title", "fnname"], // Foo :=
                ["type", "type"]
              ];
        
              for ([hljs_class, rustdoc_class] of highlightJSToRustDoc) {
                for (titleElement of document.querySelectorAll(`.hljs-${hljs_class}`)) {
                  titleElement.classList.remove(`hljs-${hljs_class}`);
                  titleElement.classList.add(rustdoc_class);
                }
              }
            } else {
              // For use with the mdbook Tutorial
              hljs.highlightAll();
        
              // The Sphinx/my_st generated HTML for code blocks doesn't use <code> tags, so highlight.js'
              // default selector "pre code" doesn't match. Let's do it by hand:
              for (block of document.querySelectorAll("div[class*=highlight-slint] div.highlight pre")) {
                hljs.highlightElement(block)
              }
            }
          });
        </script>

        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="favicon.svg">
        <link rel="shortcut icon" href="favicon.png">
        <link rel="stylesheet" href="css/variables.css">
        <link rel="stylesheet" href="css/general.css">
        <link rel="stylesheet" href="css/chrome.css">
        <link rel="stylesheet" href="css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="highlight.css">
        <link rel="stylesheet" href="tomorrow-night.css">
        <link rel="stylesheet" href="ayu-highlight.css">

        <!-- Custom theme stylesheets -->

    </head>
    <body>
    <div id="body-container">
        <!-- Provide site root to javascript -->
        <script>
            var path_to_root = "";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script>
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script>
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script>
            var html = document.querySelector('html');
            var sidebar = null;
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            } else {
                sidebar = 'hidden';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html" class="active"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="getting_started.html"><strong aria-hidden="true">2.</strong> Getting Started</a></li><li class="chapter-item expanded "><a href="memory_tile.html"><strong aria-hidden="true">3.</strong> Memory Tile</a></li><li class="chapter-item expanded "><a href="polishing_the_tile.html"><strong aria-hidden="true">4.</strong> Polishing the Tile</a></li><li class="chapter-item expanded "><a href="from_one_to_multiple_tiles.html"><strong aria-hidden="true">5.</strong> From One To Multiple Tiles</a></li><li class="chapter-item expanded "><a href="creating_the_tiles_from_js.html"><strong aria-hidden="true">6.</strong> Creating The Tiles From JavaScript</a></li><li class="chapter-item expanded "><a href="game_logic_in_js.html"><strong aria-hidden="true">7.</strong> Game Logic In JavaScript</a></li><li class="chapter-item expanded "><a href="ideas_for_the_reader.html"><strong aria-hidden="true">8.</strong> Ideas For The Reader</a></li><li class="chapter-item expanded "><a href="conclusion.html"><strong aria-hidden="true">9.</strong> Conclusion</a></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky bordered">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Slint Memory Game Tutorial (node)</h1>

                    <div class="right-buttons">
                        <a href="print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script>
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <!-- Copyright © SixtyFPS GmbH <info@slint.dev> ; SPDX-License-Identifier: MIT -->
<h1 id="introduction"><a class="header" href="#introduction">Introduction</a></h1>
<p>This tutorial will introduce you to the Slint UI framework in a playful way by implementing a little memory game. We're going to combine the <code>.slint</code> language for the graphics with the game rules implemented in JavaScript.</p>
<p>The game consists of a grid of 16 rectangular tiles. Clicking on a tile uncovers an icon underneath.
We know that there are 8 different icons in total, so each tile has a sibling somewhere in the grid with the
same icon. The objective is to locate all icon pairs. You can uncover two tiles at the same time. If they
aren't the same, the icons will be obscured again.
If you uncover two tiles with the same icon, then they remain visible - they're solved.</p>
<p>This is how the game looks like in action:</p>
<p><video autoplay loop muted playsinline src="https://slint.dev/blog/memory-game-tutorial/memory_clip.mp4"
        class="img-fluid img-thumbnail rounded"></video></p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->

                            <a rel="next" href="getting_started.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">

                    <a rel="next" href="getting_started.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>




        <script>
            window.playground_copyable = true;
        </script>


        <script src="elasticlunr.min.js"></script>
        <script src="mark.min.js"></script>
        <script src="searcher.js"></script>

        <script src="clipboard.min.js"></script>
        <script src="highlight.js"></script>
        <script src="book.js"></script>

        <!-- Custom JS scripts -->


    </div>
    </body>
</html>