-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApps.html
More file actions
1020 lines (919 loc) · 41.7 KB
/
Apps.html
File metadata and controls
1020 lines (919 loc) · 41.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
layout: Layout_Default
title: "Application Gallery"
meta_description: App Gallery.
meta_keywords: "programs, applications, apps, showcase, works"
---
{%- comment %}
<!--
------------------------------------------
© released under (CC0) :
------------------------------------------
This site's HTML + CSS + Jekyll + Liquid.
This site's content.
Gamepad.Coder 2021.
--------------------------------------------------
https://creativecommons.org/publicdomain/zero/1.0/
--------------------------------------------------
-->
{% endcomment -%}
{%- capture app_img_2do_about_loQ %}/assets/images/app_highlights/loQ/2do_tree_about.jpg{% endcapture -%}
{%- capture app_img_website_loQ %}/assets/images/app_highlights/loQ/this.jpg{% endcapture -%}
<!-- main content -->
<div id="the_page__main_content" class="app_highlights">
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- adds a container to exit on click outside picture bounds -->
<div id="modalClickBox" style="
width: 100%;
height: 100%;
"></div>
<!-- Loads the clicked image into this zoomable popup -->
<img class="modal-content" id="img01">
</div>
<div class="green_dot_underline_wrapper__skipTopMargin">
<div class="h2_wrapper">
<h2 id="h_unity">Unity Typewriter and Windowing System</h2>
</div>
</div>
<article class="additional_bottom_margin">
<img id="img_unitySystem" class="app_highlight_item" src="{{ "/assets/images/app_highlights/unity_windowing_sys/2013-10-22 21_50_17-Unity - 01 first test.unity - 7.24.2013 - timeline, notes, cmd - PC, Mac & Linux.png" | absolute_url }}" />
<!-- <img id="img_treeview" src="{{ "/assets/images/app_highlights/" | absolute_url }}"
class="app_highlight_item"/> -->
<!-- <h3>About:</h3> -->
<input id="apps_collapsible_section_1" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_1" class="label-toggle_collapsible_section">About:</label>
<div class="collapsible_section">
<p>
Made back in 2013. My first large experiment.
<br> Windows can be dragged, zoomed, grouped,
<br> typed into, saved and loaded.
</p>
<p>
Built in the <a href="https://unity.com/">Unity</a> game development environment,
and written in "UnityScript" (<span class="parenthetical">a language loosely based on
JavaScript</span>). I later ported it to C# in 2014 in order to have better support
for <a href="https://en.wikipedia.org/wiki/Polymorphism_(computer_science)">polymorphism</a>
and <a href="https://en.wikipedia.org/wiki/Subtyping">subtyping</a>.
</p>
</div>
<input id="apps_collapsible_section_2" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_2" class="label-toggle_collapsible_section">Purpose:</label>
<div class="collapsible_section">
<p>
My initial plan was to build a framework for AR and VR (<span class="parenthetical">Augmented
Reality and Virtual Reality</span>), but integrating further support for web, video, audio, and
other media seemed like it was going to be a laborious task. So I decided to move on and build
on top of platforms where I could easily work with existing files and code libraries, instead of
writing each media utility from the ground up.
</p>
<p>
It was an incredibly fun project, and it was my first big trial by fire where I learned how to
better manage and organize large complex projects.
</p>
</div>
<input id="apps_collapsible_section_3" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_3" class="label-toggle_collapsible_section">Math:</label>
<div class="collapsible_section">
<p>
In my first iteration, I had windows in the same plane (parallel to the screen, all the same
distance away from the camera). This caused severe visual glitches whenever portions of two or
more windows overlapped. <span class="parenthetical">I was new to Unity and game engines and 3D,
and if there was a workaround for this, I was unable to discover it at the time.</span> To
remedy this, I ended up learning a lot about 3D vector math.
</p>
<p>
[~] note to self, add diagrams here.
</p>
<p>
I spaced windows away from the others, giving each its own plane in 3D. Then they could move around
the user's screen without any anomalies nor visual chimera glitches. But placing windows further
from the camera makes them smaller. So as windows are placed further away, they are proportionally
resized to maintain the appearance that all of the windows were located in the same "Desktop" plane.
</p>
</div>
<input id="apps_collapsible_section_4" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_4" class="label-toggle_collapsible_section">Future Plans?</label>
<div class="collapsible_section">
<p>
When I move back to working on 3D interfaces again, I may revisit this project, clean it with
the better practices I now know, and upload a version of source code which can run on modern
versions of Unity. But likely I will instead make a more elegant solution than this one. It was
an incredible learning experience though.
</p>
</div>
<div style="padding-bottom: 41px;">
<p style="float: right;">
<span style="
font-size: 26px;
color: #999;
">
<!-- 🠕🠕 ↑↑ ⇧⇧</span> -->
<!-- 🠕 not displaying in Chrome on Android -->
⇧ </span>
<span class="parenthetical">click a section to expand</span>
</p>
</div>
</article>
<div class="green_dot_underline_wrapper">
<div class="h2_wrapper">
<h2 id="h_godot_rte">Rich Text Editor in Godot</h2>
</div>
</div>
<article id="apps_godot_rte_article" class="additional_bottom_margin">
<img id="img_unitySystem" class="app_highlight_item" src="{{ "/assets/images/homepage/GalleryPreview.gif" | absolute_url }}" />
<p>
My current project.
</p>
<p>
A subset of a larger system I'm working on in Godot.
</p>
<p style="border: 1px solid black; margin: auto; padding: 10px; max-width: 80%;">
<span class="parenthetical">Currently on hold. I'll be returning to this after I finish this
website and secure a job.</span>
<br><br>
<span class="parenthetical">More details, tutorials, and full code will be available in the
Documentation section of this website when it's done.</span>
</p>
<br>
<input id="apps_godot-rte_collapsible_section_1" class="toggle_collapsible_section" type="checkbox">
<label for="apps_godot-rte_collapsible_section_1" class="label-toggle_collapsible_section">Structure</label>
<div class="collapsible_section">
<p>
Each letter is a node, and each line is a node containing zero or more letters.
</p>
<p>
Letters contain internal data for their foreground and background color,
their font name, their font size, and their style.
</p>
<p>
The window itself currently has its graphical style hardcoded, but I plan to extend this (much later).
</p>
<p>
Clicking within the window will activate it, and place the text cursor at the mouse position.
Clicking and dragging the mouse will select a region of text.
<span clas="parenthetical">
(You can also select text by holding SHIFT and pressing: the arrow keys, HOME button, and the END button.)
</span>
</p>
<p>
When CTRL is held down before the user clicks the window, the window functions differently:
<ul>
<li>
Holding CTRL and left-click dragging will move the window.
</li>
<li>
Holding CTRL and right-click dragging will resize the window.<br>
<span class="parenthetical">
(The direction of the resize depends on the quadrant of the window clicked.
If the user holds CTRL, right-clicks on the leftmost side of the window,
then drags out, the rightmost side of the window will stay where it is,
and the leftmost side will follow the mouse and expand or contract.)
</span>
</li>
</ul>
</p>
</div>
<input id="apps_godot-rte_collapsible_section_2" class="toggle_collapsible_section" type="checkbox">
<label for="apps_godot-rte_collapsible_section_2" class="label-toggle_collapsible_section">Undo/Redo Support!</label>
<div class="collapsible_section">
<p>
Any action which changes the document is called
through a COMMANDS class, which creates an Action object to track changes.
</p>
<p>
After an Action object is created, its Action.do() function is called, then the Action object is pushed
onto an undo stack. When the user presses the hotkey for undo (CTRL+Z), the Action object is popped,
its Action.undo() function is called, and the Action object is pushed onto the redo stack.
</p>
</div>
</article>
<div class="green_dot_underline_wrapper">
<div class="h2_wrapper">
<h2 id="h_linux">Linux Framebuffer Windowing System</h2>
</div>
</div>
<article id="apps_linux_article" class="additional_bottom_margin">
<p style="border: 1px solid black; margin: auto; padding: 10px; max-width: 80%;">
<span class="parenthetical">Due to the Coronavirus pandemic, I don't presently have access to this code, but I will upload images of it when I am able.</span>
</p>
<input id="apps_collapsible_section_5" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_5" class="label-toggle_collapsible_section">About:</label>
<div class="collapsible_section">
<p>
Written in C, then ported to C++. Runs in a Linux terminal, and plots individual pixels to the
screen. Keyboard input only.
<br><br>
Windows can be moved and resized. Windows contain lines and headers (which contain sub-sections of
more headers and lines). Headers can be folded and expanded, allowing quick navigation between dense
sets of hierarchical data without ever taking your hands off the keyboard.
<br><br>
</p>
</div>
<input id="apps_collapsible_section_6" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_6" class="label-toggle_collapsible_section">Painting Pixels:</label>
<div class="collapsible_section">
<p>
In this app the screen is rendered from blocks, like a chess board. The screen's grid of blocks does
not change location nor size, but behind it is a canvas <span class="parenthetical">(which can move
around)</span> filled with windows and lines and characters <span class="parenthetical">(which can
also move around)</span>. Think of the screen's grid like a camera fixed in place while people move
around within <span class="parenthetical">(or outside of)</span> its view. Every time the program
paints pixels to the screen, the screen's grid "camera" takes a snapshot of blocks it can currently
see, and displays them at actual pixel coordinates on the computer's monitor.
<br><br>
</p>
</div>
<input id="apps_collapsible_section_7" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_7" class="label-toggle_collapsible_section">
What this app does
<br>from the top down:</label>
<div class="collapsible_section">
<p>
The canvas can place windows anywhere, and can scroll to view windows placed off the screen.
Windows can be moved and resized. Windows have a solid background color for each block they
display within the grid system. Windows can additionally assign a default foreground color for
text <span class="parenthetical">(different from the workspace's default font color)</span>.
Windows contain a border of solid-colored grid elements, and a central document. The central
document contains rows of lines. Lines can be one of two types: [1] a simple line of character
objects to display and edit [2] or a header, which functions as a simple line, but additionally
has a sub-document grouped under it. Headers can fold <span class="parenthetical">(i.e. collapse
and hide their sub-document region, showing only their title)</span> and unfold. Header titles
can be edited just like any other line. Sub-documents under headers can contain lines of either
type.
<br><br>
When the user selects a window, then activates it, the program shifts into line selection mode.
Once the desired line is selected, the user hits [CONTROL+ENTER] to shift from line selection
mode -> into editing mode. From here line characters can be typed, selected, copied, pasted, and
deleted as if typing in a standard text editor. [CONTROL+ENTER] likewise shifts back from text
editing mode -> back to line selection mode.
<br><br>Lines store a <a href="https://en.wikipedia.org/wiki/Linked_list">linked-list</a> of
character objects. Each character object has: a foreground color, a background color, references
to neighbors, and the symbol to display at its grid coordinate. <span class="parenthetical">(To
specifically differentiate, let's define "symbol" in this context to mean: a letter, number, or
any visible character which results from hitting a key on a keyboard.)</span>
<br><br> When the program draws to the screen, each grid element with a window will report what
is located at each blocky grid coordinate. Borders for windows tell the grid to paint a single
color at each pixel in that rectangle. Coordinates in a window which do contain a character
object report their block's background color and which foreground color the grid should paint
their symbol. When the character object tells the grid which symbol to draw, the grid looks up
that symbol in the font object.
<br><br>The font object is a series of 2D regions I programmed manually. Each region has
elements containing 1's and 0's representing pixels in a rectangle. The 1's are the pixel
positions in the rectangle to draw the symbol, and the 0's represent where to draw the
background color. Each typeable character on the keyboard is mapped to one of the 2D regions in
the font array <span class="parenthetical">(fun example: the 2D region mapped to the space bar
is all 0's, resulting in an empty box; pure background color)</span>.
<br><br>
So the grid gets the foreground, the background, and the symbol data, then paints the pixels
onto the portion of the screen associated with that grid coordinate's region.
<br><br>This process is repeated for each window and each line on the screen until... viola! You
have a screen with blocks and letters and colors.
<br><br>
Next up, how to use it.
<br><br>
</p>
</div>
<input id="apps_collapsible_section_8" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_8" class="label-toggle_collapsible_section">Controls:</label>
<div class="collapsible_section">
<p>
<ul>
<li style="list-style-type: none;">
<p>
Primary design rule for this application:
<br /><br />
You should never have to take your hands off the keyboard nor move them out of typing
position <span class="parenthetical">(i.e. you'll never have to take your index
fingers off the [f] and [j] keys)</span>.
<br /><br />
</p>
<!-- <h3 class="h3_list_header"></h3> -->
<input id="apps_collapsible_section_8-1" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_8-1" class="label-toggle_collapsible_section">
The [ESDF <img src="{{ "/assets/images/app_highlights/esdf_keys.png" | absolute_url
}}" style=" height: 2em; display: inline-block; width: auto; vertical-align:
middle;">
keys] scroll the canvas,
<br> which moves all the windows in unison.
</label>
<div class="collapsible_section">
<ul>
<li>
This lets you scroll around and view other windows.
</li>
<li>
The [A] and [Q] keys adjust the speed at which the canvas scrolls.
</li>
<li>
These controls are only deactivated when in typing mode. Otherwise they work no
matter where you are in selection mode.
</li>
</ul>
</div>
</li>
<li style="list-style-type: none;">
<input id="apps_collapsible_section_8-2" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_8-2" class="label-toggle_collapsible_section">
The <img src="{{ "/assets/images/app_highlights/ijkl_keys.jpg" | absolute_url }}"
style="height: 2em; display: inline-block; width: auto; vertical-align: middle;">
keys are at the core of interaction.
</label>
<div class="collapsible_section">
<ul>
<li>
The [IJKL] keys are for selection
<br>across different contexts.
</li>
<li>
The [P] and [;] keys change the scope of what is selected (from high up canvas,
to low down character editing).
</li>
<li>
The [U] and [O] keys do a few different things at different levels, but it's
pretty straightforward.
</li>
</ul>
</div>
</li>
<li style="list-style-type: none;">
<input id="apps_collapsible_section_8-3" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_8-3" class="label-toggle_collapsible_section">
Let's see how keys work at each level
</label>
<div class="collapsible_section">
<ul>
<li style="list-style-type: none;">
<input id="apps_collapsible_section_8-3-1" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_8-3-1" class="label-toggle_collapsible_section">
When the canvas is active
</label>
<div class="collapsible_section">
<ul>
<li>
[IJKL] keys select windows.
<br>
<div style="margin-left: 20px;">
<span class="parenthetical">(The canvas will automatically scroll to
view any selected window if off-screen).
</span>
</div>
</li>
<li>
The [;] key activates the selected window.
</li>
<li>
The [P] key exits an active window and returns the scope to choosing
windows within the canvas.
</li>
<li>
The [U] key toggles "move the selected window" mode. Once on, the [IJKL]
keys nudge the window <span class="parenthetical">(pretend these are the
arrow keys)</span>. And pressing [U] again turns off move-mode.
</li>
<li>
The [O] key toggles "resize the selected window" mode. [IJKL] keys
resize the window. [I] and [K] shrink and expand the window vertically.
[J] and [L] shrink and expand the window horizontally. Pressing [O]
again turns off resize-mode.
</li>
</ul>
</div>
</li>
<li style="list-style-type: none;">
<input id="apps_collapsible_section_8-3-2" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_8-3-2" class="label-toggle_collapsible_section">
When a window is active
</label>
<div class="collapsible_section">
<ul>
<li>
the [I] and [k] keys allow you to select lines of text
</li>
<li>
the [J] and [L] keys fold and unfold headers
<br>
<div style="margin-left: 20px;">
<span class="parenthetical">(if the current header is selected and
folded then [J] will select and scroll up to the header's parent).
</span>
</div>
</li>
<li>
the [U] and [O] keys go to
<br>the next and previous header, respectively.
</li>
<li>
the ([) and ['] keys scroll the current window
<br>
<div style="margin-left: 20px;">
<span class="parenthetical">(similar to how the [ESDF] keys scroll
the canvas)</span>
</div>
</li>
<li>
the [P] key will deactivate the window and move selection up to the
canvas level.
</li>
<li>
the [;] key or [CTRL+ENTER] combo will activate the selected line (or
header) and the program shifts into text editing mode.
</li>
</ul>
</div>
</li>
<li style="list-style-type: none;">
<input id="apps_collapsible_section_8-3-3" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_8-3-3" class="label-toggle_collapsible_section">
When a line is active in text editing mode
</label>
<div class="collapsible_section">
<ul>
<li>
All keyboard inputs which normally type a character will insert a
character at the highlighted position.
</li>
<li>
The [ENTER] key will make a new line and move the highlighted position
to it. The window is scrolled down one line if the user presses [ENTER]
at the bottom of the window's viewable area.
</li>
<li>
[BACKSPACE], [DELETE], [HOME], [END], [PAGEUP], [PAGEDOWN], and the up
down left right [ARROW_KEYS] function as they do in regular text
editors, such as Notepad.
</li>
<li>
The shift key allows selecting a range of characters in a line (or
lines).
</li>
<li>
[CTRL+C] will copy characters if there is a selection.
</li>
<li>
[CTRL+V] will paste characters <span class="parenthetical">(replacing
any selected characters)</span>.
</li>
<li>
[CTRL+ENTER] will exit editing mode and return to line selection mode.
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</p>
</div>
<input id="apps_collapsible_section_9" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_9" class="label-toggle_collapsible_section">Background Info and Trivia:</label>
<div class="collapsible_section">
<p>
<a href="https://en.wikipedia.org/wiki/GNU_nano">Nano</a> is a minimalistic but fantastic <a
href="https://en.wikipedia.org/wiki/Command-line_interface">command-line interface</a> text
editor that can be found on most Linux distributions.
</p>
<p>
It uses a code library called <a href="https://en.wikipedia.org/wiki/Ncurses">ncurses</a>, which
I initially used to build the first versions of this project. Ncurses basically lets you define
text and colors at positions on a grid, and it makes writing a text editor from (mostly scratch)
a breeze.
</p>
<p>
Later I was curious about how Linux displays images, simple graphics, and command line
terminals. So I began investigating <a
href="https://en.wikipedia.org/wiki/Linux_framebuffer">the framebuffer</a>.
</p>
<p>
In addition to using the framebuffer, I retrieved the hardware signals of my keyboard from
Linux in the form of <a href="https://en.wikipedia.org/wiki/Scancode">scancodes</a>. From there
I set up branches of code to account for how to react to different key presses and different
combinations.
</p>
</div>
<input id="apps_collapsible_section_10" class="toggle_collapsible_section" type="checkbox">
<label for="apps_collapsible_section_10" class="label-toggle_collapsible_section">Concluding Remarks:</label>
<div class="collapsible_section">
<p>
This experiment was incredibly fun, and was my first foray into interacting with hardware on a
low level. Surprisingly, the biggest utility from this project was how it made me start thinking
about hardware and software in a more comprehensive way. It really bridged a gap for me between
my understandings of high level frameworks <-(&)-> the 1's and 0's that power, organize,
and encode everything above. And seeing a bit beneath the hood closer to the machine processes
has given me a lasting appreciation for the history of computing in general, and for all the
sub-processes that have been working inside my computers all my life.
</p>
</div>
</article>
<div class="green_dot_underline_wrapper">
<div class="h2_wrapper">
<h2 id="h_treeview">AutoHotkey
<br> TreeView Tasklist
</h2>
</div>
</div>
<article class="additional_bottom_margin">
<div class="apps_written_bg_image"
style="background-image: url('{{ app_img_2do_about_loQ | absolute_url }}');"
>
<img id="img_treeview" src="{{ "/assets/images/app_highlights/2do_tree_about.gif" | absolute_url }}"
class="app_highlight_item"/>
</div>
<p>
Written in AutoHotkey (<span class="parenthetical">AHK</span>).<br>
Built on top of my AHK GUI Abstraction Framework.
</p>
<p>
I use this for planning out my day,
<br>keeping track of large projects & requirements,
<br>and to minimize clutter while brainstorming.
</p>
<p>
<!-- <a href="">
Click here for more pictures + details.
</a> -->
</p>
<!-- <p>
<ul>
<li>
Click here to see the Documentation Pages for this App.
<br> (coming soon)
</li>
<li>
Click here to see the source code on GitHub.
<br> (coming soon, next phase of website)
</li>
<li>
Click here to download for Windows.
<br> (coming .. soon, you get the picture :)
</li>
</ul>
</p> -->
</article>
<div class="green_dot_underline_wrapper">
<div class="h2_wrapper">
<h2 id="h_ahk_desktop">AutoHotkey
<br> Scrolling Notes with Nested Windows
</h2>
</div>
</div>
<article class="additional_bottom_margin">
<p>
<!-- <a href="">
Click here for more pictures + details.
</a> -->
<span class="parenthetical">Demo coming soon.</span>
</p>
</article>
<div class="green_dot_underline_wrapper">
<div class="h2_wrapper">
<h2 id="h_ahk_gui_framework">AutoHotkey
<br> GUI Abstration Framework</h2>
</h2>
</div>
</div>
<article class="additional_bottom_margin">
<p>
<!-- <a href="">
Click here for more pictures + details.
</a> -->
<span class="parenthetical">Functional, but not tidy and not comprehensive in coverage, currently on
the backburner.</span>
</p>
<p>
<span class="parenthetical">This large framework powers the above two AutoHotkey projects.</span>
</p>
</article>
<div class="green_dot_underline_wrapper">
<div class="h2_wrapper">
<h2 id="h_thisWebsite">This Website</h2>
</div>
</div>
<article class="additional_bottom_margin" style="
color:#d8d3d3;
font-family: Arial, Helvetica, sans-serif;
">
<div class="apps_written_bg_image"
style="background-image: url('{{ app_img_website_loQ | absolute_url }}');"
>
<img id="img_this" src="{{ "/assets/images/app_highlights/this.jpg" | absolute_url }}"
class="app_highlight_item"/>
</div>
<h3>A New Journey:</h3>
<p>
First time studying Web Design with HTML5 + CSS.<br><br>
I'd never heard of the <a href="https://jekyllrb.com/">Jekyll</a> static website builder
nor the <a href="https://www.sphinx-doc.org/en/master/">Sphinx</a> documentation generator when I started,
but I absolutely love both of these tools now.<br><br>
</p>
<h3>Beginning with Jekyll and a Dream:</h3>
<p>
I had a basic idea in mind when I started, but I soon realized that if I wanted to
make each page have a consistent <code><header></code>
<span class="parenthetical">
(the navigation bar and image at the very top),
</span>
then I would be duplicating a lot of code. Coming from my background of using low-level languages,
the notion of necessary code duplication was strange to me. But I was mainly worried about keeping
it all in sync.
</p>
<p>
Imagine this scenario. Say I were to start with a homepage and a <code><header></code>. Then I make a second page.
I copy the homepage's <code><header></code> code and paste it into the second page. Any time I create a new page, I
need to make sure it contains this code
<span class="parenthetical">
(in order to have a consistent presentation as the
user navigates between pages).
</span>
</p>
<p>
If later I were to change even one part of the <code><header></code>, then I would have to
manually update the <code><header></code> code of each and every page to match that
change.
</p>
<p>
This approach is not efficient and the product would not be easy to maintain.
</p>
<p>
So I searched the internet. I read that there were tools for building
<a href="https://en.wikipedia.org/wiki/Static_web_page">"static" websites</a>, and I soon discovered
the <a href="https://jekyllrb.com/">Jekyll</a>. If you need to make a website, but you're not using
a lot of JavaScript to dynamically insert content, I highly recommend Jekyll.
</p>
<p>
Briefly: Jekyll lets you define a basic layout, then you can wrap new pages inside the shared
layout. You can define multiple layouts, and use variables to (a) determine what content to
insert or (b) to generate content using your variables. It's awesome.
</p>
<p>
Code duplication exists once Jekyll bakes your website into an output directory. But in your source
files, you just write code once (and tell Jekyll where it should be inserted). Instead of
duplicating large sections, you just type {% raw %}<code>{{ content }}</code> or <code>{% include
some_file.html %}</code>{% endraw %} and you're done!
</p>
<p>
For an example, here is a link to this page's content file on GitHub:
<a href="https://github.com/gamepad-coder/gamepad-coder.github.io/blob/master/Apps.html">
Apps.html</a>. This is the file before Jekyll bakes it into the finished HTML page.
You'll notice this file doesn't contain a <code><header></code> tag. When Jekyll
bakes this Apps.html page, Jekyll takes the
<a href="https://github.com/gamepad-coder/gamepad-coder.github.io/blob/master/_layouts/Layout_Default.html">
Layout_Default.html</a> file and pastes the Apps.html file into the
{% raw %}<code>{{ content }}</code>{% endraw%} line inside Layout_Default.html. <br><br>
Resulting in: the page you're looking at now!
</p>
<p>
<span class="parenthetical">If this is interesting to you,
or if you'd like more details, you can read my initial impressions of Jekyll in
<a class="nav_ref" href="Philosophy/1__PlanningTheSite.html"
style="font-size:small;">[Blog Post #1]</a>.</span>
</p>
<h3>Making Manuals:</h3>
<p>
Long story short, I love the websites for <a href="https://docs.godotengine.org/en/latest/">Godot's documentation</a>
and <a href="https://docs.blender.org/manual/en/latest/">Blender's documentation</a>. I knew I
wanted to use the <a href="https://sphinx-rtd-theme.readthedocs.io/en/stable/">ReadTheDocs theme for
Sphinx</a> for my Documentation section from the beginning. It took a fair amount of time to learn
<a href="https://www.sphinx-doc.org/en/master/index.html">Sphinx</a>, <a
href="https://pygments.org/docs/">Pygments</a>, and <a
href="https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html">reStructuredText</a>,
but it was absolutely worth it, and incredibly fun.
</p>
<p>
However I faced a few minor problems:
<ol>
<li>
I wanted to keep my <code><header></code> bar on my baked Documentation pages.
</li>
<li>
I needed to find a way to take the HTML structure which Sphinx outputs -> and make it
compatible with my Jekyll processing pipeline.
</li>
</ol>
</p>
<h3>Automation:</h3>
<p>
After I discovered Sphinx, I had to be a little creative to make Sphinx's output files
compatible with the needs of Jekyll's input files.
<span class="parenthetical">
I'm using Sphinx for the entire Documentation section, but I'm using Jekyll for all other pages.
</span>
</p>
<p>
To modify all my Sphinx-generated HTML files, I began automating a lot of manual tweaks and
insertions by utilizing <a href="https://en.wikipedia.org/wiki/Regular_expression">Regular Expressions</a>
for the first time.
<span class="parenthetical">
Then I reached a point where AutoHotkey was malfunctioning when performing
Regular Expression replacements across huge files, so I began studying Python for the first
time. I ported my AutoHotkey automation into .py scripts, and it's been amazing ever since. Now I can run
these pre-processing and post-processing .py scripts from either Windows, or from my Debian
<a href="https://docs.microsoft.com/en-us/windows/wsl/">WSL2</a> command line.
</span>
</p>
<h3>Creating Code-Block Folding:</h3>
<p>
Recently, I wanted to add code-block folding to my Documentation section.
Sphinx was capable of fully highlighting my AutoHotkey code (after a few minor modifications), but had no support
for folding regions of code. So I wrote a pre-processing script in Python to manually insert
arbitrary tags near every open <code>{</code> curly brace and different arbitrary tags near
every close <code>}</code> curly brace.
</p>
<p>
I wrote a post-processing Python script to take the HTML
files which Sphinx generates, and replace my arbitrary tags with the HTML <code><details></code> element
(which has built-in functionality for collapsing/folding blocks of text). It was really different for me,
but pretty straightforward, and very fun.
</p>
<p>
You can try out my custom code-block folding here:
<ul>
<li>
Click this link: <a class="nav_ref" href="/Documentation/AutoHotkey/Utilities/Emulate_Numberpad/index.html">Docs: Emulate Numberpad</a>
<br>
</li>
<li style="
margin-top: 1rem;
">Then scroll to the bottom and click the box:
<span style="
-webkit-box-shadow: -11px 10px 2px -2px rgb(0 0 0 / 30%), 0 1px 0 rgb(255 255 255 / 10%);
box-shadow: -11px 10px 2px -2px rgb(0 0 0 / 30%), 0 1px 0 rgb(255 255 255 / 10%);
border: 1px solid rgba(28, 160, 189, 0.47);
font-size: initial;
font-weight: bold;
/* display: block; */
margin-top: 14px;
/* margin-bottom: 24px; */
margin-left: 10px;
padding: 0.1rem;
color: #2a8b9b;
background-color: white;
margin-top: 20px;
">emulate_numpad.ahk</span>
</li>
<p></p>
</ul>
</p>
<h3>Short Writeup:</h3>
<p>
If you'd like to read more about the toolchains I use (and what my pre-processing
and post-processing scripts do) I've written a short overview on
<a href="https://github.com/gamepad-coder/gamepad-coder.github.io">this website's GitHub repository page</a>.
</p>
<h3>In Summary:</h3>
<p>
I began this website with a portfolio concept, but I kept working on it because I really enjoyed it.
</p>
<br>
<br>
<br>
<p>
<a href="{{ "/Philosophy/0__changelog.html" | absolute_url }}">
View changelog here.
</a>
</p>
</article>
<h2 id="h_acronym">Acronyms</h2>
<article class="additional_bottom_margin">
<p>
AHK : <a href="https://www.autohotkey.com/">AutoHotkey</a>
<br> OOD : <a href="https://en.wikipedia.org/wiki/Object-oriented_design">Object-Oriented Design</a>
<br> GUI : <a href="https://en.wikipedia.org/wiki/Graphical_user_interface">Graphical User Interface</a>
<br> WSL2 : <a href="https://docs.microsoft.com/en-us/windows/wsl/">Windows Subsystem for Linux
<span class="parenthetical">(run Linux code and apps inside Windows!)</span></a>
</p>
</article>
</div><!-- #the_page__main_content -->
<aside id="asideBar" class="aside_appHighlights">
<h3 style="text-align:center">Navigate This Page:</h3>
Experiments
<ul>
<li>
<a class="nav_ref" href="{{ page.url | append: "#h_unity" | absolute_url}}">Unity Typewriter and Windowing System</a>
</li>
<li>
<a class="nav_ref" href="{{ page.url | append: "#h_godot_rte" | absolute_url}}">Rich Text Editor in Godot</a>
</li>
</ul>
Linux
<ul>
<li>
<a class="nav_ref" href="{{ page.url | append: "#h_linux" | absolute_url}}">Linux Framebuffer Windowing System</a>
</li>
</ul>
AutoHotkey <span class="parenthetical">(AHK)</span>
<ul>
<li><a class="nav_ref" href="{{ page.url | append: "#h_treeview" | absolute_url}}">TreeView Tasklist</a></li>
<li><a class="nav_ref" href="{{ page.url | append: "#h_ahk_desktop" | absolute_url}}">Scrolling Notes with Nested Windows</a></li>
<li><a class="nav_ref" href="{{ page.url | append: "#h_ahk_gui_framework" | absolute_url}}">GUI Abstration Framework</a></li>
</ul>
Websites
<ul>
<li>
<a class="nav_ref" href="{{ page.url | append: "#h_thisWebsite" | absolute_url}}">This Website</a>
</li>
</ul>
<p
class="skip_bottom_border"> info: <a class="nav_ref" href="{{ page.url | append: "#h_acronym" | absolute_url}}">Acronym Definitions</a></p>
</aside>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- from
https://www.w3schools.com/howto/howto_css_modal_images.asp -->
<script>
// Get the modal
var modal = document.getElementById("myModal");
var clickToExit = document.getElementById("modalClickBox");
var counter = 1;
var b_clicking = false;
var b_dragging = false;
var previousX;
var previousY;
var b_zoomed = false;
// Get the image and insert it inside the modal - use its "alt" text as a caption
// var img_tv = document.getElementById("img_treeview");
// var img_unity = document.getElementById("img_unitySystem");
// var img_web = document.getElementById("img_this");
// var img = "";
var modalImg = document.getElementById("img01");
var otherImgs = document.getElementsByTagName('img');
for( var i=0, len=otherImgs.length; i<len; i++ ){
var i_img = otherImgs[i];
if( i_img != modalImg ){
i_img.onclick = function(){
modalImg.src = this.src;
modal.style.display = "block";
}
}
}
clickToExit.onmouseup = function() {
reset_modal();
};
modalImg.onmouseup = function() {
// console.log("here4: b_dragging is [" + b_dragging + "]");
if( ! b_dragging ){
counter++;
}
b_dragging = false;
if(counter==2){
modalImg.style.maxWidth = "150vw";
modalImg.style.maxHeight = "150vh";
var imgWidth = modalImg.width;
if( imgWidth < 400 ){
// modalImg.style.width = "200%";
modalImg.style.height = "80%";
b_zoomed = true;
}
}
if( counter > 2){
reset_modal();
}
};
function reset_modal(){
if( b_zoomed ){
modalImg.style.height = "auto";
}
modal.style.display = "none";
modalImg.style.maxWidth = "95vw";
modalImg.style.maxHeight = "95vh";
counter = 1;
b_zoomed = false;
b_clicking = false;
b_dragging = false;
}
$("#myModal").mousedown(function(e) {
e.preventDefault();
previousX = e.clientX;
previousY = e.clientY;
b_clicking = true;
});
$(document).mouseup(function() {
b_clicking = false;
});
$(document).mousedown(function() {
b_clicking = true;
// console.log("here 3");
});
$("#myModal").mousemove(function(e) {
if( previousX != e.clientX || previousY != e.clientY ){
if (b_clicking) {
b_dragging = true;
e.preventDefault();
var directionX = (previousX - e.clientX) > 0 ? 1 : -1;
var directionY = (previousY - e.clientY) > 0 ? 1 : -1;