Gradient Editor

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

Re: Gradient Editor

Post by rbytes »

Once you add the scrubbing feature, probably all devices will be able to set points that are accurate to 1 in .0001
I sent you the modified code. I discovered why my last PM didn't reach you. My message box was full!

Thanks for being open to suggestions and modified versions. You are welcome to adapt anything I post and use it in the official version or not.

Most of the active Forum members, like me, are strictly hobby programmers. I have had no formal training, just a lot of self-taught experience dating back to BASIC on the Commodore Vic 20 and 64, the Atari ST and various Amiga models. I wrote quite a few apps on the PC with Macromedia Authorware and Adobe Flash, and then got into HTML, CSS and PHP. Before discovering Smart Basic I was also a fan of Dark Basic and Pythonista for a while. What makes Smart Basic really cool is that you can create icons on your home screen to launch the programs. I have done that with a lot of mine. I also developed a launcher that I start from an icon that lets me launch any Smart Basic program (mine or others) from multiple pages of buttons. I have over 160 such programs.
The only thing that gets me down is gravity...

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

Gradient Editor V1.4

Post by rbytes »

This is a version of Gradient Editor with some enhanced features. I offer it for use until matt7's next update, expected around December 2018.

The feature descriptions can be found at the start of the code. There is an additional updated file, the template file gradient.txt located in folder src/templates/. Its code is in this post after the code for GradientEditor.txt, and should replace the old template file in the same folder.

Code: Select all

/*
GradientEditor V1.4 is a modification of GradientEditor V1.3 by matt7
V1.4 is contributed by me, rbytes, August 2018 for temporary use.
I hope it will be useful until the next major update by matt7, expected ~ December 2018

Added features of V1.4 (and feature requests for matt7's next update) include:

- an ASCII file named "gradient.tn" that is saved each time GradientEditor is run. It is an equivalent of "gradient.dat", which saves the gradient stops, but is in ASCII rather than binary. Therefore it can easily be modified in the SmartBASIC editor to change gradient stops, shapes and sizes.

- The file "gradient.dat", which contains only the gradient stop data, is still saved. But if the "gradient.tn" file exists, it is loaded instead of "gradient.dat". Currently only the gradient stop data is read from "gradient.tn", but a future update to GradientEditor may enable loading of shapes and their dimensions.

- an enhanced "gradient.txt" template file located in src/templates/ is required to generate the "gradient.txt" file that is saved in the main GradientEditor folder when you press the Save button.

- the executable "gradient.txt" file generated by GradientEditor.txt in its same folder location now contains a definition area for variables near the start of the code. The user can enter a .png image filename and assign values to two other variables, one to enable/disable image saving and the other to enable/disable exporting an image file to the Camera Roll.

- the graphics save area is precisely defined for each of the 3 shape types, to ensure that the saved transparent png image is as small as possible without cropping any part of the shape.

- instead of a 3 second pause when "gradient.txt" ends, it goes into a loop, waiting for a tap on the screen. Therefore you can view the screen image as long as you want before tapping to end the program.

- using x and y for the locations of RECT and ELPS shapes caused a syntax error in GradientEditor. This was because the QUAD shape uses arrays named x and y to define its four corners! The conflict was solved by renaming the RECT and ELPS location variables to x1 and y1. 

*/
'b'
'==============================================================
'
' Initialization
'
'==============================================================

''
'b'
'==============================================================
' SmartBASIC Setup/Options
'==============================================================

''
SET TOOLBAR OFF
SET ORIENTATION LANDSCAPE

REFRESH OFF

GRAPHICS CLEAR 1, 1, 1, 1    ' Will be set to transparent
REFRESH                      ' after the Wait screen is shown
PAUSE 0.1                    ' (for Preview screen background)
GRAPHICS

OPTION TEXT POS CENTRAL
OPTION SPRITE POS CENTRAL

SET LISTS CUSTOM

'b'
'==============================================================
' Libraries
'==============================================================

''
{lib/arrays/copy}
{lib/arrays/insert}
{lib/arrays/match}
{lib/arrays/sort}

{lib/constants/math}

