Graphics files
Strategy

Build Great Windows Desktop Apps With Flutter


Let’s build Windows desktop apps with Flutter and Dart.  This example shows how to use Flutter to connect a Windows kiosk or laptop to an external camera with WiFi then transfer and display the images.  I’m using a RICOH THETA Z1 camera to test the application which displays and navigates  23MP images. The 8MB graphic files are a nice test for the Flutter rendering engine on Windows.   

Graphics files

GitHub code repo and additional information is available from this post in the RICOH THETA Developer Community forum

This technique will also work for Linux and MacOS desktops with some modifications for those specific platforms.

The end result is a  zipped file that contains a Windows executable.  You can share the executable with your peers and ask them to test your application and provide feedback.  This application sends HTTP requests to the camera to test the camera API.

HTTP requests

Configure  Windows and Flutter Environment

Set the flutter channel to dev.

dev Flutter channel

Run flutter upgrade after you change the channel to dev.

Install Visual Studio, not just Visual Studio Code.  This is the output of flutter doctor.

Installing Visual Studio

Visual Studio is large.  You only need the Desktop development with C++ workload.  When you install Visual Studio, you will see a screen similar to the one below.  Check on the box for C++ development.

Desktop development with C++

You do not need to use Visual Studio for Flutter development editing when you write your Windows desktop applications.  I use Visual Studio Code for development.  You can use any editor.  You just need to have Visual Studio installed on your development workstation.  I’m using Visual Studio Community edition 2019 16.7.6 in this example.  The specific packages on the right are the default settings when you select Desktop development with C++.

On the command line, run flutter --config --enable-windows-desktop to enable Windows desktop support.

Run flutter devices to confirm that you have a windows device.

At this point, you can access the device similar to an Android or iOS device.  As I only have one device, I can just use flutter run.   If you have more than one device, you need to specify windows with flutter run -d windows.

On a 6 core i7 workstation with 32GB of RAM, it took about 20 seconds for the first build.  You can use hot reload and hot restart during the development process to see your changes quickly.  For the development process, the application runs on the Dart VM.  It is not built as a native Windows executable until the final build and packaging stage when you are ready to distribute your application.

 You can add Flutter widgets into the tree and you do not have to wait for the application to build.  It feels to me like the changes are viewable on the app screen within a second of making a change to the code and saving the change.  If you have the Dart and Flutter extensions installed in your VS Code editor, your app can hot reload automatically whenever you save a change.  This is quite cool and part of the magical feeling of painting the UI with the wonderful Flutter workflow.  

Build for Distribution

 After you finish development or you’ve at least reached a stage where you want to distribute it to your stakeholders for feedback, you need to build the Flutter app for distribution.  Run flutter build windows

The binary will be located in build -> windows -> runner -> Release.

You can double-click on the binary and it will launch.  If you send your new binary application file to your co-worker, it may not run. Don’t worry.  There’s a quick fix.

An easy way to distribute your Windows binary for testing is to copy three libraries from Visual Studio into the same folder that the binary is in. Keep the binary in the same folder that Flutter automatically saved it in.  The binary needs the other files in the folder to run.  Zip the folder and then send it to your tester.  They will need to unzip the folder and double-click on the binary.

The libraries from Visual Studio that you need to include in the folder you distribute the executable on are:

  • msvcp140.dll
  • vcruntime140.dll
  • vcruntime140_1.dll

Search from those three files in your Visual Studio installation directory and then copy them into your Flutter distribution folder.  Your Visual Studio installation directory is likely C:Program Files (x86)Microsoft Visual Studio.

In this example, I’m using the built-in search box on the default Windows 10 file browser.  Simply type in vcruntime140.dll and you can find the location of the library.  You need to copy this into the same folder that your binary is in.  

Repeat the process for the other two libraries.

If you’re working for a business, you may be understandably wondering if it is okay to copy these libraries from Visual Studio.  This technique is documented on the Visual C++ Deployment Examples section of the site. If you need to get authorization, that site is a good starting point for reference information. 

Windows Desktop Limitations

If you narrow the scope of your Windows application and research which Flutter packages aren’t supported on Windows, then you can have fun with a limited feature set. There are many limitations, but I’ll highlight one as an example to give you a feel of what to expect. 

