Skip to content

App Development

Jspa2 edited this page Dec 21, 2022 · 8 revisions

App Development

Introduction

In this guide, we will provide an overview of how to develop graphical applications for SphereOS. We will cover the fundamentals of windows, processes, and provide a sample application to help you get started. This guide is intended for those who already have a basic understanding of the C# programming language and Cosmos. By the end of this guide, you should have a solid foundation for creating your own graphical applications on SphereOS.

Development Environment

To begin developing graphical applications for SphereOS, you will first need to clone the SphereOS repository from GitHub. This can be done using the following command:

git clone https://github.com/Project-Sphere/SphereOS

This will download the source code of the SphereOS operating system to your local machine.

Next, open the downloaded repository in Visual Studio 2022. This will allow you to edit and build the source code of the operating system. It is important to note that to create applications for SphereOS, you must work directly on the source code of the operating system itself. At this time, there is no support for creating standalone executables that can be run on SphereOS.

Understanding Windows

Windows are the foundation of graphical applications on SphereOS. A window is a rectangular area on the screen that can be used to display graphical content and interact with the user. Windows have a location and size on the screen, and they provide a back buffer where graphical content can be drawn and stored before it is displayed on the screen.

Contrary to what you might expect, all GUI controls on SphereOS are implemented as windows. This means that even a simple dialogue box is actually made up of multiple windows, each with its own location and size on the screen. For example, a dialogue box might be made up of a main window for the box itself, a child window for the title bar at the top, and a child window for the 'OK' button.

Using windows as the building blocks for graphical applications allows for a high degree of flexibility and customisation. It also makes it possible to create complex user interfaces with a hierarchical structure, where windows can be nested inside other windows to create parent-child relationships.

Titlebars are generated by the AppWindow class, which is a subclass of the Window class. AppWindows automatically update their titlebar when the title is changed.

Processes

Processes are a fundamental concept in the SphereOS operating system. They are used to manage the lifecycle of an application, including its startup, running, and shutdown. Processes are managed by the ProcessManager, which is a central component of the operating system that is responsible for keeping track of all the processes that are currently running.

When you develop an application for SphereOS, you create a new class that extends the Process class from the SphereOS.Core namespace. This class defines the behavior of your application, including its startup, running, and shutdown procedures. For example, you might create your application's windows in the Start method of your Process subclass, check for changes in the Run method, and clean up in the Stop method.

This is an example process:

using SphereOS.Core; // Import the SphereOS Core namespace

namespace SphereOS.Gui.Apps
{
    // Define a new class called MyApp that extends the Process class
    internal class MyApp : Process
    {
        // Define the constructor for the MyApp class
        internal MyApp() : base("MyApp", ProcessType.Application) { }

        // Override the Start method of the Process class
        internal override void Start()
        {
            base.Start();

            // Code here will be run when the app starts.
        }

        // Override the Run method of the Process class
        internal override void Run()
        {
            // Code here will be run repeatedly.
        }

        // Override the Stop method of the Process class
        internal override void Stop()
        {
            base.Stop();

            // Code here will be run when the app stops.
        }
    }
}

The Process class has several parameters that define information about the process, such as its name and whether it is an application or a service. These parameters are used by the ProcessManager to identify and manage your process.

Sample Application

This code creates a simple graphical application that displays a window with the text "Hello World!" and a button labeled "OK". When the button is clicked, the window is removed from the screen. The application uses the AppWindow and Button classes from the SphereOS.Gui.UILib namespace to create the user interface, and it uses the WindowManager class from the SphereOS.Core namespace to manage the windows on the screen. The MyApp class extends the Process class from the SphereOS.Core namespace, and it overrides the Start and Run methods to define the behavior of the application.

Overall, this code provides a complete implementation of a simple graphical application that can be run on SphereOS. It creates a window, draws text and graphics to the window, and handles user input through a button.

You can use this as a template for your app.

using SphereOS.Core; // Import the SphereOS Core namespace
using SphereOS.Gui.UILib; // Import the SphereOS GUI library namespace
using System.Drawing; // Import the System.Drawing namespace

namespace SphereOS.Gui.Apps
{
    // Define a new class called MyApp that extends the Process class
    internal class MyApp : Process
    {
        // Define the constructor for the MyApp class
        internal MyApp() : base("MyApp", ProcessType.Application) { }

        // Declare a field to store the application's main window
        AppWindow window;

        // Declare a field to store the WindowManager object
        WindowManager wm = ProcessManager.GetProcess<WindowManager>();

        // Override the Start method of the Process class
        internal override void Start()
        {
            // Call the Start method of the base Process class
            base.Start();

            // Create a new AppWindow object for the application
            window = new AppWindow(this, 256, 256, 320, 256);

            // Add the AppWindow to the WindowManager
            wm.AddWindow(window);

            // Set the title of the AppWindow
            window.Title = "My App";

            // Set the Closing event handler of the AppWindow
            window.Closing = TryStop;

            // Clear the AppWindow with a light grey color
            window.Clear(Color.LightGray);

            // Draw the string "Hello World!" to the AppWindow
            window.DrawString("Hello World!", System.Drawing.Color.White, 12, 12);

            // Create a new Button object for the AppWindow
            Button button = new Button(window, window.Width - 80 - 12, window.Height - 20 - 12, 80, 20);

            // Set the text of the Button
            button.Text = "OK";

            // Set the OnClick event handler of the Button
            button.OnClick = (int x, int y) =>
            {
                // When the Button is clicked, remove the AppWindow from the WindowManager
                wm.RemoveWindow(window);
            };

            // Add the Button to the WindowManager
            wm.AddWindow(button);

            // Update the WindowManager with the changes to the AppWindow
            wm.Update(window);
        }

        // Override the Run method of the Process class
        internal override void Run()
        {
            // The Run method is empty in this implementation, as there is no need
            // to update the application's user interface or handle user input
            // while the application is running.
        }
    }
}

Registering Your App

To finish creating your application, you will need to register it with the AppManager. This is done by adding a line of code to the LoadAllApps method in the Gui/AppManager.cs file. This method is called when the GUI starts up, and it is responsible for registering all the available applications.

// Register a new application called 'MyApp' with the AppManager
RegisterApp(new App("MyApp", () => { return new MyApp(); }, Icons.Icon_Default, Color.FromArgb(0, 161, 255)));

This line of code uses the RegisterApp method to register a new application with the AppManager. The RegisterApp method takes an instance of the App class as an argument, which specifies the details of the application to be registered.

The App class takes several arguments in its constructor: a string representing the name of the application, a delegate that returns an instance of the Process subclass that implements the application, a Bitmap representing the icon to be used for the application, and a Color object representing the theme colour of the application.

In this case, the App constructor is called with the following arguments:

  • The name of the application is 'MyApp'.
  • The delegate returns a new instance of the MyApp class, which is the Process subclass that implements the application.
  • The icon for the application is specified by the Icons.Icon_Default Bitmap, which represents the default application icon.
  • The theme colour of the application window is specified by the Color.FromArgb(0, 161, 255) method, which creates a colour with red, green, and blue values of 0, 161, and 255, respectively.
Clone this wiki locally