{lib/geometry/cartesian}
{lib/geometry/clamp}
{lib/geometry/cubic_hermite_splines}
{lib/geometry/ease}
{lib/geometry/interpolation}

{lib/graphics/gradient}
{lib/graphics/rgb_hsl}
{lib/graphics/roundrect}

{lib/interface/touchpoll}

'b'
'==============================================================
' Global Parameters
'==============================================================

''
GET SCREEN SIZE .scrW, .scrH

.devTy$ = DEVICE_TYPE$()
.root$ = CURRENT_DIR$()
.dat$ = .root$ & "/gradient.dat"
.dt$ = .root$ & "/gradient.tx"
.q$  = CHR$(34)

' These can also be changed from the Preview screen
GRADIENT.bandWidth = 2    ' gradient res — impacts performance
GRADIENT.interpMethod$ = "poly5"
GRADIENT.easeAccel = 10

'g'
/*
    More configurability is available at the top of
    each screen's config file. For example:

    Edit Screen  (src/screens/edit/config_E)

      ED.maxColorGradStops    ' Controls the maximum number of
      ED.maxAlphaGradStops    ' color and alpha gradient stops

    Menu Screen  (src/screens/menu/config_M)

      MD.slideDuration    ' Controls menu slide on/off speed
*/

'r'
'  Enable/disable debugging aids
' -------------------------------

DEBUG.showTC = 0
DEBUG.showTxt = 0
DEBUG.simulateiPad = 0
DEBUG.threeTouchExit = 0

IF DEBUG.simulateiPad THEN
  .devTy$ = "iPad"
  .scrW = .scrH*4/3
'  .scrH = .scrW*3/4
END IF

IF DEBUG.showTxt THEN
  DEBUG.spinRate = 4
  DEBUG.nSpinChrs = 10
  DIM DEBUG.spin$(DEBUG.nSpinChrs)
  DEBUG.spin$(0) = "⠋"
  DEBUG.spin$(1) = "⠙"   ' Spinner characters for the debug
  DEBUG.spin$(2) = "⠹"   ' text field. This shows when the
  DEBUG.spin$(3) = "⠸"   ' program is using SLOWDOWN and how
  DEBUG.spin$(4) = "⠼"   ' performance is impacted during
  DEBUG.spin$(5) = "⠴"   ' certain operations. 
  DEBUG.spin$(6) = "⠦"
  DEBUG.spin$(7) = "⠧"
  DEBUG.spin$(8) = "⠇"
  DEBUG.spin$(9) = "⠏"
END IF

''
'b'
'==============================================================
' Create Pages (including all sprites, fields, etc.)
'==============================================================

''
GOSUB LOAD_ENUMS()

CREATE_WAIT_SCR()
SHOW_WAIT_SCREEN()
GRAPHICS CLEAR        ' Clear for Preview screen background
REFRESH

CONFIGURE_OBJECTS()
CREATE_OBJECTS()
SNAP_TO_SCREEN(.SCR_E)

'b'
'==============================================================
'
' Main Loop
'
'==============================================================

''
' Process
' ---------
DO

  IF TOUCHPOLL() OR (LI_HIT(.scr) > -1) THEN

    IF .scr = .SCR_E THEN
      GOSUB PROCESS_EDIT_SCREEN

    ELSE ! IF .scr = .SCR_P THEN
      GOSUB PROCESS_PREV_SCREEN

'y'
/*
    ELSE ! IF .scr = .SCR_S THEN
      GOSUB PROCESS_SAVE_SCREEN     ' TODO

    ELSE ! IF .scr = .SCR_L THEN
      GOSUB PROCESS_LOAD_SCREEN     ' TODO

    ELSE ! IF .scr = .SCR_X THEN
      GOSUB PROCESS_EXPT_SCREEN     ' TODO

    ELSE ! IF .scr = .SCR_Z THEN
      GOSUB PROCESS_SETT_SCREEN     ' TODO
*/

''
    ELSE ! IF .scr = .SCR_M THEN
      GOSUB PROCESS_MENU_SCREEN

    END IF ! END IF ! END IF

  ELSE
    SLOWDOWN

  END IF