It’s common to use Firebase as a backend for Flutter mobile apps.   This Google service provides authentication, storage, messaging and database access.  The most common way for Flutter to talk to Firebase is with FlutterFire.  Most of the FlutterFire packages will work with Android, iOS, MacOS, and Web.  None of the FlutterFire packages are supported on the Windows desktop as of January, 2020.  This will likely change in time.  Be aware that there are gaps in the package support. 

What Works

In my sample photo application to manage my RICOH THETA camera, I used the following packages:

These packages and many others work fine. There are usually workarounds for missing packages.  For example,  I could use the http package I’m already using in my application to access the Firebase REST API.  However, I’ll more likely focus on local image management and wait for the Windows desktop support to mature.

Conclusion and Recommendations

I’ve been using the Windows desktop for Flutter development every week for several months.  Although it’s in alpha, it is stable enough for testing and prototyping.  I don’t recommend it for production at this time. With the rapid pace of Flutter development, we should see it mature rapidly.  If you’re already using Flutter for mobile development, I recommend reviewing the current state of native desktop applications.  It’s time to put your hand in the game and build something. You’ll be able to use your skills immediately and start showing your coworkers prototypes. 

Perhaps most significantly, the development process can be more fun since you don’t have to deal with iOS simulators or Android emulators. Although the Flutter platform is amazing, I often encounter glitches with graphics or emulator connections on both iOS and Android.   

There are also glitches with the Windows desktop development process and you may encounter problems with Windows-specific OS features.  You need to be mentally ready for these problems and keep a positive attitude!

I’m excited about the potential for Flutter desktop and I’m happy to build my testing apps to gain more experience with desktop layouts and native OS features.  The perfect scenario is to use your Flutter skills to show your boss or stakeholders a concept such as a business kiosk or staff terminal on Windows desktop.  You can have a big emotional impact on your stakeholders by actually showing them your concept running on Windows. 



Source link

r/webdev - CSS Problem - How to make menu sticky but not floating?
Strategy

CSS Problem – How to make menu sticky but not floating? : we…


I have a left sided menu in the head of my website. Sadly the menu is floating over the other content.

Instead, i want it to take up this part of the website and the rest of the content to be placed next to it, not under it.

I know I could just put the menu and the content into the same container, but I would have to remove the menu from the head.

The menu:

#nav_bar {
    background: #181818;
    width: 60px;
    height: 100%;
    position: fixed;
    top: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    z-index: 3;
    min-height: 500px;
}
r/webdev - CSS Problem - How to make menu sticky but not floating?



Source link

A simple heading 1 that says Theme Builder in black on a white background.
Strategy

Theming and Theme Switching with React and styled-components


I recently had a project with a requirement to support theming on the website. It was a bit of a strange requirement, as the application is mostly used by a handful of administrators. An even bigger surprise was that they wanted not only to choose between pre-created themes, but build their own themes. I guess the people want what they want!

Let’s distill that into a complete list of more detailed requirements, then get it done!

  • Define a theme (i.e. background color, font color, buttons, links, etc.)
  • Create and save multiple themes
  • Select and apply a theme
  • Switch themes
  • Customize a theme

We delivered exactly that to our client, and the last I heard, they were using it happily!

Let’s get into building exactly that. We’re going to use React and styled-components. All the source code used in the article can be found in the GitHub Repository.

The setup

Let’s set up a project with React and styled-components. To do that, we will be using the create-react-app. It gives us the environment we need to develop and test React applications quickly.

Open a command prompt and use this command to create the project:

npx create-react-app theme-builder

The last argument, theme-builder, is just the name of the project (and thus, the folder name). You can use anything you like.

It may take a while. When done, navigate it to it in the command line with cd theme-builder. Open the file src/App.js file and replace the content with the following:

import React from 'react';

function App() {
  return (
    <h1>Theme Builder</h1>
  );
}

export default App;

This is a basic React component that we will modify soon. Run the following command from the project root folder to start the app:

# Or, npm run start
yarn start

You can now access the app using the URL http://localhost:3000.

A simple heading 1 that says Theme Builder in black on a white background.

create-react-app comes with the test file for the App component. As we will not be writing any tests for the components as part of this article, you can choose to delete that file.

We have to install a few dependencies for our app. So let’s install those while we’re at it:

# Or, npm i ...
yarn add styled-components webfontloader lodash

Here’s what we get:

  • styled-components: A flexible way to style React components with CSS. It provides out-of-the-box theming support using a wrapper component called, <ThemeProvider>. This component is responsible for providing the theme to all other React components that are wrapped within it. We will see this in action in a minute.
  • Web Font Loader: The Web Font Loader helps load fonts from various sources, like Google Fonts, Adobe Fonts, etc. We will use this library to load fonts when a theme is applied.
  • lodash: This is a JavaScript utility library for some handy little extras.

