Gradient Editor

matt7
Posts: 105
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone 8, Windows
Location: Kentucky, USA

Gradient Editor

Post by matt7 » Mon Aug 06, 2018 7:10 pm

The info in this post is basically copy-pasted from the README.txt file provided with the code.
Code can be found here: https://www.dropbox.com/sh/ihbq5jsb5vrz ... M7Jya?dl=0

Current version: 1.3
Latest changes:
  • Updated the Gradient Library to a new version that now supports several different interpolation methods. The parameter GRADIENT.interpMethod$ can be set to "linear", "cosine", "poly5", "cubic", or "cubicM". See the documentation in the Gradient Library file for more information.
  • Added the ability to change gradient drawing parameters from the Preview screen options. These are GRADIENT.bandWidth, GRADIENT.interpMethod$, and GRADIENT.easeAccel. NOTE: Cubic interpolation methods are supported, but gradients will not be updated until touches are stopped due to the long draw times.
  • Expanded the code that is written to gradient.txt to now include shape data and gradient drawing parameters from the Preview screen. The file is now also a standalone script that can be run. It will draw the last saved gradient onto a blank graphics window.
rbytes has also added some additional save and .png export features that he has shared and that you may be interested in. See his post here: https://kibernetik.pro/forum/viewtopic. ... 416#p13416

Description:

This program is designed to expedite the design of gradients that can be drawn using matt7's Gradient Library (https://kibernetik.pro/forum/viewtopic.php?f=20&t=2229).

Editing Gradients:

The core of this program is the Edit screen, where color and alpha gradient stops can be added, modified, and removed. Modifications to gradient stops include moving their position in the gradient and altering the color or alpha values they contain. Color adjustments can be made in the RGB or HSL color space.

Image

Saving and Loading Gradients:

A full-fledged Save screen and Load screen where multiple gradients can be saved and reopened for editing is planned, but for now only the following basic functionality is implemented:

Selecting "Save" in the menu will do two things. The first thing is it will update the gradient.dat file that is loaded on program startup, so the next time the program is started it will load the last saved gradient from this file. The second thing is it will update the gradient.txt file that contains a standalone script for drawing the last saved gradient. This is provided so that the code can be copy-pasted into another program for use with the Gradient Library.

Selecting "Load" in the menu will reset the gradient being edited or previewed to the last saved gradient.

Previewing Gradients:

While editing a gradient, it may be desired to see how that gradient will look drawn across a shape other than the fixed horizontal rectangle on the Edit screen. The Preview screen allows you to see the gradient across any shape in any direction supported by the Gradient Library. Handles also allow the resizing of these shapes. The list on the left side of the screen provides various display options, such as toggling outline visibility, toggling handle visibility, and cycling through different backgrounds (grid, white, black, and clear).

Image

Features:

Edit Screen:
  • To add a gradient stop, touch and hold the (+) button on the left side of the screen. A new gradient stop will appear, which can be dragged onto the gradient as either a color or an alpha gradient stop. While dragging to select the position the gradient stop will automatically update to match the current color or alpha value at that position in the gradient. This is useful for fine-tuning gradient transitions to lean more towards one color or alpha value than another.
  • To remove a gradient stop, touch and hold the gradient stop and drag your touch down to the bottom third of the screen. This will remove the gradient stop, but it will still be held for as long as your touch remains active, so you can drag it back onto the gradient if you change your mind.
  • While adjusting color and alpha values in the RGB, HSL, or Alpha slider page at the bottom of the screen, you can make finer adjustments by moving your touch towards the top of the screen. In the top third of the screen, your horizontal movements will adjust the slider by 1/5th of your touch movement. This is especially useful when adjusting the hue on the HSL page!
Preview Screen:
  • Touch and drag anywhere on the shape other than a gradient handle to move the gradient.
  • When touching a gradient handle, a dashed line guide will show where the handle can be moved.
Other:
  • To reset the default gradient that is loaded at program startup, simply delete gradient.dat.
  • If gradient updating is causing slow performance (during slider and gradient handle adjustments), go to the Global Parameters section in GradientEditor.sb and increase the GRADIENT.bandWidth parameter. 0.5 is the highest resolution (which is unnecessary for this program). 1 is standard, and increasing to 2 or higher will improve performance, though banding may appear in some or all of the gradients.
Code information:

Scope and Variable Info