'r'
  IF DEBUG.showTxt THEN
    DEBUG.t = TIME()
    DEBUG.c = (DEBUG.c+1) % (DEBUG.spinRate*DEBUG.nSpinChrs-1)
    DEBUG.s$ = DEBUG.spin$(FLOOR(DEBUG.c/DEBUG.spinRate))
    DEBUG.txtSys$ = " " & DEBUG.s$ & " " & STR$(DEBUG.t,"#")
    FIELD "debug" TEXT DEBUG.txtSys$ & " " & DEBUG.txt$
  END IF

  IF DEBUG.threeTouchExit AND TOUCH_X(2) > -1 THEN
    DEBUG.exit = .TRUE
    IF .scr = .SCR_M THEN .scr = MD.oldScr
  END IF

''
UNTIL MD.exit OR DEBUG.exit

'b'
'==============================================================
'
' Termination
'
'==============================================================

''
HIDE_SCREEN(.SCR_M)
HIDE_SCREEN(.scr)
IF DEBUG.showTxt THEN PAGE .PG_DEBUG HIDE
TEXT

END

'b'
'==============================================================
'
' Support Functions
'
'==============================================================

''
'b'
'==============================================================
' Touch Control Hit Detection
'==============================================================

''
DEF TC_HIT (scr, xT, yT)

  FOR iTC = TC.n-1 TO 0 STEP -1
    IF SP.scr(TC.iSP(iTC)) = scr THEN
      IF SPRITE_HIT(TC.nTC$(iTC), xT, yT) THEN RETURN iTC
    END IF
  NEXT iTC

  RETURN -1

END DEF

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

DEF UPDATE_TC_POS (iTC)

  nTC$ = TC.nTC$(iTC)
  iSP = TC.iSP(iTC)
  iPG = SP.pg(iSP)

  GET SPRITE nTC$ POS xTC, yTC
  xTC = PG.x(iPG) + SP.x(iSP)
  yTC = PG.y(iPG) + SP.y(iSP)
  SPRITE nTC$ AT xTC, yTC

END DEF

'b'
'==============================================================
' List Selection Detection
'==============================================================

''
DEF LI_HIT (scr)

  IF scr = .SCR_P THEN
    RETURN LIST_SELECTED(PD.nOptList$)
  END IF

  RETURN -1

END DEF

'b'
'==============================================================
'
' Saving the gradient data to file
'
'==============================================================

''
DEF SAVE_GRADIENT_DATA ()