Define a theme

This is the first of our requirements. A theme should have a certain structure to define appearance, including colors, fonts, etc. For our application, we will define each theme with these properties:

  • unique identifier
  • theme name
  • color definitions
  • fonts
Screenshot of a code editor showing the organized structure of properties for a sea wave theme.
A theme is a structured group of properties that we’ll use in the application.

You may have more properties and/or different ways to structure it, but these are the things we’re going to use for our example.

Create and save multiple themes

So, we just saw how to define a theme. Now let’s create multiple themes by adding a folder in the project at src/theme and a file in it called, schema.json. Here’s what we can drop in that file to establish “light” and “sea wave” themes:

{
  "data" : {
    "light" : {
      "id": "T_001",
      "name": "Light",
      "colors": {
        "body": "#FFFFFF",
        "text": "#000000",
        "button": {
          "text": "#FFFFFF",
          "background": "#000000"
        },
        "link": {
          "text": "teal",
          "opacity": 1
        }
      },
      "font": "Tinos"
    },
    "seaWave" : {
      "id": "T_007",
      "name": "Sea Wave",
      "colors": {
        "body": "#9be7ff",
        "text": "#0d47a1",
        "button": {
          "text": "#ffffff",
          "background": "#0d47a1"
        },
        "link": {
          "text": "#0d47a1",
          "opacity": 0.8
        }
      },
      "font": "Ubuntu"
    }
  }
}

The content of the schema.json file can be saved to a database so we can persist all the themes along with the theme selection. For now, we will simply store it in the browser’s localStorage. To do that, we’ll create another folder at src/utils with a new file in it called, storage.js. We only need a few lines of code in there to set up localStorage:

export const setToLS = (key, value) => {
  window.localStorage.setItem(key, JSON.stringify(value));
}

export const getFromLS = key => {
  const value = window.localStorage.getItem(key);

  if (value) {
    return JSON.parse(value);
  }
}

These are simple utility functions to store data to the browser’s localStorage and to retrieve from there. Now we will load the themes into the browser’s localStorage when the app comes up for the first time. To do that, open the index.js file and replace the content with the following,

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import * as themes from './theme/schema.json';
import { setToLS } from './utils/storage';

const Index = () => {
  setToLS('all-themes', themes.default);
  return(
    <App />
  )
}

ReactDOM.render(
  <Index />
  document.getElementById('root')
);

Here, we are getting the theme information from the schema.json file and adding it to the localStorage using the key all-themes. If you have stopped the app running, please start it again and access the UI. You can use DevTools in the browser to see the themes are loaded into localStorage.

The theme with DevTools open and showing the theme properties in the console.
All of the theme props are properly stored in the browser’s localStorage, as seen in DevTools, under Application → Local Storage.

Select and apply a theme

We can now use the theme structure and supply the theme object to the <ThemeProvider> wrapper.

First, we will create a custom React hook. This will manage the selected theme, knowing if a theme is loaded correctly or has any issues. Let’s start with a new useTheme.js file inside the src/theme folder with this in it:

import { useEffect, useState } from 'react';
import { setToLS, getFromLS } from '../utils/storage';
import _ from 'lodash';

export const useTheme = () => {
  const themes = getFromLS('all-themes');
  const [theme, setTheme] = useState(themes.data.light);
  const [themeLoaded, setThemeLoaded] = useState(false);

  const setMode = mode => {
    setToLS('theme', mode)
    setTheme(mode);
  };

  const getFonts = () => {
    const allFonts = _.values(_.mapValues(themes.data, 'font'));
    return allFonts;
  }

  useEffect(() =>{
    const localTheme = getFromLS('theme');
    localTheme ? setTheme(localTheme) : setTheme(themes.data.light);
    setThemeLoaded(true);
  }, []);

  return { theme, themeLoaded, setMode, getFonts };
};

This custom React hook returns the selected theme from localStorage and a boolean to indicate if the theme is loaded correctly from storage. It also exposes a function, setMode, to apply a theme programmatically. We will come back to that in a bit. With this, we also get a list of fonts that we can load later using a web font loader.