With a program this large and extensive, I try to keep scope and variable names organized and grouped logically, but also very short. This helps keep the code more readable and in my opinion, makes it much easier to develop and change. However, for anyone else who wants to look through the code, it may be difficult to tell what all the prefixes and abbreviations used in variable names mean. For help deciphering variable names, see the following file:

doc/scope_and_var_info.txt

Object Registration

One interesting feature of this program is object registration and configuration. ("Objects" refer to pages, sprites, and fields.) I have developed some file scanning features to count the number of each object type for array declarations ahead of their configuration and creation. This allows me to simply add new objects to a screen's config file and never have to worry about resizing the arrays. The code also frequently calls a MATCH function (library file) that looks up an object index from its name, so I never have to worry about inserting new objects ahead of existing ones and changing their index in the page, sprite, or field structures (PG, SP, and FD). The code for the file scanning is found in src/startup/configure_objects.

Included Libraries

Some may also be interested in the library files that this program uses. I have provided full documentation for each library file in that file's header. Of particular interest to some may be the following:
  • lib/interface/touchpoll
    • Inspired by sneepy's Click and drag library, TAPPOLL (https://kibernetik.pro/forum/viewtopic.php?f=20&t=661)
    • Provides a polling routine for tracking touch 0. This populates the scope TP (for "touchpoll") with many useful variables about the current touch. For example, in this program, adjusting a slider requires the user to touch the slider handle and then move a small amount before the touch is considered a "movement". You can see in my processing code (src/screens/edit/process_E and src/screens/preview/process_P) that handles are moved by subtracting the current touch location from the location of the touch when it was first considered a "movement". I believe this provides a more stable-feeling experience for the user, instead of an object on screen starting to move/jiggle immediately upon being touched. Also provided, though not used anywhere currently in this program, is the ability to detect the direction of the initial movement (TP.d0$), so processing can be altered depending on the direction of the movement. This is similar to scrolling on a webpage, where scrolling up or down locks the scrolling to the vertical axis, but dragging at an angle allows movement in both x,y directions.
    • I have not incorporated some of the more advanced touch detections such as double clicks or classifying touches as taps, drags, swipes, etc., like sneepy's TAPPOLL routine. I instead opted for more of a minimalistic approach for processing speed, though I may consider developing some alternative, expanded touchpoll libraries with similar advanced features or even for tracking multiple touches.
  • lib/graphics/rgb_hsl
    • provides RGB <-> HSL conversions
  • lib/graphics/roundrect
    • provides functions for drawing and filling rounded rectangles
  • lib/geometry/ease
    • provides easing functions for smoother page and sprite movement (could be expanded, but serves the purposes of this program for now)
Last edited by matt7 on Thu Aug 16, 2018 3:57 pm, edited 4 times in total.

User avatar
rbytes
Posts: 1963
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Gradient Editor

Post by rbytes » Mon Aug 06, 2018 11:42 pm

Update: I still couldn't get the relative paths to work. I changed them all to absolute paths, and now have the GradientEditor program running. It is excellent. Of course if I move the GradientEditor folder, those paths will all have to be updated, so I hope you will investigate why the relative paths are not working correctly.

In the editor, I still haven't figured out how to remove a gradient stop. Adding or positioning one is easy. For removal, I tried long-clicking gradient stops, double-clicking them, dragging them horizontally past the end of the scale and dragging them vertically away from the gradient. No luck.

Original post:
I downloaded the Dropbox folder and installed it. I am getting path errors to all of the library files.

3969791A-62AA-4451-9E49-108A37CBD625.png
3969791A-62AA-4451-9E49-108A37CBD625.png (230.56 KiB) Viewed 548 times

I took a quick look and tried to fix the paths, but so far have had no success. Hope you will test everything with the same folder structure you posted on Dropbox, to make sure it all runs ok.
Zzzzz

matt7
Posts: 105
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone 8, Windows
Location: Kentucky, USA

Re: Gradient Editor

Post by matt7 » Tue Aug 07, 2018 3:13 am

Sorry for those difficulties getting it up and running. I ran it one final time for testing and then copied it straight to Dropbox, so I have no idea why the relative library includes are not working for you. They work fine for me (iPhone 8, iOS 11, sB 5.8). I wonder if compiling is not consistent across different devices?

Anyway, I'm glad you like it!

To remove a gradient stop, touch and hold it, and then drag down (the touch needs to be in about the lower third of the screen). It should remove the gradient stop immediately, and as long as you are continuing that same touch, the gradient stop is "held" and remembered, so you can add it back if you change your mind. This is one of the features that aren't obvious from within the program. I added a blurb about it in the README but that can be easy to miss.