'  Text file for copying to another program
' ------------------------------------------

  template$ = .root$ & "/src/templates/gradient.txt"

  txt$ = .root$ & "/gradient.txt"
  IF FILE_EXISTS(txt$) THEN FILE txt$ DELETE

  WHILE FILE_END(template$) = 0
    FILE template$ READLINE line$

    IF line$ = "/* Color Data (M1) */" THEN
      FOR iC = 0 TO ED.nC-1
        pos$ = STR$(INT(cD.E_G(iC,0)*255)/255, "#.####")
        r$   = STR$(INT(cD.E_G(iC,1)*255)/255, "#.####")
        g$   = STR$(INT(cD.E_G(iC,2)*255)/255, "#.####")
        b$   = STR$(INT(cD.E_G(iC,3)*255)/255, "#.####")
        line$ = "nC += 1   !   DATA  "
        line$ &= pos$ & ",  " & r$ & ",  " & g$ & ",  " & b$
        FILE txt$ WRITELINE line$
      NEXT iC

    ELSE ! IF line$ = "/* Alpha Data (M1) */" THEN
      FOR iA = 0 TO ED.nA-1
        pos$ = STR$(INT(aD.E_G(iA,0)*255)/255, "#.####")
        a$   = STR$(INT(aD.E_G(iA,1)*255)/255, "#.####")
        line$ = "nA += 1   !   DATA  " & pos$ & ",  " & a$
        FILE txt$ WRITELINE line$
      NEXT iA

    ELSE ! IF line$ = "/* Color Data (M2) */" THEN
      FILE txt$ WRITELINE "DIM cD(" & ED.nC & ",4)"
      FOR iC = 0 TO ED.nC-1
        pos$ = STR$(INT(cD.E_G(iC,0)*255)/255, "#.####")
        r$   = STR$(INT(cD.E_G(iC,1)*255)/255, "#.####")
        g$   = STR$(INT(cD.E_G(iC,2)*255)/255, "#.####")
        b$   = STR$(INT(cD.E_G(iC,3)*255)/255, "#.####")
        IF iC = 0 THEN
          pos$ &= "    ' Position"
          r$   &= "    ' Red"
          g$   &= "    ' Green"
          b$   &= "    ' Blue"
        END IF
        FILE txt$ WRITELINE ""
        FILE txt$ WRITELINE "cD(" & iC & ",0) = " & pos$
        FILE txt$ WRITELINE "cD(" & iC & ",1) = " & r$
        FILE txt$ WRITELINE "cD(" & iC & ",2) = " & g$
        FILE txt$ WRITELINE "cD(" & iC & ",3) = " & b$
      NEXT iC

    ELSE ! IF line$ = "/* Alpha Data (M2) */" THEN
      FILE txt$ WRITELINE "DIM aD(" & ED.nA & ",2)"
      FOR iA = 0 TO ED.nA-1
        pos$ = STR$(INT(aD.E_G(iA,0)*255)/255, "#.####")
        a$   = STR$(INT(aD.E_G(iA,1)*255)/255, "#.####")
        IF iA = 0 THEN
          pos$ &= "    ' Position"
          a$   &= "    ' Alpha"
        END IF
        FILE txt$ WRITELINE ""
        FILE txt$ WRITELINE "aD(" & iA & ",0) = " & pos$
        FILE txt$ WRITELINE "aD(" & iA & ",1) = " & a$
      NEXT iA

    ELSE ! IF line$ = "/* Shape Data */" THEN
      IF PD.shape$ = "RECT" THEN
        FILE txt$ WRITELINE "x1 = scrW/2"
        FILE txt$ WRITELINE "y1 = scrH/2"
        FILE txt$ WRITELINE "w = scrW*" &2*REAL(PD.re_sz)/.scrW
        FILE txt$ WRITELINE "h = scrH*" &2*IMAG(PD.re_sz)/.scrH
        FILE txt$ WRITELINE "dir$ = """ & PD.re_dir$ & """"
      ELSE ! IF PD.shape$ = "QUAD" THEN
        FILE txt$ WRITELINE "DIM x(4), y(4)"
        FILE txt$ WRITELINE "x(0) = " & STR$(PD.qu_x(0) + PD.wOptList/2) & "  !  y(0) = " & PD.qu_y(0)
        FILE txt$ WRITELINE "x(1) = " & STR$(PD.qu_x(1) + PD.wOptList/2) & "  !  y(1) = " & PD.qu_y(1)
        FILE txt$ WRITELINE "x(2) = " & STR$(PD.qu_x(2) + PD.wOptList/2) & "  !  y(2) = " & PD.qu_y(2)
        FILE txt$ WRITELINE "x(3) = " & STR$(PD.qu_x(3) + PD.wOptList/2) & "  !  y(3) = " & PD.qu_y(3)
        FILE txt$ WRITELINE "dir$ = """ & PD.qu_dir$ & """"
      ELSE ' PD.shape$ = "ELPS"
        FILE txt$ WRITELINE "x1 = scrW/2"
        FILE txt$ WRITELINE "y1 = scrH/2"
        FILE txt$ WRITELINE "rx = scrW*" & REAL(PD.el_sz)/.scrW
        FILE txt$ WRITELINE "ry = scrH*" & IMAG(PD.el_sz)/.scrH
        FILE txt$ WRITELINE "dir$ = """ & PD.el_dir$ & """"
      END IF ! END IF

    ELSE ! IF line$ = "/* Gradient Data */" THEN
      FILE txt$ WRITELINE "GRADIENT.bandWidth = " & GRADIENT.bandWidth
      FILE txt$ WRITELINE "GRADIENT.interpMethod$ = """ & GRADIENT.interpMethod$ & """"
      IF GRADIENT.interpMethod$ = "poly5" THEN FILE txt$ WRITELINE "GRADIENT.easeAccel = " & GRADIENT.easeAccel
      FILE txt$ WRITELINE ""
      FILE txt$ WRITELINE "t1 = TIME()"
      IF PD.shape$ = "RECT" THEN
        FILE txt$ WRITELINE "RECTGRAD(cD, aD, x1, y1, w, h, dir$)"
        FILE txt$ WRITELINE "t2 = TIME()"
        IF PD.OL THEN
          FILE txt$ WRITELINE ""
          FILE txt$ WRITELINE "DRAW COLOR 0, 0, 0"
          FILE txt$ WRITELINE "DRAW RECT x1, y1 SIZE w/2, h/2"
        END IF
      ELSE ! IF PD.shape$ = "QUAD" THEN
        FILE txt$ WRITELINE "QUADGRAD(cD, aD, x1, y1, dir$)"
        FILE txt$ WRITELINE "t2 = TIME()"
        IF PD.OL THEN
          FILE txt$ WRITELINE ""
          FILE txt$ WRITELINE "DRAW COLOR 0, 0, 0"
          FILE txt$ WRITELINE "DRAW QUAD x(0), y(0), x(1), y(1), x(2), y(2), x(3), y(3)"
        END IF
      ELSE ' PD.shape$ = "ELPS"
        FILE txt$ WRITELINE "ELPSGRAD(cD, aD, x1, y1, rx, ry, dir$)"
        FILE txt$ WRITELINE "t2 = TIME()"
        IF PD.OL THEN
          FILE txt$ WRITELINE ""
          FILE txt$ WRITELINE "DRAW COLOR 0, 0, 0"
          FILE txt$ WRITELINE "DRAW CIRCLE x1, y1 SIZE rx, ry"
        END IF
      END IF ! END IF
      FILE txt$ WRITELINE ""
      FILE txt$ WRITELINE "DRAW TEXT ""Draw Time = "" & STR$(t2-t1) & "" secs"" AT 5, 5"

    ELSE
      FILE txt$ WRITELINE line$

    END IF ! END IF ! END IF ! END IF ! END IF ! END IF
  END WHILE
 

  ' code to save gradient data to an ascii file that can be reloaded  (rbytes)
  tnt$ = .root$ & "/gradient.tn"
  IF FILE_EXISTS(tnt$) THEN FILE tnt$ DELETE

      FILE tnt$ WRITELINE str$(ED.nc)
      FOR iC = 0 TO ED.nC-1
        pos$ = STR$(INT(cD.E_G(iC,0)*255)/255, "#.####")
        r$   = STR$(INT(cD.E_G(iC,1)*255)/255, "#.####")
        g$   = STR$(INT(cD.E_G(iC,2)*255)/255, "#.####")
        b$   = STR$(INT(cD.E_G(iC,3)*255)/255, "#.####")
        FILE tnt$ WRITELINE pos$
        FILE tnt$ WRITELINE r$
        FILE tnt$ WRITELINE g$
        FILE tnt$ WRITELINE b$
      NEXT iC
      FILE tnt$ WRITELINE str$(ED.nA)
      FOR iA = 0 TO ED.nA-1
        pos$ = STR$(INT(aD.E_G(iA,0)*255)/255, "#.####")
        a$   = STR$(INT(aD.E_G(iA,1)*255)/255, "#.####")
        FILE tnt$ WRITELINE pos$
        FILE tnt$ WRITELINE a$
      NEXT iA

      FILE tnt$ WRITELINE PD.shape$
      IF PD.shape$ = "RECT" THEN
        FILE tnt$ WRITELINE "scrW/2"
        FILE tnt$ WRITELINE "scrH/2"
        FILE tnt$ WRITELINE STR$(REAL(PD.re_sz)/.scrW)
        FILE tnt$ WRITELINE STR$(IMAG(PD.re_sz)/.scrH)
        FILE tnt$ WRITELINE PD.re_dir$
      ELSE ! IF PD.shape$ = "QUAD" THEN
        FILE tnt$ WRITELINE STR$(PD.qu_x(0) + PD.wOptList/2)
        FILE tnt$ WRITELINE PD.qu_y(0)
        FILE tnt$ WRITELINE STR$(PD.qu_x(1) + PD.wOptList/2)
        FILE tnt$ WRITELINE STR$(PD.qu_y(1))
        FILE tnt$ WRITELINE STR$(PD.qu_x(2) + PD.wOptList/2)
        FILE tnt$ WRITELINE STR$(PD.qu_y(2))
        FILE tnt$ WRITELINE STR$(PD.qu_x(3) + PD.wOptList/2)
        FILE tnt$ WRITELINE STR$(PD.qu_y(3))
        FILE tnt$ WRITELINE PD.qu_dir$
      ELSE ! if PD.shape$ = "ELPS" THEN
        FILE tnt$ WRITELINE scrW/2
        FILE tnt$ WRITELINE scrH/2
        FILE tnt$ WRITELINE REAL(PD.el_sz)/.scrW
        FILE tnt$ WRITELINE IMAG(PD.el_sz)/.scrH
        FILE tnt$ WRITELINE PD.el_dir$
      END IF ! END IF ! ENDIF

        FILE tnt$ WRITELINE GRADIENT.bandWidth
        FILE tnt$ WRITELINE GRADIENT.interpMethod$
        IF GRADIENT.interpMethod$ = "poly5" THEN FILE tnt$ WRITELINE GRADIENT.easeAccel
        FILE tnt$ WRITELINE PD.OL


'  code for for saving gradient as binary data
' --------------------------------------------

  IF FILE_EXISTS(.dat$) THEN FILE .dat$ DELETE

  FILE .dat$ WRITE ED.nC
  FOR iC = 0 TO ED.nC-1
    pos = INT(cD.E_G(iC,0)*255)
    r   = INT(cD.E_G(iC,1)*255)
    g   = INT(cD.E_G(iC,2)*255)
    b   = INT(cD.E_G(iC,3)*255)
    FILE .dat$ WRITE pos, r, g, b
  NEXT iC

  FILE .dat$ WRITE ED.nA
  FOR iA = 0 TO ED.nA-1
    pos = INT(aD.E_G(iA,0)*255)
    a   = INT(aD.E_G(iA,1)*255)
    FILE .dat$ WRITE pos, a
  NEXT iA

END DEF

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

DEF LOAD_GRADIENT_DATA (dat$)

  ' code for loading ascii data
  tnt$ = .root$ & "/gradient.tn"
  IF FILE_EXISTS(tnt$) THEN
      FILE tnt$ SETPOS 0
      FILE tnt$ READLINE temp$ ! nC=val(temp$)
      DIM cD.E_G(nC,4)
      FOR iC = 0 TO nC-1
        FILE tnt$ readline temp$    ' pos
        cD.E_G(iC,0) = val(temp$)
        FILE tnt$ readline temp$    ' r
        cD.E_G(iC,1) = val(temp$)
        FILE tnt$ readline temp$    ' g
        cD.E_G(iC,2) = val(temp$)
        FILE tnt$ readline temp$    ' b
        cD.E_G(iC,3) = val(temp$)
      NEXT iC

      FILE tnt$ READLINE temp$ ! nA=val(temp$)
      DIM aD.E_G(nA,2)
      FOR iA = 0 TO nA-1
        FILE tnt$ readline temp$
        aD.E_G(iA,0) = val(temp$)
        FILE tnt$ readline temp$
        aD.E_G(iA,1) = val(temp$)
      NEXT iA
      FILE tnt$ READLINE PD.shape$
  ELSE
      ' code for loading binary data
      FILE dat$ SETPOS 0
      FILE dat$ READ nC
      DIM cD.E_G(nC,4)
      FOR iC = 0 TO nC-1
          FILE dat$ READ pos, r, g, b
           cD.E_G(iC,0) = pos/255
           cD.E_G(iC,1) = r/255
           cD.E_G(iC,2) = g/255
           cD.E_G(iC,3) = b/255
      NEXT iC

      FILE dat$ READ nA
      DIM aD.E_G(nA,2)
      FOR iA = 0 TO nA-1
           FILE dat$ READ pos, a
           aD.E_G(iA,0) = pos/255
           aD.E_G(iA,1) = a/255
      NEXT iA
  END IF
  END DEF

      /*  for future development
      IF PD.shape$ = "RECT" THEN newPg=.PG_P_RECT
      IF PD.shape$ = "QUAD" THEN newPg=.PG_P_QUAD
      IF PD.shape$ = "ELPS" THEN newPg=.PG_P_ELPS
      PAGE newPg SHOW
      PAGE oldPg HIDE
      
      FILE tnt$ READLINE PD.shape$
      IF PD.shape$ = "RECT" THEN
        FILE tnt$ READLINE "scrW/2"
        FILE tnt$ READLINE "scrH/2"
        FILE tnt$ READLINE STR$(REAL(PD.re_sz)/.scrW)
        FILE tnt$ READLINE STR$(IMAG(PD.re_sz)/.scrH)
        FILE tnt$ READLINE PD.re_dir$
      ELSE ! IF PD.shape$ = "QUAD" THEN
        FILE tnt$ READLINE STR$(PD.qu_x(0) + PD.wOptList/2)
        FILE tnt$ READLINE PD.qu_y(0)
        FILE tnt$ READLINE STR$(PD.qu_x(1) + PD.wOptList/2)
        FILE tnt$ READLINE STR$(PD.qu_y(1))
        FILE tnt$ READLINE STR$(PD.qu_x(2) + PD.wOptList/2)
        FILE tnt$ READLINE STR$(PD.qu_y(2))
        FILE tnt$ READLINE STR$(PD.qu_x(3) + PD.wOptList/2)
        FILE tnt$ READLINE STR$(PD.qu_y(3))
        FILE tnt$ READLINE PD.qu_dir$
      ELSE ! if PD.shape$ = "ELPS" THEN
        FILE tnt$ READLINE scrW/2
        FILE tnt$ READLINE scrH/2
        FILE tnt$ READLINE REAL(PD.el_sz)/.scrW
        FILE tnt$ READLINE IMAG(PD.el_sz)/.scrH
        FILE tnt$ READLINE PD.el_dir$
      END IF ! END IF ! ENDIF

        FILE tnt$ READLINE GRADIENT.bandWidth
        FILE tnt$ READLINE GRADIENT.interpMethod$
        IF GRADIENT.interpMethod$ = "poly5" THEN FILE tnt$ READLINE GRADIENT.easeAccel
        FILE tnt$ READLINE PD.O
        */

'b'
'==============================================================
'
' Subroutines and Functions for:
' Startup, Configuration, Object Creation, and Processing 
'
'==============================================================

''
{src/startup/enumerations}
{src/startup/configure_objects}
{src/startup/create_objects}

{src/screens/common/config_C}
{src/screens/edit/config_E}
{src/screens/menu/config_M}
{src/screens/preview/config_P}

{src/screens/wait/create_W}
{src/screens/common/create_C}
{src/screens/edit/create_E}
{src/screens/menu/create_M}
{src/screens/preview/create_P}

{src/screens/menu/process_M}
{src/screens/edit/process_E}
{src/screens/preview/process_P}

'==============================================================
Now the updated template file, which must be located in folder src/templates/
Do not confuse it with the file of the same name that is generated in the main GradientEditor/ folder

Code: Select all

'g'
/*
    This file is automatically updated whenever the gradient being edited or previewed in the main program is saved. It provides example code that can be copied into another program for drawing a gradient using matt7's Gradient Library (https://kibernetik.pro/forum/viewtopic.php?f=20&t=2229).

    This file is also a standalone script that when run will draw the last saved gradient to an empty graphics window. The script contains the gradient's color and alpha data from the Edit screen, and it also contains the gradient's shape data and other drawing options from the Preview screen.

    Two different methods for populating the color and alpha arrays are provided (only one is needed):

    1. The first uses DATA and READ commands. This method is more compact for higher numbers of color and alpha stops, more flexible for making changes like inserting and removing stops, and is also more convenient if the arrays will be renamed.

    2. The second manually assigns each value to the array. This may be preferable if DATA is already being used elsewhere in the program or for gradients with only a few stops.

*/
''
''
'r'
'==============================================================
'  Save Image Data
'==============================================================

''
image$="gradient.png"   ' image file to save    (0=no, 1=yes, must be valid name if saver = 1)
saver=1                 ' image save enable     (0=no, 1=yes, but must be yes if exporter = 1)
exporter=0              ' image export enable   (0=no, 1=yes)
IF exporter=1 then saver=1


'b'
'==============================================================
'  Color and Alpha Arrays
'==============================================================

''
'  Method 1: DATA and READ
' -------------------------

nC = 0    '         Pos      Red      Green    Blue
/* Color Data (M1) */

nA = 0    '         Pos      Alpha
/* Alpha Data (M1) */

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


'  Method 2: Manual Assignment
' -----------------------------

/* Color Data (M2) */

/* Alpha Data (M2) */

'b'
'==============================================================
'  Shape Data
'==============================================================

''
SET TOOLBAR OFF
SET ORIENTATION LANDSCAPE
GET SCREEN SIZE scrW, scrH

/* Shape Data */

'b'
'==============================================================
'  Draw Gradient
'==============================================================

''
{lib/graphics/gradient}
{lib/geometry/cubic_hermite_splines}

GRAPHICS CLEAR
GRAPHICS
DRAW COLOR 0, 0, 0

/* Gradient Data */


'g'
'==============================================================
'  Image Save and Export
'==============================================================

''

IF saver THEN
if len(dir$)=6 then                 'quad shape
  sx1=MIN(x(0),x(1))-1    ' upper left corner x
  sy1=MIN(y(0),y(3))-1    ' upper left corner y
  sx2=MAX(x(2),x(3))+2    ' lower right corner x
  sy2=MAX(y(1),y(2))+2    ' lower right corner y
  GRAPHICS SAVE sx1,sy1,sx2-sx1,sy2-sy1 to image$
ENDIF
IF DIR$="r" OR dir$="a" THEN        'ellipse shape
  GRAPHICS SAVE x1-rx-1,y1-ry-1,rx*2+2,ry*2+2 to image$
ENDIF
IF DIR$="x" OR dir$="y" THEN        'rect shape
  GRAPHICS SAVE x1-w/2-1,y1-h/2-1,w+2,h+2 to image$
END IF
ENDIF

IF exporter THEN
  ALBUM EXPORT image$
END IF

'g'
'==============================================================
'  Touch (Hold) to End
'==============================================================

''
LOOP: SLOWDOWN
GET TOUCH 0 AS tx,ty
IF tx<>-1 THEN
  IF laun$="desktop" THEN
    IF FILE_EXISTS("/launch") THEN
      RUN "/-Launch.sb"
    ELSE
      EXIT
    ENDIF
  ENDIF
  END
ENDIF
GOTO LOOP


'==============================================================
The following images show how the executable gradient.txt file saved by GradientEditor.txt in the GradientEditor/ folder saves the gradient shape to a .png file. These three shapes were also exported to my Camera Roll. They seem quite large, but that is only because they are cropped very closely around their edges to make the image files as compact as possible.
Attachments
5DD2E881-1EF6-4858-A994-01FF1A2A7CFA.png
5DD2E881-1EF6-4858-A994-01FF1A2A7CFA.png (387.48 KiB) Viewed 2587 times
74DC693C-1DBC-4F5C-8374-3E17E0EBE812.png
74DC693C-1DBC-4F5C-8374-3E17E0EBE812.png (970.99 KiB) Viewed 2587 times
6D549E0C-DE10-4A97-ACA3-DF9AEA70AC0B.png
6D549E0C-DE10-4A97-ACA3-DF9AEA70AC0B.png (685.08 KiB) Viewed 2587 times
The only thing that gets me down is gravity...

matt7
Posts: 115
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone
Location: USA

Re: Gradient Editor

Post by matt7 »

Very nice, rbytes. Good idea sticking some optional save and export functionality into the gradient.txt script.

I updated the OP to mention that you shared a version with some added features, and linked to your post.

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

Re: Gradient Editor

Post by rbytes »

Thanks, matt7. It's nice to find another Forum member who is exploring the graphics power of sB.
The only thing that gets me down is gravity...

Post Reply