|
| 1 | +/* |
| 2 | +Dosktop is a package which allow users to easily create rich text-based terminal |
| 3 | +applications and games. Dosktop differs from other terminal packages by |
| 4 | +providing an extremely simple API that abstracts out all low-level terminal |
| 5 | +operations, while avoiding complicated event-driven TUI designs. |
| 6 | +
|
| 7 | +The BASICs |
| 8 | +
|
| 9 | +If your familiar with programming on classical computers and OS environments |
| 10 | +like the Commodore 64 or MS-DOS, you will find that Dosktop behaves similar |
| 11 | +to these systems. Dosktop is a procedural package that gives users control |
| 12 | +over the terminal with simple BASIC-like commands. It maintains this |
| 13 | +simplicity by managing much of it's functionality and resources internally. |
| 14 | +While users do not need to keep track of these resources themselves, there |
| 15 | +are still a few concepts they need to be familiar with. |
| 16 | +
|
| 17 | +Aliases |
| 18 | +
|
| 19 | +Aliases are a way for a user to reference a resource in Dosktop without |
| 20 | +actually needing to manage and store it themselves. Things like creating |
| 21 | +a text layer, a button, or a timer, all use aliases to identify what the |
| 22 | +user creates and how they can reference that resource at a later time. |
| 23 | +For example: |
| 24 | +
|
| 25 | + // Create a new text layer with the layer alias "Foreground", placed at |
| 26 | + // screen location (0, 0), with a width and height of 20x20 characters, |
| 27 | + // a zOrder drawing priority of 0, with no parent layer associated with it. |
| 28 | + dosktop.AddLayer("Foreground", 0, 0, 20, 20, 0, "") |
| 29 | +
|
| 30 | +Once created, the user no longer needs to manage the resource. If they |
| 31 | +wish to manipulate it, they simply need to reference the Alias they want |
| 32 | +to access. For example: |
| 33 | +
|
| 34 | + // Move the text layer with the alias "Foreground" to screen X and Y |
| 35 | + // location (2, 2). |
| 36 | + dosktop.MoveLayerByAbsoluteValue("Foreground", 2, 2) |
| 37 | +
|
| 38 | +Furthermore, an alias is always unique and distinct for any given |
| 39 | +resource. That means, while it is not recommended, it is possible to give |
| 40 | +two different types of resources the same alias name. For example: |
| 41 | +
|
| 42 | + // Create a timer with the timer alias "MyAliasName", with a duration of |
| 43 | + // 1000 milliseconds, with it's enabled status as being "true". |
| 44 | + dosktop.AddTimer("Foreground", 1000, true) |
| 45 | +
|
| 46 | +Now we have a layer that has an alias called "Foreground" and a timer |
| 47 | +that has an alias called "Foreground". |
| 48 | +
|
| 49 | +Attribute Entries |
| 50 | +
|
| 51 | +Often when working with software, flexibility comes at the expense of |
| 52 | +simplicity. Having methods with dozens of options and parameters makes |
| 53 | +functionality more flexible, but also much more difficult to manage and |
| 54 | +understand. That's why to keep things simple, Dosktop uses Attribute Entries |
| 55 | +for configuring most customizable features. Attribute Entries are simply |
| 56 | +structures that hold all kinds of information about how the user would like for |
| 57 | +something to operate. By simply generating an entry, configuring it, and |
| 58 | +passing it in as a parameter, functionality will automatically know how to |
| 59 | +behave if one should want to do something outside the default. In addition, |
| 60 | +if you want a feature to behave differently under specific cases, you can |
| 61 | +configure multiple attribute entries and simply provide which one you need at |
| 62 | +any given time. For example: |
| 63 | +
|
| 64 | + // Create a style entry which lets you configure most TUI related features. |
| 65 | + styleEntry := dosktop.NewTuiStyleEntry() |
| 66 | +
|
| 67 | + // Configure the foreground color to use when rendering TUI buttons. |
| 68 | + styleEntry.ButtonForegroundColor = dosktop.GetRGBColor(0, 255, 0) |
| 69 | +
|
| 70 | + // Add a button to a layer with the alias called "Foreground", with a |
| 71 | + // button alias called "OkButton", with a button label of "OK", with |
| 72 | + // our created style entry, with a layer location of (2,2), with |
| 73 | + // a button width and height of 10x3 characters. |
| 74 | + dosktop.AddButton("Foreground", "OkButton", "OK", styleEntry, 2, 2, 10, 3) |
| 75 | +
|
| 76 | +You will note that not all style attributes need to be set. Any attributes |
| 77 | +which are not modified will be left at their default settings. In addition, |
| 78 | +if you wish to quickly create multiple attribute entries based off a single |
| 79 | +one, you can simply do the following: |
| 80 | +
|
| 81 | + // Create a new text style entry for printing text dialog messages. |
| 82 | + defaultTextStyle := dosktop.NewTextStyleEntry() |
| 83 | +
|
| 84 | + // Configure some attributes for our new entry. |
| 85 | + defaultTextStyle.ForegroundColor = dosktop.GetRGBColor(255, 0, 0) |
| 86 | +
|
| 87 | + // Create a new text style entry by cloning an existing style entry. |
| 88 | + boldTextStyle := dosktop.NewTuiStyleEntry(defaultTextStyle) |
| 89 | +
|
| 90 | + // Set our new style to include the bold attribute |
| 91 | + defaultTextStyle.isBold = true |
| 92 | +
|
| 93 | +As you can see, cloning attribute entries is a speedy way to configure |
| 94 | +multiple items with similar base settings. |
| 95 | +
|
| 96 | +Failing Fast |
| 97 | +
|
| 98 | +Almost all functionality in Dosktop is designed to perform consistently. |
| 99 | +That is, it will perform most tasks predictably without external runtime |
| 100 | +conditions changing its behaviour. As a result, when a problem occurs |
| 101 | +Dosktop will usually prefer to throw a Panic rather than choose an alternative |
| 102 | +solution or throw an error. This is because any problems encountered will |
| 103 | +generally be a developer issue and it should be addressed rather than covered |
| 104 | +up or hidden by default behaviour. For example: |
| 105 | +
|
| 106 | + // Attempt to initialize Dosktop with a terminal size of (-1, 0) |
| 107 | + dosktop.InitializeTerminal(-1, 0) |
| 108 | +
|
| 109 | +In this case, the user is attempting to create a terminal session with |
| 110 | +invalid dimensions. Rather than choose a sane default or return a recoverable |
| 111 | +error, Dosktop will panic since clearly the developer made an error and should |
| 112 | +correct it. For functionality that could vary depending on runtime conditions, |
| 113 | +errors will be returned as expected. |
| 114 | +
|
| 115 | +Double buffering |
| 116 | +
|
| 117 | +When updating the screen with with rapid changes or changes that may take a |
| 118 | +long time, it is desirable to wait until all drawing is completed before |
| 119 | +performing a refresh. This allows you to eliminate flickering, screen |
| 120 | +tearing, or other artifacts that may appear when display data is being |
| 121 | +updated at the same time as a screen refresh. In Dosktop, all changes to |
| 122 | +the terminal remain in memory until the user calls 'UpdateDisplay' to refresh |
| 123 | +the screen. This allows the user to make as many changes as they want before |
| 124 | +writing their changes to screen in a single pass. |
| 125 | +*/ |
| 126 | +package dosktop |
| 127 | + |
0 commit comments