Planetary Gears is a world-clock, timer, and calendar webapp written using jquery, fuse.js, and moment-timezone. I wrote it for a client and released it under the 2-clause BSD License back in November 2019. Since I have a moment, I am doing an expose` of the app here.
The basic view is as above, and searching for a timezone brings up a list of possible matches:
You can click on any option in the autocomplete box to select it and add it to the table, or just press Enter to add the first match.
You can add as many rows to the table as you want, and change the paramters like whether "now" is centered in the time interval or the beginning of the time interval, how large the interval is, and whether time is displayed in 12 or 24 hour format.
Using the buttons on the left edge of the table you can change the order of the zones or remove them.
Time blocks are one-hour long but not necessarily starting on the hour! Irregular timezones are properly calculated using moment-timezone. The blocks are color-coded, showing early, work, and late hours, as well as weekends.
The calendar part of the app displays a month-by-month calendar or year-by-year. You can easily use the control forms at top to change the mode and the displayed month/year. The current day is hilighted on the calendar if applicable.
There is also a simple timer/stopwatch function in the app. The timer goes up to 24 hours and optionally plays a chime when the time's up. The stopwatch has a lap counter like a real stopwatch, in case you need it.
An instance of Planetary Gears is always running on this server at nilfm.cc/gears, and if you want to run it on a server of your own, you can clone the git repository and drop it anywhere in your server's document hierarchy. Any bug reports or feature requests, let me know! And enjoy :)
Neat projects often emerge where you least expect. After trying to use rio from plan9port in combination with my wmctrl script qwopTiler, I was a bit saddened when I realized that they wouldn't gel, since rio is not Extended-Window-Management-Hints (EHWM) compliant and much of the functionality of wmctrl depends on EHWM.
But all was not lost, as the features I wanted were simple, as is the source of rio. So ryudo was born.
Building on top of nice features from rio like the sweep-to-resize and slick menu system, ryudo adds keyboard shortcuts for all your typical window management operations like hide, unhide, maximize, and close, as well as keybinds for quick window snapping just like was implemented in qwopTiler, and an extra feature to launch a centered terminal with a keyboard shortcut.
The border colors, border widths, menu colors, and keybind settings are all together in the config.h file, so changing the settings doesn't require one to hunt in the source for them. Other minor features were the re-enabling of the -ffm (focus-follows-mouse) runtime option and the final cutting of long window names in the hidden window list to 23 characters max (plus a '~' symbol to signify that it is truncated).
Some caveats inherited from the rio and 9wm code are RGBA windows being bound to an RGB space (which means a tool like transset needs to be used to acheive window translucency -- not a terrible setback), and a lack of click-to-raise behavior in focus-follows-mouse mode. The latter might be fixable by tweaking active() and setactive() but I've yet to find motivation or time to mess with that too much.
In all, ryudo has proven in my usage so far to be extremely lightweight and usable, supporting keyboard and mouse control depending on preference. If you like rio or 9wm and want a little more versatility, give ryudo a try! If you have experience in C and/or X11 programming and want to improve ryudo, hack away -- the source is free for all.
steppenwolf and steppenwolf-dark are GTK themes -- user interface themes for Linux desktops and GTK applications in general. steppenwolf is based on OneStepBack by Jean-Pierre Bucciol, and steppenwolf-dark is based on steppenwolf in turn.
Originally, steppenwolf was developed as a theme to provide sleek menus, tooltips, and notifications in grey-on-black that lend well to alpha blending and the simple style I use in my openbox themes, along with high visibility and low resource usage.
The dark theme takes more inspiration from Matcha, although the code, being from the OneStepBack lineage rather than an Arc lineage, is much lighter. How much lighter? Well, the GTK-2 port of Matcha is approximately 2000 lines of code, while steppenwolf-dark is 400, and the GTK-3 port of Matcha is 10000 lines of code, with steppenwolf-dark clocking in at 1100. I don't know about you, but I'd much rather parse 1100 or 400 lines of code than 10000 or 2000 to load my applications.
Both themes share the same aesthetic for the menus, tooltips, and notifications, and the same turquoise hilight color. The skeuomorphic widget styles of the original theme are traded in the dark theme for a more flat aesthetic. The GTK-2 versions require no external theme-engine dependency, using only the native and pixmap engines.
The steppenwolf themes provide a consistent look across applications with the GTK-2/3 versions and reasonable compatibility with the QGTK style plugin for QT5 applications. The GTK-3 themes, being written in a variant of css, make the theme spec easily translatable to most application frameworks, which is nice. To boot, the low resource usage makes them ideal for workstations or old machines where performance is the prime concern. If you're looking for a fresh theme experience on your Linux desktop or for your GTK applications on another operating system, look no further than steppenwolf!
checklist is a simple baby registry webapp in python + django, made to prepare for the birth of my son, Zia. It's still hosted/live for posterity, since Zia is at the time of this writing three and a half months old!
The backend is, again, django, and data store is in SQLite. Each row in the database is a unique ID field, a product description/name, a link to where it can be purchased, slots for a name and email of the person pledging to get the item, and finally a boolean value for if the item has been pledged/claimed. The main list view simply shows all database entries which have not been claimed, in order of ID numbers.
Upon clicking an entry in the main list view, you are brought to the above view, where you can follow the link to an online shop and enter your name and email address. If you pledge the item, you must fill out both fields.
If you, say, bookmark the detail view for any particular item, and return there after it has been pledged, you will see the above view, thus even knowing the ID number (and thus the URL) of any item, you cannot overwrite the database entry for another person's pledge.
As administrator, I can view the status of the database either by using the django admin panel or from the serverside with the django shell. From there I can add, edit, or delete rows.
The HyperKaos Engine is a 2D adventure/puzzle game engine originally written in C++ and then rewritten in C (with the SDL v1.2 library). It features a top-down adventure perspective reminiscent of the original Legend of Zelda (one room per screen), and a host of systems for interacting with the game world.
A room consists of a background spritesheet (four 320x180 sprites in a vertical spritesheet to enable ambient animation), and arrays of entities like obstacles, people, sigils (magic triggers), warps, and of course the titular HyperKaos.
HyperKaos are event chains, and they are made up of Kaos. The Kaos API is simple. Each subclass must implement run() and destroy(), and their constructors all share the same signature, taking a string as input and parsing it for necessary data to construct the Kaos. The inheritence of the Kaos API is implemented with a void pointer in the Kaos struct and a pointer to a Kaos in the subclass struct, creating a link both ways between the base class and the subclass. When the constructor for the subclass is run, it is responsible for linking the two structs together and assigning the function pointers for run() and destroy().
Map data is broken in to chunks and loaded on demand when the player enters that area of the game world. Chunk data was originally hardcoded in bufferData(), which was messy, inflexible, and very hard to debug. The new system is to have bufferData() call worldBuilder(), which reads map data from a text file in the mapdata/ directory. This is the reason for having all the Kaos subclass constructors take a single string argument. worldBuilder() checks the type of Kaos to be built and calls its constructor, passing it the args list as-is. The constructor then parses this list for the information it needs to build the Kaos. If any part of the map data file is malformed, the game exits with an error message.
The Kaos API is so versatile that HyperKaos chains underlie everything from textboxes to the magic system to scene triggers. The scene system is simple but powerful, allowing to break out of the top-down room context to display arbitrarily layered and moving sprites for a set time (they can be skipped if you want, like any good cutscene engine!).
The HyperKaos chains are also directly related to the save system. Each chain has an ID number which is multiplied onto the save state number when the chain is run. If its ID is 1, it doesn't have an effect on the overall state of the game. If its ID is a unique prime number, it alters the save state, making it a unique product of primes. This can be used to create branching storylines and a complexly changing world. The engine only supports one save slot for now, but you can easily copy and paste save files to bypass this.
Ayanami CMS is the backend of this website. It is a static site generator and content management system that aims to make it easy to keep a simple website up to date.
You run it from the serverside, after logging in via SSH. This offloads security concerns from the script itself, letting it do what it's meant to do: generate the website.
It leads you through an interactive session, selecting the page of the website to edit, and then whether to post something new, edit an existing post, or rebuild the page and/or the media library from an updated template.
If you post something new, the script leads you through the motions, asking for a title, a linked file (as many as you want if you just want to dump some images), and then giving control to your editor of choice to create the main content for the post. Depending on the type of file you link, the post will use a different template to hilight the filetype (ie, music or video player, vertical image gallery, file download with image preview). If you don't link a file in that step, you can still embed files in the main post content with HTML tags (as I'm doing with this post).
If you choose to edit a post, you are met with the database for that page. It will paginate with the same number of posts per page as the webpage itself (a setting in Ayanami's config.sh). You can paginate forward, return to the first page, exit back to initialization, or choose a post to edit.
In editing a post, you cannot change the template type or number of files linked, but you can change the title, URL of linked files, and the post body. You can also delete a post.
After finalizing a new or edited post, builds the permalink for it (called "islands"), and then builds the page itself, taking care of pagination based on the setting in config.sh.
The media library (formerly called the "archive") is a simple HTTP fileserver interface which lists files in the directories given in the "librarydirs" variable in the configuration. Here, I use it to host my mixes and digital art, and to mirror some of my videos.