It would be a good idea to use global styles to control things, like the site’s background color, font, button, etc. styled-components provides a component called, createGlobalStyle that establishes theme-aware global components. Let’s set those up in a file called, GlobalStyles.js in the src/theme folder with the following code:

import { createGlobalStyle} from "styled-components";

export const GlobalStyles = createGlobalStyle`
  body {
    background: ${({ theme }) => theme.colors.body};
    color: ${({ theme }) => theme.colors.text};
    font-family: ${({ theme }) => theme.font};
    transition: all 0.50s linear;
  }

  a {
    color: ${({ theme }) => theme.colors.link.text};
    cursor: pointer;
  }

  button {
    border: 0;
    display: inline-block;
    padding: 12px 24px;
    font-size: 14px;
    border-radius: 4px;
    margin-top: 5px;
    cursor: pointer;
    background-color: #1064EA;
    color: #FFFFFF;
    font-family: ${({ theme }) => theme.font};
  }

  button.btn {
    background-color: ${({ theme }) => theme.colors.button.background};
    color: ${({ theme }) => theme.colors.button.text};
  }
`;

Just some CSS for the <body>, links and buttons, right? We can use these in the App.js file to see the theme in action by replace the content in it with this:

// 1: Import
import React, { useState, useEffect } from 'react';
import styled, { ThemeProvider } from "styled-components";
import WebFont from 'webfontloader';
import { GlobalStyles } from './theme/GlobalStyles';
import {useTheme} from './theme/useTheme';

// 2: Create a cotainer
const Container = styled.div`
  margin: 5px auto 5px auto;
`;

function App() {
  // 3: Get the selected theme, font list, etc.
  const {theme, themeLoaded, getFonts} = useTheme();
  const [selectedTheme, setSelectedTheme] = useState(theme);

  useEffect(() => {
    setSelectedTheme(theme);
   }, [themeLoaded]);

  // 4: Load all the fonts
  useEffect(() => {
    WebFont.load({
      google: {
        families: getFonts()
      }
    });
  });

  // 5: Render if the theme is loaded.
  return (
    <>
    {
      themeLoaded && <ThemeProvider theme={ selectedTheme }>
        <GlobalStyles/>
        <Container style={{fontFamily: selectedTheme.font}}>
          <h1>Theme Builder</h1>
          <p>
            This is a theming system with a Theme Switcher and Theme Builder.
            Do you want to see the source code? <a href="https://github.com/atapas/theme-builder" target="_blank">Click here.</a>
          </p>
        </Container>
      </ThemeProvider>
    }
    </>
  );
}

export default App;

A few things are happening here:

  1. We import the useState and useEffect React hooks which will help us to keep track of any of the state variables and their changes due to any side effects. We import ThemeProvider and styled from styled-components. The WebFont is also imported to load fonts. We also import the custom theme, useTheme, and the global style component, GlobalStyles.
  2. We create a Container component using the CSS styles and styled component.
  3. We declare the state variables and look out for the changes.
  4. We load all the fonts that are required by the app.
  5. We render a bunch of text and a link. But notice that we are wrapping the entire content with the <ThemeProvider> wrapper which takes the selected theme as a prop. We also pass in the <GlobalStyles/> component.

Refresh the app and we should see the default “light” theme enabled.

The theme with a white background and black text.
Hey, look at that clean, stark design!

We should probably see if switching themes works. So, let’s open the useTheme.js file and change this line:

localTheme ? setTheme(localTheme) : setTheme(themes.data.light);

…to:

localTheme ? setTheme(localTheme) : setTheme(themes.data.seaWave);

Refresh the app again and hopefully we see the “sea wave” theme in action.

The same theme in with a blue color scheme with a light blue background and dark blue text and a blue button.
Now we’re riding the waves of this blue-dominant theme.

Switch themes

Great! We are able to correctly apply themes. How about creating a way to switch themes just with the click of a button? Of course we can do that! We can also provide some sort of theme preview as well.

A heading instructs the user to select a theme and two card components are beneath the heading, side-by-side, showing previews of the light theme and the sea wave theme.
A preview of each theme is provided in the list of options.

Let’s call each of these boxes a ThemeCard, and set them up in a way they can take its theme definition as a prop. We’ll go over all the themes, loop through them, and populate each one as a ThemeCard component.

{
  themes.length > 0 && 
  themes.map(theme =>(
    <ThemeCard theme={data[theme]} key={data[theme].id} />
  ))
}

Now let’s turn to the markup for a ThemeCard. Yours may look different, but notice how we extract its own color and font properties, then apply them:

const ThemeCard = props => {
  return(
    <Wrapper 
      style={{backgroundColor: `${data[_.camelCase(props.theme.name)].colors.body}`, color: `${data[_.camelCase(props.theme.name)].colors.text}`, fontFamily: `${data[_.camelCase(props.theme.name)].font}`}}>
      <span>Click on the button to set this theme</span>
      <ThemedButton
        onClick={ (theme) => themeSwitcher(props.theme) }
        style={{backgroundColor: `${data[_.camelCase(props.theme.name)].colors.button.background}`, color: `${data[_.camelCase(props.theme.name)].colors.button.text}`, fontFamily: `${data[_.camelCase(props.theme.name)].font}`}}>
        {props.theme.name}
      </ThemedButton>
    </Wrapper>
  )
}

Next up, let’s create a file called ThemeSelector.js in our the src folder. Copy the content from here and drop it into the file to establish our theme switcher, which we need to import in App.js:

import ThemeSelector from './ThemeSelector';

Now we can use it inside the Container component:

<Container style={{fontFamily: selectedTheme.font}}>
  // same as before
  <ThemeSelector setter={ setSelectedTheme } />
</Container>

Let’s refresh the browser now and see how switching themes works.

An animated screenshot showing the theme changing when it is selected from the list of theme card options.

The fun part is, you can add as many as themes in the schema.json file to load them in the UI and switch. Check out this schema.json file for some more themes. Please note, we are also saving the applied theme information in localStorage, so the selection will be retained when you reopen the app next time.

Selected theme stored in the Local Storage.

Customize a theme

Maybe your users like some aspects of one theme and some aspects of another. Why make them choose between them when they can give them the ability to define the theme props themselves! We can create a simple user interface that allows users to select the appearance options they want, and even save their preferences.

Animated screenshot showing a modal opening with a list of theme options to customize the appearance, including the them name, background color, text color, button text color, link color, and font.

We will not cover the theme creation code explanation in details but, it should be easy by following the code in the GitHub Repo. The main source file is CreateThemeContent.js and it is used by App.js. We create the new theme object by gathering the value from each input element change event and add the object to the collection of theme objects. That’s all.

Before we end…

Thank you for reading! I hope you find what we covered here useful for something you’re working on. Theming systems are fun! In fact, CSS custom properties are making that more and more a thing. For example, check out this approach for color from Dieter Raber and this roundup from Chris. There’s also this setup from Michelle Barker that relies on custom properties used with Tailwind CSS. Here’s yet another way from Andrés Galente.

Where all of these are great example for creating themes, I hope this article helps take that concept to the next level by storing properties, easily switching between themes, giving users a way to customize a theme, and saving those preferences.

Let’s connect! You can DM me on Twitter with comments, or feel free to follow.





Source link

Post image
Strategy

Stuck! ‘f’ logo : graphic_design


Can you tell what this ‘f’ logo is without context?

It’s only for a personal project but I want it to be good enough for a multi-million $ company!

Clue as to the subject it is for, in links below.

it was born out of pen and paper but you can see how it has evolved from this ://ibb.co/zHyCY5F

It will in some cases be paired with the rest of the word that follows however I want it to be able to stand (lol) on it’s own, too https://ibb.co/kh1NvfN

Bottom right is where it’s at so far https://ibb.co/wgkcXmxAm i right to have gone from the brush stroke to a typeface? Also I’ve tried to find if this idea has already been done (which is usually the case) but i couldn’t find any instance, the nearest thing I suppose I was going for is kind of this shorturl.at/bpHM1 but that looks way too complex lol

Any help/feedback will be greatly appreciated!!! I’m more conceptual and I absolutely loathe logo design!!

And is there any other/better subreddit for this?

Thank you in advance

Post image



Source link

r/webdev - How to decrease global TTFB?
Strategy

How to decrease global TTFB? : webdev


My WordPress sites are hosted on Cloudways with a DigitalOcean droplet (New York).

I’ve one site that gets most of the traffic from India and Singapore. And in these regions, TTFB is very high.

r/webdev - How to decrease global TTFB?

Now, I don’t want to buy a new server just for one site. I’m already using BunnyCDN, but that only works for static resources. The problem is TTFB here.

Just like we have CDN for static resources, is there any caching solution for DNS as well? So that it resolves fast globally?

Or any other way to lower the TTFB down?

Thanks



Source link