The other feature which is "hidden" is scrubbing in the RGB, HSL, and alpha sliders. While moving the slider handles, if you move your touch to the upper third of the screen, slider movement becomes 1/5th of your touch movement. This is helpful for fine tuning values, especially on the hue slider.

matt7
Posts: 105
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone 8, Windows
Location: Kentucky, USA

Re: Gradient Editor

Post by matt7 » Tue Aug 07, 2018 3:59 am

rbytes, I just updated the program to remove all relative references in library includes (anything with "./" or "../"). I also moved all library includes to the main file GradientEditor.sb. Finally, I changed all {{ }} style includes to { } style includes, since I manually verified that there were no repeats by moving all includes to the head file.

Hopefully, this will solve the compile problems you were having. (Though the previous includes were working for me, so I don't have any way to test on my end if these changes will work for you.) But I did test after these changes and everything works fine for me like before.

My theory is that compiling is device dependent (probably unintentionally). For example, let's say file A resides in the top directory, and it includes file B which is in a subdirectory. If file B has an include for file C in it that uses a relative reference, what directory is used for the "current directory" for the relative reference when compiling? Perhaps this compiling activity is not deterministic. Here are two possibilities:
  1. C is brought into B first, using B's path for the starting point of the relative reference. Then B (that now also contains C) is brought into A.
  2. B is brought into A first, and then the relative reference to C (originally from B but now in A) uses A's path for the starting point of the relative reference.
So for me, I tested relative references and it seemed that option 1 was how it worked. But for your device, perhaps the compiling was done according to number 2. Another possibility is that this was caused (or further complicated) by the use of {{ }} rather than { }.

User avatar
rbytes
Posts: 1963
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Gradient Editor

Post by rbytes » Tue Aug 07, 2018 4:18 am

I just noticed a new post from you while I was composing one. Regarding the question about what the relative file paths for includes should be, perhaps the creator of Smart Basic could clarify that. Mr. Kibernetik usually reads all new posts, but you might also post your question in Other Topics to ensure he sees it.

My uncertainty about relative paths prompted me to change all paths to absolute (relative to the root folder), such as "/Graphics Demos/GradientEditor/libs/..." etc.etc. That solved my problem, but I will still download your new version and test it.

Thanks for the operational hints. You have designed a very polished interface. Nice smooth action on the sliders.

I can use the editor to create gradients, but I am still not certain how I can embed a saved gradient in a program of my own, positioning it exactly where desired. I didn't notice an explanation for this in the documentation.
Zzzzz

matt7
Posts: 105
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone 8, Windows
Location: Kentucky, USA

Re: Gradient Editor

Post by matt7 » Tue Aug 07, 2018 4:39 am

Technically, all includes are still relative paths (relative to the GradientEditor folder, wherever that is placed). I removed the "./" and "../" style paths and the {{ }} brackets, hoping that would fix it for you. I'm not sure how else to do it other than make them all absolute paths and tell everyone exactly where they have to put the program directory in their smart Basic folders. Is this what other people typically do for their programs? (I've only been grabbing single files/libraries from the forum, not programs with files in several layers of subdirectories.)

This program (the Gradient Editor) is only designed to help you get the values you need for the color data array and alpha data array (only two of the required inputs for each gradient drawing function). The gradient.txt file provides you with the code you can copy-paste into your program. But again, that auto-generated code only builds the color and alpha data arrays. It's up to you to define the other parameters for positioning/sizing the gradient.

