All posts


Posted On Feb 22, 2023

Opened up the project after a long break, all the code seems to started making more sense, lol.

So I think it would be a good idea to dust it off a little bit.

Save and load files

Now, ASCII-d can save and load from any text file. I guess I’ll go with .txt format from now

There are some problems though:

  1. The file loading is slow on the first load, and become faster on subsequence loads. Not sure why.
  2. The loaded content does not have any shape data, so it would be loaded as a flat string. Still have no idea how to go about this…

But overall, the app is usable enough. I’ll dogfooding for a while and see what can be improved.

Had to update Druid to version v0.8.2. I was planning to stick on 0.7.0 because I don’t want to deal with
API changes, but ran into a serious issue that makes the app crash after opening the Save dialog (druid#2213).

Draw arrowheads

Another update is to switch to arrow drawing instead of just line drawing, picking the right characters to use is a little bit
of a labor work (LOL). Since not all characters will fit nicely to the character grid. Luckily, I was able to (shamelessly)
steal the arrows from the ASCIIflow project.

pub const CHAR_ARROW_DOWN: char = '🭯';
pub const CHAR_ARROW_UP: char = '🭭';
pub const CHAR_ARROW_RIGHT: char = '►';
pub const CHAR_ARROW_LEFT: char = '◄';

The output drawing would look like this:

     │    🭯     

  │ a box !! │  

Support multiple windows

Another update (this is how it looks like to code again after a long break, endless idea!!) is to support multiple windows. Now we can open multiple files
in multiple windows, make it easier for drawing multiple ideas!

Here’s the list of keyboard shortcuts up until this point:

  • MetaO: Open a new file
  • MetaS: Save the current buffer to file
  • MetaC: Copy current buffer content into the Clipboard
  • MetaN: Open a new empty window

In Druid, to support multiple windows, it’s quite straightforward. First, we need a list of opened windows, it can be in the Delegate struct:

struct Delegate {
    windows: Vec<WindowId>,

And also implement the window_added(), window_removed() method to handle adding/removing windows. The app will be closed after the last window is closed:

fn window_added(
    &mut self,
    id: WindowId,
    handle: druid::WindowHandle,
    data: &mut ApplicationState,
    env: &Env,
    ctx: &mut DelegateCtx,
) {;
fn window_removed(
    &mut self,
    id: WindowId,
    data: &mut ApplicationState,
    env: &Env,
    ctx: &mut DelegateCtx,
) {
    if let Some(pos) =|x| *x == id) {;
    if == 0 {
        // Quit when the window is closed