Commit Graph

1072 Commits

Author SHA1 Message Date
Isaiah Odhner
400c6b4251 Automatically add .ans file extension when bare filename is entered
This applies to Save As and Copy To dialogs, but not the CLI.
2023-05-16 14:43:01 -04:00
Isaiah Odhner
cdf30c49f9 Fix 103 type checker errors by annotating height (and not width) 2023-05-16 14:43:01 -04:00
Isaiah Odhner
e045e6e9f9 Handle backup files (*~) when guessing format from file extension 2023-05-16 14:42:23 -04:00
Isaiah Odhner
9f9974fc48 Generalize --recode-samples to look for files of all types, recursively 2023-05-16 14:42:23 -04:00
Isaiah Odhner
62e313c2db Ignore temporary backup files (*~) 2023-05-16 14:35:00 -04:00
Isaiah Odhner
1a9c079f7e Use format IDs for custom formats; show "Unknown file extension" instead of assuming ANSI 2023-05-16 14:35:00 -04:00
Isaiah Odhner
f5d97912b6 Design transparent/opaque options UI ANSI art
This is a first draft (or first 13 versions) of an ANSI art rendition of
MS Paint's transparent/opaque option selector used for the Select and
Text tools.

A somewhat silly smattering of notes:

- Emoji representation: 🛢️🔴🧊 or 🛢️🔴🟩
- More symbols considered (and some used):
  ⛀⛁⛃🛢️⬬
  ▰𝄰ᐟ⸍⸝🧊
  ╭╮🔴⏺◖◗
  ╰╯
- The red circle seems really unreliable so I don't think I can use it.
- Overlapping the red circle/sphere object is hard to represent!
- I managed to get something fairly legible in Ubuntu's terminal,
  not so much in VS Code. VS Code is harder; I might've modified some
  settings, I don't know, but it doesn't handle semigraphics as well,
  at least not on my computer. But...
- At least if you've used MS Paint before, you can recognize the general
  color/shape profile of the icons, if not parse out what the icons are
  meant to represent if you'd never looked closely at them before.
- I'm not sure if v12 or v13 is better. I moved the right border to the
  right a bit by making it Braille, but should the corners extend
  further right then (with two dots), or mirror the left border by using
  a single dot Braille character?
2023-05-16 02:47:32 -04:00
Isaiah Odhner
004700ad57 Add more unicode alternatives 2023-05-16 02:30:10 -04:00
Isaiah Odhner
79cbeb9e30 Fix corrupted upper left pixel in sample file
(This bug has since been fixed.)
2023-05-16 02:30:10 -04:00
Isaiah Odhner
7bc86bc483 Fix error handling for decode_based_on_file_extension
- UnicodeDecodeError was caught in a more general error handler;
  now it's allowed to reach the more specific handler.
- UnidentifiedImageError and FormatReadNotSupported were missing return;
  now it's not caught there so it doesn't need to, as the exception will
  interrupt the control flow.
2023-05-15 16:05:10 -04:00
Isaiah Odhner
9ad1933310 Improve error handling for unsupported format reading/writing 2023-05-15 15:42:41 -04:00
Isaiah Odhner
1cd6b24e33 Don't close Copy To dialog if there's an error 2023-05-15 15:05:03 -04:00
Isaiah Odhner
c24c164004 Add error handling to Save As for encode_based_on_file_extension 2023-05-15 15:03:58 -04:00
Isaiah Odhner
9653bfd9d8 Handle file extensions vs PIL format IDs
They usually correspond very closely, like .png -> PNG, but are
are more distinct for some formats, like .jp2 -> JPEG2000.

- Handle formats like JPEG2000 that differ in name from the extension.
- Bring my own file ext handling in line with PIL: use dotted lowercase.
- Raise an exception when a file format is detected but not supporting
  for reading or for writing, depending on the attempted operation.