If you look at the documentation for the Gradient Library (look at the header in the library file; see https://kibernetik.pro/forum/viewtopic.php?f=20&t=2229 or look in the library files of this program: lib/graphics/gradient) it tells you everything you need to know about generating the gradient across a shape (RECT, QUAD, or ELPS, using the corresponding function), the gradient directions supported by those shapes (horizontal vs. vertical for rectangles, radial vs. angular for ellipses, etc.). And finally it provides info about how to position and size the gradient (x,y,w,h vs. x,y,rx,ry, etc.). You can also check out the examples/loading screen demo. Note that any time I draw a gradient, I have to define all those parameters and then call RECTGRAD, QUADGRAD, or ELPSGRAD to perform that actual drawing of the gradient.

User avatar
rbytes
Posts: 1963
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Gradient Editor

Post by rbytes » Tue Aug 07, 2018 5:06 am

I downloaded the folder again from Dropbox. Your new path system works perfectly.

I created a QUAD gradient shaped as a triangle and saved it. Then I made a copy of one of your demo gradient programs (the one containing 6 gradient shapes) and tried to modify it to show my triangle gradient. I eliminated all gradients except one QUAD, and pasted in the data code section from "Gradient.txt". but I couldn't quite connect that data to the library call to display the gradient.

It would be a real benefit (for slow learners like me) if the saved "Gradient.txt" file was an executable program that displayed the gradient centered on screen. Then all I or other users would need to do is embed that code within our own programs and modify the position and size.
Zzzzz

matt7
Posts: 105
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone 8, Windows
Location: Kentucky, USA

Re: Gradient Editor

Post by matt7 » Tue Aug 07, 2018 5:30 am

Good to hear it's working now for you straight from Dropbox with no editing of the include paths. I'll post something over in the Other topics forum tomorrow about it. Hopefully, Mr. Kibernetik can clear up the confusion about how the libraries and compiling work. (Also, thanks for the earlier compliment on the polished interface!)

I like your suggestion about having the gradient.txt that is generated be a standalone program. I have plans on making a more complete Save screen with plenty of options about what gets generated in that file, and adding the shape data from the Preview screen sounds like a good option to provide. But for now, I decided I'd rather get the program out with the current basic save/load functionality, since the main purpose of the program is helping you design your gradients quickly without having to go back and forth between updating decimal RGB values in your code and rerunning your program to see the changes.

I'm also about to get very busy IRL so I'm not sure when I'll be able to add the other things I have planned. So my only recommendation to you for now is just to spend some time reading the documentation in the header of the Gradient Library file. I explain all function inputs and some other important things to know about how the functions work (for example, they all use graphics mode COPY, so gradients with transparency need to be drawn in a sprite if you want to preserve what is underneath them). Basically, each function is exactly the same as the standard smart Basic functions for rectangles, quadrilaterals, and ellipses ("circles"), except they add a color data array, alpha data array, and a gradient direction (string). And for the Gradient Editor, check out the README.txt file I wrote (or the original post above, which is basically the same thing).

User avatar
rbytes
Posts: 1963
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Gradient Draw

Post by rbytes » Tue Aug 07, 2018 6:14 pm

I spent a little time creating a simple Gradient Draw program for each gradient shape. Here is the one to display an ellipse.
I will post the others later today. The idea is that you copy the color and alpha code lines from a saved GradientEditor file and paste them into this code between the double lines.

You can then instantly display the gradient.

At a later time you can modify the x, y, size and direction variables. They are commented with explanations.

This was the gradient as I created it in the editor:

1DDC05ED-64CA-473B-97ED-C250A30C67A0.png
1DDC05ED-64CA-473B-97ED-C250A30C67A0.png (181.68 KiB) Viewed 512 times

And here it is in an ellipse, displayed by the attached code.

9C0249BD-15D9-4374-B6F6-34B4C20C166B.png
9C0249BD-15D9-4374-B6F6-34B4C20C166B.png (2.36 MiB) Viewed 517 times

Code: Select all

/*
Gradient Draw Ellipse
by rbytes, August 2018
displays an ELLIPSE gradient created in
GradientEditor by matt7
*/

{{/Library/Graphics/Gradients.lb}}
bw = .5   ' GRADIENT.bandWidth (gradient resolution = Retina)
ea = 6    ' GRADIENT.easeAccel (color interpolation smoothing = SmoothStep)
GRADIENT.bandwidth = bw
GRADIENT.easeAccel = ea
SET TOOLBAR OFF
GRAPHICS
GRAPHICS CLEAR
DRAW COLOR 0,0,0

'===================================================

' COPY THE CODE LINES DEFINING nC and nA FROM AN ELLIPSE GRADIENT FILE SAVED BY GradientEditor
' AND PASTE IT BETWEEN THE DOUBLE LINES HERE, ERASING ANY PREVIOUS DEFINITIONS OF nC and nA

nC = 0    '         Pos      Red      Green    Blue
nC += 1   !   DATA  0.0000,  0.0000,  1.0000,  1.0000
nC += 1   !   DATA  0.1176,  1.0000,  1.0000,  0.0000
nC += 1   !   DATA  0.2392,  0.0000,  1.0000,  0.9176
nC += 1   !   DATA  0.3608,  1.0000,  1.0000,  0.0000
nC += 1   !   DATA  0.4902,  0.0235,  1.0000,  1.0000
nC += 1   !   DATA  0.6275,  1.0000,  1.0000,  0.0000
nC += 1   !   DATA  0.7529,  0.0000,  1.0000,  1.0000
nC += 1   !   DATA  0.8784,  1.0000,  1.0000,  0.0000
nC += 1   !   DATA  1.0000,  0.1608,  1.0000,  1.0000

nA = 0    '         Pos      Alpha
nA += 1   !   DATA  0.0000,  1.0000
nA += 1   !   DATA  1.0000,  0.9294

'===================================================

DIM cD(nC,4)
    FOR iC = 0 TO nC-1
      READ cD(iC,0)
      READ cD(iC,1)
      READ cD(iC,2)
      READ cD(iC,3)
    NEXT iC

    DIM aD(nA,2)
    FOR iA = 0 TO nA-1
      READ aD(iA,0)
      READ aD(iA,1)
    NEXT iA

'Set x,y points to define shape
x1=512
y3=350

'Set radius
r=300


'Define the direction of the gradient
'dir$="r"    ' concentric gradient
dir$="a"    ' rotary gradient

'-------------------------------------------------------

ELPSGRAD(cD, aD, x1, y3, r, r, dir$)
DRAW CIRCLE x1, y3 SIZE r+0.5, r+0.5
 
PAUSE 5
Last edited by rbytes on Wed Aug 08, 2018 12:03 am, edited 2 times in total.
Zzzzz

User avatar
rbytes
Posts: 1963
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Gradient Draw

Post by rbytes » Tue Aug 07, 2018 8:12 pm

Here is a variation of the Gradient Draw program that displays RECT (rectangle) gradients.

Code: Select all

/*
Gradient Draw Rect
by rbytes, August 2018
displays a RECT gradient created in
GradientEditor by matt7
*/
{{/Library/Graphics/Gradients.lb}}
SET TOOLBAR OFF
bw = .5   ' GRADIENT.bandWidth (gradient resolution = Retina)
ea = 6    ' GRADIENT.easeAccel (color interpolation smoothing = SmoothStep)
GRADIENT.bandwidth = bw
GRADIENT.easeAccel = ea
GRAPHICS
GRAPHICS CLEAR
DRAW COLOR 0,0,0

'===================================================

' COPY THE CODE LINES DEFINING nC and nA FROM A RECT GRADIENT FILE SAVED BY GradientEditor
' AND PASTE IT BETWEEN THE DOUBLE LINES HERE, ERASING ANY PREVIOUS DEFINITIONS OF nC and nA

nC = 0    '         Pos      Red      Green    Blue
nC += 1   !   DATA  0.0000,  0.0000,  0.7804,  0.7804
nC += 1   !   DATA  0.4157,  1.0000,  0.6000,  0.0000
nC += 1   !   DATA  0.5098,  0.0000,  0.7804,  0.7804
nC += 1   !   DATA  0.6039,  0.9922,  0.6000,  0.0000
nC += 1   !   DATA  1.0000,  0.0000,  0.7804,  0.7804

nA = 0    '         Pos      Alpha
nA += 1   !   DATA  0.0000,  1.0000
nA += 1   !   DATA  1.0000,  0.9294


'===================================================

DIM cD(nC,4)
    FOR iC = 0 TO nC-1
      READ cD(iC,0)
      READ cD(iC,1)
      READ cD(iC,2)
      READ cD(iC,3)
    NEXT iC

    DIM aD(nA,2)
    FOR iA = 0 TO nA-1
      READ aD(iA,0)
      READ aD(iA,1)
    NEXT iA

'Set x,y points to define shape
x1=510
y1=350

'Set sizes
h=600
v=400

r1=h/2
r2=v/2


'Define the direction of the gradient
'dir$="x"
dir$="y"

'-------------------------------------------------------

RECTGRAD(cD, aD, x1, y1, h, v, "x")
DRAW RECT x1, y1 SIZE r1, r2
 
PAUSE 5
Below is the editing screen of GradientEditor showing the gradient I created, and an image showing the output of the Gradient Draw code.
Attachments
3BB04B3B-B2B2-4466-8E76-45D56CDC7C21.png
3BB04B3B-B2B2-4466-8E76-45D56CDC7C21.png (175.46 KiB) Viewed 510 times
4CD3F6B2-A9C0-4FD8-96B3-B40EDB482B2F.png
4CD3F6B2-A9C0-4FD8-96B3-B40EDB482B2F.png (1.89 MiB) Viewed 510 times
Zzzzz

Post Reply