Announcing Sagebox, a Windows C++ Tool for Beginners,
Hobbyists, and Professionals
Contact e-mail:
rob@projectsagebox.com
Programming C/C++ with Windows Made Simpler
Sagebox is a set of C++ tools to
write WIndows or Console-Mode programs that use Windows
functions as easy as scripting language, but with the power,
structure and speed of compiled C++.
With Sagebox, you can write a C/C++ program that uses the full
power of windows as a simple procedural program, or as a
fully-canonical event-driven program. -- or a mixture of the
two, allowing you to start quickly and then, if desired, move
into more complex event-driven Windows elements as you go.
I wrote and have been using Sagebox as a personal tool for
years, writing commercial programs (such as Sagelight Image
Editor), neural networking applications, and in private computer
consulting to create high-level GUI applications to talk to and
control hardware, such as emulators and general development
tools.
I spent the last few months putting on easy-to-use interface
around the core functions of Sagebox, so that anyone can use it
with very little introduction.
Sagebox is free for personal use
Sagebox is free for personal use, and is also great as
professional tool, useful for building and developing. Sagebox is
going to try to go the free routine and look for funding through
donations, perhaps a GoFundMe, or some other way to finance the
development. For work-related and other professional use, please
contact
rob@projectsagebox.com
Sagebox is
pure C/C++
Since Sagebox pure C/C++ and is not a scripting language or a
programming environment, it works with your C/C++ coding style,
and can be brought into existing code as simply as bringing in
an external library. While Sagebox provides very powerful
functions and methods, you can keep your program as your
program, writing it in any style you wish, with Sagebox there to
help.
Since Sagebox works procedurally as well event-driven, you can
bring Sagebox into an existing project, console mode or Windows,
to add Windows and other functions without changing the style of
your code.
Creative
Development and Casual, ad-hoc Programming — How Sagebox Began
The main focus of Sagebox is the idea of creative development
and a way to stay in
the creative process white developing or simply playing around
with code. This can be hard to do today with so
many needs of the OS and the event-driven structure that needs
to be understood. This often causes us to split out our program
into an event-driven model vs. procedural, making it harder to
understand, develop and change. When we want to develop
creatively with the need to create a specific structure for our
code just to support the UI and other elements, it can mean
writing more code just to support that structure than the actual
code focused on what we're wanting to accomplish. In many cases, the answer
is that we just don't do it unless we have to, or implement it
minimally, which thwarts the creative process (and sometimes the
fun of programming)
I personally like the modern-day
operating systems and their respective UI's work. It brings a lot of
power, but also a lot of overhead. We can use that same power to do things
more simply, without
losing anything. Most of the time, with the right tool-set,
C/C++ programs don't actually need to be written in an event-driven
structure, even when they are based in the Windows UI. Much of the time, this is required simply because we
want to put something on the screen or talk to a device. We
can do that in very different ways now, including procedurally
or through sub-classing. The events of the OS are still with
us, as they should be, but there are different ways to go about
handling them where we don't need to split our program up into
pieces.
This is really the heart of Sagebox: keep things simple without
losing power, and to make it easy when we do want to get more
complex. Sometimes,though, you want to handle events as
events. Sagebox has a built-in method to handle the transition
and working with both procedural handling and event-driven
handling together.
The Question
was, "Why go through all of the work to create a button, slider,
or other control and the related event code just for something I
may not use?"
Sometimes I just want to be creative and work on other things,
and this was literally the question I asked myself. I wanted
something easier, functional, and consistent. I didn't start in
Windows programming but learned it to support what I did best:
writing low-level fast routines -- which now days, writing
GUI-based desktop code is a much
better way to develop even low-level embedded systems. I didn't
want to write an entire event-driven structure just because I
needed GUI plaform, but definitely wanted to stay with C++ and
the ability to drop into .ASM/SSE code whenever I wanted (since
I'm a low-level guy), or to emulate the C/C++ I might use on the
device or elsewhere.
So, I wrote Sagebox to allow me to do what I really like to do:
powerful, creative C++ development in
away where I can focus on my development code.
Wistfully
Remembering the Old Days
I was watching a video by Thomas
Figg, entitled
"Programming
is Terrible" (I am sure
the title is sarcastic) and he asked the audience who started
in Logo. A few people raised their hands. His response was,
"That's
why you've never escaped programming. It was so much fun in the
beginning and you've been trying to find and recapture that ever
since -- I know I have."
Well, that's me, too, and I wrote Sagebox to do exactly that,
Creative Computing Magazine
Anyone remember this cover? |
For me, it wasn't the language Logo, but assembly language and
Basic, and a magazine called Creative Computing. What a
wonderful magazine. You could just type in the programs they
would give you and they would run! You didn't always understand
what the code did, but you could modify it and play with it. In
the above magazine cover is an Ascii representation of Spock
from Star Trek.
I wanted to recapture those days with C/C++. Though Sagebox
has matured into a development tool useful across the board,
this is where Sagebox started, with the focus of creative
development and the fun of programming.
Now days, we can do much more
interesting things with ASCII pictures (such as the above image if we want to), such as gray-scaling, using
color, or a black background for more contrast.
To
re-create this
picture, all I have to do is create a window, print
ASCII characters in the font chosen, copy them into bitmaps,
average them for their light value, and distribute them
accordingly. I can also apply Floyd-Steinberg dithering in
real-time by just checking a box -- back, then I bet it was much
harder! (I will be releasing the source code for this shortly).
The dithering code, for example, is easily found on the Internet
in copy-and-paste form, and it doesn't take a lot to adapt it
for this or other purposes.
We can program in C/C++ just
like a Scripting Language and have as much or more power.
Scripting languages are great, and I am not
trying to take anything away from that idea. On the contrary, I
want to give something back to C/C++, something it has really
earned over the last few years.
In the last few years (decade even), a lot of development that would otherwise go to C/C++ has gone
toward scripting languages for a very good reason: C++ just
wasn't safe or easy for some tasks unless you were a dyed-in-the-wool
hardcore programmer, which most of us are not. I am one of
those programmers, but I
still don't want to do all that work just to develop and
experiment with new algorithms. As much as possible, I just want
to focus on the algorithms and development code instead.
Since the release of C++11, C/C++ has become a much more amazing
tool, correcting -- if sometimes only in philosophy -- many
issues that were problematic. From RAII (a horrible name for
really just not creating open-ended memory) to lambdas, to a
better use of the STL, and so-forth, C++ has really grown and
fixed a lot of things that have bothered programmers for a long
time. In fact, with C++20 (or is it C++21), I am very excited
still about changes coming, particularly the yield() statement
-- it only took 40+ years from the original concept, but it's
finally here! -- that alone is going to make for some great
programs I'm already thinking about.
C++ can now really be used in a much tighter, less error-prone
environment. With that, and being able to program
procedurally under Windows, we can program in a similar
environment, but with the structure of and speed of C++ --
working directly on the machine rather than through a VM. Of
course, JIT and other elements of VM-based languages makes
things better, but you can build much faster process with C++,
not to mention the addition of using instrinsics, asm, and SSE.
Before C++11, the idea that C++ as a heavily structured,
statically-typed language
may have been a draw towards scripting languages and away from
C/C++. I respect
that, and now, with all of the new things since C++11, I see the
structure as much more of a strength than it was before.
Programs these days are bigger, do more, and are more complex --
all good things because it lets us do more, and we can do it
very quickly with the right tools. That C/C++ structure keeps
things in check and speed much faster (after all, if you have to
top-level-decipher and convert a type on every other operation,
it's going to be slower). With all of the additives of C++11
and forward, that strong typing and structure now becomes a safe
harness without being too restrictive.
The only thing missing is being
able to parse dynamically while running
It's not released in the Alpha version, but Sagebox has a
fully-developed object-oriented scripting language. Sagebox was
also originally written as a scripting language with a full
IDE. That part never really saw fruition,but the scripting
language had already been built, based on my experience as part
of the Delphi & Kylix compiler development team at Borland, back
in its glory days.
In the next version or so of Sagebox, this will lead to the idea
of being able to pass RegEx, functions, and dynamic source code
through Sagebox to use as a scripting language.
The goal for Sagebox is to add
to using C++ as a Creative Development Platform
Again, not taking anything away from scripting or other
languages, such as Python, Java, Javascript, Visual Basic, etc.
(in fact, I highly recommend P5 that is under Javascript).
Everything has its strength.
With Sagebox, I am hoping to provide a set of tools that can
help bring back the old days of creative development, casual,
ad-hoc programming, in a way where we can just go for it and
worry about how we're going to refactor it later -- whether it
means keeping it
using Sagebox tools, move it to MSVC, Java, C#, whatever.
Support for
procedural programs, event-driven, or a mixture.
Sagebox can be written as a pure procedural program or
event-driven program, in either console mode or Windows. With
Sagebox, you can change your program from Windows to Console
Mode or back again with a project switch, without changing any
code whatsoever.
Sagebox can also be written as a mixture of procedural code and
event-driven code. This lowers the learning curve and workload,
by allowing most elements to take place in a procedural mode,
moving to event-driven methodology as needed. It turns out that
most programs don't need to be written as event-driven at all, even in
Windows, but when there is a use for it, Sagebox allows you to
move with your needs.
Windows
Controls
All of the basic controls are supported in Sagebox, and all of
them can
be personalized. For example, you can create
your own graphic buttons with just 2-3 lines of code (and the
bitmaps you create).
Windows, Buttons, Sliders, List Boxes, Combo Boxes, Checkboxes,
as well as other control types such as Bitmap Windows, Dialog Windows,
and more -- all give a lot of power in just a few lines of code,
in procedural console mode or a pure event-driven Windows
program.
Quick Dev
Controls
The Quick Dev Controls are worth discussing as a separate
subject. They were written specifically for development.
Originally written for console-mode apps to use Windows
functions more discretely, the Quick Dev Controls turned out to
be so useful, I use them for primary development (Windows or
Console Mode), and then move to a proper GUI once I've decided
how I want to go about the user interface.
Quick Dev Controls are additive. You don't need
to create a window to support them, and
as you add controls, the window it creates grows to the size of
your controls.
For example, let's say you have some code and you just want to
put up a simple button to get some input. You can just specify
auto& cButton =
cSagebox.DevButton("Press to Quit");
You can just call up the Dev button
and it will put up the following window:
You can then check the button status with:
if
(cButton->Pressed()) { <some code> }
or you can also tell it to fill a boolean value so that you can
just look at the boolean to determine if the button was pressed.
If I then want to add a checkbox, slider, or Window, it's easy.
For example, adding a status window is easy:
auto& StatusWin =
cSagebox.DevWindow("Status Window"); // You don't need a
name
StatusWin << "Hello
World!\n"; // You can also use printf() or Write()
This will bring change the window and add the text, as follows: This will bring change the window and add the text, as follows:
And so-forth, adding controls as you go.
As you add controls, the Quick Dev Window resizes itself. Here
is the entire program for the above (which can work equally as a
Console Mode program or Windows program), taken directly as a
screenshot from the editor:
This waits until the button is pressed, then exits the program.
Widgets
Sagebox features a very easy way to use widgets -- either
through a procedural program or Windows event-driven program.
The Widgets allow powerful functions with just a call. For
example, this widget:
Color Selector Widget
The Color Selector Widget can be used with 2 lines of code: One
to bring it up in its own window, or recessed in your window,
and another line of code to actually use it.
The line to instantiate it the Color Selector looks like this:
auto MySelector =
ColorSelector(50,100); // Put Color Selector
at X=50 and Y=100
The Widget then comes up. Whether through a simple procedural
program or in reaction to WIndows event sent by the Color
Selector Widget, you can then do the following to use it:
if
(MySelector.ValueChange(rgbValue)) { DoSomethingWidth{rgbValue) };
You can also set the colors, get the current color in Rgb or HSL
format, move the window, and a number of other functions.
Curves Selection Widget
Similarly, the above Widget can be used to select curves and get
the results in just a few lines of code.
If you're a Sagelight user, you might recognize this curves
box. It is being brought over from Sagelight as well as number
of other widgets.
More Widgets Coming
Sagebox has just been released, and now that it is out, I can
add many more Widgets.
Sagebox
Functions and Classes
While Sagebox is pure C++ and doesn't want to interfere in how
you want to program, Sagebox also offers powerful functionality
in various classes and functions. More are being added now that
the Alpha version has been released.
Types such as CPoint (similar to MSVC, but with more
functionality), CString, CBitmap, CComplex, CSageTools, and
others all work to make programming easier.
Sagebox for
Beginners, Hobbyists, and Professionals
Since Sagebox lets you write procedurally, in a Windows program
or Console Mode program, it's easy for people new to programming
in a GUI environment, or new to C++, in general. Every program
you write using Sagebox can be a Windows program or a Console
mode program with a project switch and without changing any
code.
For example, the following program:
gets a file name from the user with the Windows File Dialog,
loads the image file, then displays it in a window. Usually,
you might want to check for errors, empty file names, and
so-forth. But, for this demo, it doesn't matter -- Sagebox is
written to understand everything happening in the system. With
the code above, if there is a problem and the code doesn't check
for errors, Sagebox simply falls
through -- it just won't load a bitmap, which
will cause the window creation to fail, which will case
WaitforClose() to fallthrough.
If you want to check events,
such as mouse clicks and mouse movement,
you can do this:
Though this is a small program, this is a fully functional
Windows program -- or a console-mode program that uses Windows
functions. Note that you can change the color of the text
inside the text string, or you can specify the color as an
option.
Casual,
Creative Programming for Hobbyists (and professionals)
For hobbyists, Sagebox has a great set of functions to allow
simple, ad-hoc-style creative programming. As the program
matures, it can be put into a more proper structure, refactored,
and possibly turned into a more even-driven approach if needed.
This allows a lot of movement with just playing around
with code that may turn into something or didn't work out, all the way to primary development and program completion.,
One of the main points of Sagebox is that because its so easy to
simply experiment, you end up doing it because, well, it's fun.
For Professionals
Since I wrote Sagebox, I have been using it professionally and
commercially for quite some time. Depending on the
application or situation, I will write entire programs with
Sagebox, or in the
case of working with a project on another platform, I use
Sagebox as a support, development, and testing tool to even when it isn't the main
development environment.
For researchers and
programming professionals, Sagebox offers a very fast
methodology to create development items -- in a procedural
fashion or working with event-driven development.
In the code in the last section, for example, I might want to keep the
MouseClicked() event where it is, but for mouse movement, I
might want to get the event. With Sagebox, it's very easy. You
just either sub-class the window or set a Message Handler and
then overload the MouseMove() function. This allows you to only
use the event-driven approach for specific items without the
need to make everything event-driven.
This allows the thread to take its time where it is ok to do so,
but then to get the important items as quickly as possible.
Most of the time, programs don't need any event-driven
structure. Sagebox works with both, and you can also trap the
original Windows message to work directly with Windows. Sagebox
also gives you full control over the Windows environment - you
can simply grab the Window Handle and Device Context and do what
you want with it.
Alpha Version - What's Next for Sagebox?
The great thing is that Sagebox is only going to get better.
The Alpha version is about getting feedback and input so that
Sagebox can work better for those who use it.
The Alpha version has been months in development, making an
interface, classes, and functions around a larger body of code
written over the years for fast, creative development using
Windows.
Now that the Alpha is
completed, there are many new additives to come in the next
year, such as solid GPU support, a UI designer, procedural
Internet functions more controls, and especially Widgets.
There is a very large body of functions, widgets, and other code
from Sagelight and other libraries I've written over the years,
ready to be installed into Sagebox.
|