2023-05-15 15:03:42 -04:00
Isaiah Odhner
1176fcee73 Save WebP files losslessly 2023-05-15 14:23:55 -04:00
Isaiah Odhner
4dbaf5145e Open and save image files with Pillow 2023-05-15 00:46:08 -04:00
Isaiah Odhner
e1185a0c21 Add spellings and adjust spell checker configuration 2023-05-15 00:15:49 -04:00
Isaiah Odhner
26e077bce3 Unify docstring formatting according to PEP 257
I used this regexp to search for multi-line docstrings: """.*(?<!""")\n

Here's a regexp to search for class docstrings: class .*\n\s*"""
in case that's useful later.
2023-05-15 00:15:49 -04:00
Isaiah Odhner
348d3489e3 Add to (and tweak) Known Issues 2023-05-15 00:15:49 -04:00
Isaiah Odhner
859d398d81 Write files in binary mode, in preparation for image formats 2023-05-15 00:14:46 -04:00
Isaiah Odhner
f78e46a5a8 Move encoding picking to AnsiArtDocument 2023-05-14 17:12:27 -04:00
Isaiah Odhner
7bb6f28d1e Add some shading to the candle 2023-05-14 17:11:29 -04:00
Isaiah Odhner
42467d7cd6 Generate full block NanoTiny meta-glyph font (4x4) 2023-05-12 22:35:38 -04:00
Isaiah Odhner
52be0534cc Add theoretical support for multiple meta-glyph fonts of different sizes 2023-05-12 22:10:53 -04:00
Isaiah Odhner
c22d174b80 Add Unicode representation of Code Page 437 2023-05-12 21:35:41 -04:00
Isaiah Odhner
85ab81ef81 Limit range of characters that display meta-glyphs 2023-05-12 21:33:42 -04:00
Isaiah Odhner
a1a8374259 Rename: singularize noun adjunct 2023-05-12 21:23:41 -04:00
Isaiah Odhner
cc68172661 Get many characters working with the meta-glyph font 2023-05-12 19:45:37 -04:00
Isaiah Odhner
ddcd069fe9 WIP: use NanoTiny meta-glyph font when zoomed in
The encoding is wrong.
2023-05-12 19:27:47 -04:00
Isaiah Odhner
94e02197f5 Convert NanoTiny font to text (2x2 metaglyphs) 2023-05-12 18:53:36 -04:00
Isaiah Odhner
2753427ae6 Repack NanoTiny to remove border 2023-05-12 18:18:17 -04:00
Isaiah Odhner
0f769689ef Update readme 2023-05-10 01:34:46 -04:00
Isaiah Odhner
8e6bc9d9a4 Formalize canvas events API: don't include event object in message
This has upsides and downsides.
- It's less verbose in most cases
- But event.offset I can't use unless I define that myself.
  (I wasn't even taking full advantage of this property.)
- It's clearer what's used because what is used has to be copied.
- But what's used has to be copied.
2023-05-10 00:38:05 -04:00
Isaiah Odhner
6dc6dc1a60 Handle stransi.Unsupported 2023-05-09 23:56:26 -04:00
Isaiah Odhner
1cdf570955 Handle minimum height at end so it no longer needs one row initially
Regarding "Initial document is zero wide to avoid an extraneous character at (0,0)",
this is not necessary anymore since I (recently) changed it to set, rather than append, values.
Regarding "...but needs one row to avoid IndexError", this commit removes that constraint.
It could now be initialized with size (1, 1) or (0, 0) or even (1, 0) I suppose, although that's not really a contender.
2023-05-09 23:56:26 -04:00
Isaiah Odhner
0d2840d5da Recode samples with new efficient ANSI export
- Will this make the files smaller when compressed? Doubtful.
- Will this commit make the repo larger? Yes, since the old is kept.
- But keeping the files in line with current encoding will allow me
to see changes in encoding, using --recode-samples.
- I'm excluding files not saved with the app:
  generated files (4x4_font_template.ans and gradient_test.ans)
  which will be recreated in their original form when regenerating,
  and a manually created empty file (0x0.ans), which tests the minumum
  document size of 1x1.
2023-05-09 23:08:43 -04:00
Isaiah Odhner
ef4fb910d5 Generate smaller ANSI files with Segment.simplify 2023-05-09 22:55:41 -04:00
Isaiah Odhner
7baba86a68 Fix type checker errors by making a return type more specific
With the more general type, it was giving:

  /home/io/Projects/textual-paint/src/textual_paint/paint.py:798:38 - error: Cannot access member "markup" for type "ConsoleRenderable"
    Member "markup" is unknown (reportGeneralTypeIssues)
  /home/io/Projects/textual-paint/src/textual_paint/paint.py:798:16 - error: Type of "markup" is unknown (reportUnknownMemberType)
  /home/io/Projects/textual-paint/src/textual_paint/paint.py:798:38 - error: Cannot access member "markup" for type "RichCast"
    Member "markup" is unknown (reportGeneralTypeIssues)
  /home/io/Projects/textual-paint/src/textual_paint/paint.py:798:38 - error: Cannot access member "markup" for type "str"
    Member "markup" is unknown (reportGeneralTypeIssues)
  /home/io/Projects/textual-paint/src/textual_paint/paint.py:798:16 - error: Return type is unknown (reportUnknownVariableType)
2023-05-09 22:45:37 -04:00
Isaiah Odhner
bb8aff84e9 Refactor so x is a column index when padding row widths 2023-05-09 22:36:33 -04:00
Isaiah Odhner
349887a74e Add minimum size of 1x1 for plain text files to match ANSI file loading 2023-05-09 22:32:43 -04:00
Isaiah Odhner
fa625e5868 Add empty file as a sample 2023-05-09 22:08:47 -04:00
Isaiah Odhner
6a650b7547 Fix missing last row when loading ANSI file not ending with a newline
This fixes loading samples/4x4_font_template.ans, and I should be able
to rebase my code for more efficient ANSI file saving, where I was also
running into missing last rows.
2023-05-09 22:08:02 -04:00
Isaiah Odhner
91ad494063 Detect file as ANSI if it includes tab, bell, backspace, etc.
This fixes opening/pasting text containing tabs (but not escape codes),
for instance if you want to copy/paste a table of characters, as I did.
2023-05-09 21:51:36 -04:00
Isaiah Odhner
7ce6cc08ca Add support for tab, backspace, and (ignoring) bell for ANSI loading 2023-05-09 19:56:36 -04:00
Isaiah Odhner
de4cf01f73 Fix scrolling in editing area, broken when updating Textual
somewhere from 0.19.0 to 0.22.3
2023-05-09 19:35:30 -04:00
Isaiah Odhner
77f631e396 Fix squashed columns when ANSI file jumps horizontally
Now I can load the font template that I made with generate_font_template.py
2023-05-09 19:23:55 -04:00
Isaiah Odhner
bd4bfa93e1 Swap x/y as received from stransi 2023-05-09 19:15:27 -04:00
Isaiah Odhner
d90449e2de Fix type errors in watchdog thread cleanup
- `observer` can be None, if --restart-on-changes was not passed, but
  the hotkey F2 is pressed.
- `is_alive` is a bound method, not a property. It was definitely used
  like a property in the code I referenced.

I didn't fix these type checker errors for a long time because:
  1. they never caused actual problems for me, and
  2. when adding a type annotation `observer: Observer | None`, Pyright
     gets even _more_ confused, saying it's Unknown | None instead of
     BaseObserver | None. The secret trick was to leave it unannotated.
  3. Adding parentheses to make it `is_alive()` also made Pyright seem
     even more confused, saying it was Unknown — until I added the
     conditional.
2023-05-09 18:03:40 -04:00
Isaiah Odhner
ef409f4756 Ignore a type checker error with watchdog observer.schedule
Type of "schedule" is partially unknown
  Type of "schedule" is "(event_handler: Unknown, path: Unknown, recursive: bool = False) -> ObservedWatch"PylancereportUnknownMemberType
2023-05-09 17:07:56 -04:00
Isaiah Odhner
302e578387 Generate type stubs for stransi and ochre 2023-05-09 16:58:25 -04:00