Page 1 of 3

128 Slider/Faders Include Crossplatform - Redesigned

Posted: Tue Mar 05, 2013 5:59 am
by netmaestro
Here is a slider/fader object that uses all native commands and so -should- be crossplatform. It works on Windows, if someone could test on MacOS and Linux it would be appreciated.

Notes:

1. Because no callbacks are used, some small code is required in your event loop:

Code: Select all

    Case #PB_Event_Gadget
      Select EventGadget() 
        Case Fader\canvas()
          Fader\ProcessFaderEvents(Fader)
2. The 128 canvas gadgets are replaced by 1 canvas gadget and 128 memory objects. This allows for mousebutton control of drawing the sliders instead of the awkward shift key.

Any bugs, let me know please. Thanks for testing!

Code: Select all

;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;
;Program:   Fader Gadget Include - CrossPlatform
;Author:    Lloyd Gallant (netmaestro)
;Date:      March 6, 2013
;License:   Free, Do as you like, NO WARRANTY WHATSOEVER
;
;Usage:     <yourfader>.iFADER = New_Fader(x, y) creates a new Fader gadget on the window
;
;           <yourfader>\SetColumn(column, level) sets the column to the desired level 
;
;           <yourfader>\GetColumn(column) returns the currently set level of the column
;
;           <yourfader>\RedrawColumn(column) redraws the column (SetColumn() does not redraw)
;
;           <yourfader>\Move(x, y) moves the fader gadget to a new location on the window
;
;           To set fader levels, hold left mousebutton down while moving mouse over fader 
;           or click a column to set the level at the mouse position
;
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Interface iFADER
  canvas()
  SetColumn(column, level)
  GetColumn(column)
  RedrawColumn(column)
  ProcessFaderEvents(*fader.iFADER)
  Move(x, y)
  Free()
EndInterface

Structure FADER
  *vTable
  Array iLevel.i(127)      ; 127 images, one to render each level 
  Array columnlevel.i(127) ; 128 memory areas to set/get the state of each column
  canvas.i                 ; gadget# of canvas that contains the 128 columns
EndStructure

Procedure Fader_Canvas(*this.FADER)
  ProcedureReturn *this\canvas
EndProcedure

Procedure Fader_SetColumn(*this.FADER, column, newlevel)
  If column>=0 And column<=127
    If newlevel>=0 And newlevel<=127
      *this\columnlevel(column) = newlevel
      ProcedureReturn 1
    Else
      ProcedureReturn 0
    EndIf
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure Fader_GetColumn(*this.FADER, column.i)
  ProcedureReturn *this\columnlevel(column)
EndProcedure

Procedure Fader_RedrawColumn(*this.FADER, column.i)
  StartDrawing(CanvasOutput(*this\canvas))
    columnx = 4+6*column
    DrawImage(ImageID(*this\iLevel(*this\columnlevel(column))),columnx,4)
  StopDrawing()
EndProcedure

Procedure Fader_Free(*this.FADER)
  If IsGadget(*this\canvas)
    FreeGadget(*this\canvas)
  EndIf
  For i=0 To 127
    If IsImage(*this\iLevel(i))
      FreeImage(*this\ilevel(i))
    EndIf
  Next
  ClearStructure(*this, FADER)
  FreeMemory(*this)
EndProcedure

Procedure Fader_Move(*this.FADER, x, y)
  ResizeGadget(*this\canvas, x, y, #PB_Ignore, #PB_Ignore)
EndProcedure

Procedure Fader_ProcessEvents(*this.FADER, *fader.iFADER)
  If EventType() = #PB_EventType_MouseMove Or EventType() = #PB_EventType_LeftButtonDown
    If GetGadgetAttribute(*this\canvas, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
      foundlevel = 127-GetGadgetAttribute(*this\canvas, #PB_Canvas_MouseY)+4
      If foundlevel<0:foundlevel=0:EndIf
      If foundlevel>127:foundlevel=127:EndIf
      foundcolumn = (GetGadgetAttribute(*this\canvas, #PB_Canvas_MouseX)-4)/6
      If foundcolumn<0:foundcolumn=0:EndIf
      If foundcolumn>127:foundcolumn=127:EndIf
      *Fader\SetColumn(foundcolumn, foundlevel)
      *Fader\RedrawColumn(foundcolumn)
    EndIf
  EndIf
EndProcedure

Procedure New_Fader(x, y)
  *this.FADER = AllocateMemory(SizeOf(FADER))
  InitializeStructure(*this, FADER)
  *this\vTable = ?FADER_Methods
  
  fg_iCol = CreateImage(#PB_Any, 6, 128) 
  StartDrawing(ImageOutput(fg_iCol))
    Box(0,0,6,128,$D1D1D1)
    DrawingMode(#PB_2DDrawing_Gradient)      
    BackColor($D3FFFF)
    GradientColor(0.32, $A1FFFF)
    GradientColor(0.62, $CE8484)
    FrontColor($E6EEEE) 
    LinearGradient(0, 0, 0, 127)      
    Box(1,0, 4, 128)
  StopDrawing() 
  
  For i=0 To 127
    temp = GrabImage(fg_iCol, #PB_Any, 0, 127-i, 6, i+1)
    *this\iLevel(i) = CreateImage(#PB_Any, 6, 128)
    StartDrawing(ImageOutput(*this\iLevel(i)))
      Box(0,0,6,128,$D1D1D1)
      Box(1,0,4,128,$EFD6AD)
      DrawImage(ImageID(temp), 0, 128-i)
      FreeImage(temp)
      For j=3 To 123 Step 4
        Line(0,j,4,1,$EF1010)
      Next
    StopDrawing()
  Next
  
  FreeImage(fg_iCol)
  
  savedlist = UseGadgetList(WindowID(window))
  *this\canvas = CanvasGadget(#PB_Any,x,y,776,136)
  HideGadget(*this\canvas, 1)
  StartDrawing(CanvasOutput(*this\canvas))
    Box(0,0,GadgetWidth(*this\canvas),GadgetHeight(*this\canvas),RGB(160,160,180))
    For i=0 To 127
      DrawImage(ImageID(*this\iLevel(0)),4+6*i,4)
    Next
  StopDrawing()
  SetGadgetData(*this\canvas, *this)
  UseGadgetList(savedlist)
  HideGadget(*this\canvas, 0)
  
  ProcedureReturn *this
  
  DataSection
    FADER_Methods:
    Data.i @Fader_Canvas(),
           @Fader_SetColumn(),
           @Fader_GetColumn(),
           @Fader_RedrawColumn(),
           @Fader_ProcessEvents(),
           @Fader_Move(),
           @Fader_Free()
  EndDataSection
  
EndProcedure

;////////////////////////////////////////////////////////////
;
;                END OF FADER GADGET INCLUDE
;
;////////////////////////////////////////////////////////////


; Little test proggie:

OpenWindow(0,0,0,900,300,"")
TrackBarGadget(0, 20,50,20,136,0,127,#PB_TrackBar_Vertical)

Fader.iFADER = New_Fader(60,50)

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget() 
        Case Fader\canvas()
          Fader\ProcessFaderEvents(Fader)
          
        Case 0
          For i=0 To 127
            Fader\SetColumn(i, GetGadgetState(0))
            fader\RedrawColumn(i)
          Next
          
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow

Fader\Free()

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 6:40 am
by idle
works on linux if you change the height to 128 at line 122

Code: Select all

 fg_iCol = CreateImage(#PB_Any, 6, 128)
otherwise it fails at grabImage

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 6:45 am
by netmaestro
Thanks for the report, I made the change and it still works fine on Windows. Two out of three platforms so far.. :mrgreen:

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 7:19 am
by kvitaliy
Lunix ( Ubuntu)
Line 135 (!) temp = GrabImage(fg_iCol, #PB_Any, 0, 127-i, 6, i+1)
Line 140 Error

I corrected in line 135 this code (..., 127-i, ...) on this code (..., 126-i, ...). Compilation took place successfully.

P,S,
In Windows of such problem isn't present!

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 7:27 am
by netmaestro
Change made, hope it works as posted now :?

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 7:38 am
by idle
yes it's working fine ubuntu 12.04 x64

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 5:51 pm
by Joris
netmaestro wrote:2. Because the canvas gadget captures the mouse and 128 different canvas gadgets are used here, the left mousebutton can't be used to move the sliders. So, to move the sliders you hold a shift key down while moving the mouse on the sliders.
Glad I saw this. Thanks for your work netmaestro.
I tested it and it works also on XP SP3 32b (yeah, windows has many platforms...)
The need of a shift key is a bit sad... but there must be a workaround for that.

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 6:57 pm
by netmaestro
The need of a shift key is a bit sad... but there must be a workaround for that.
Yes. Danilo made the comment that instead of using 128 canvases, just use one canvas and keep the sliders stored as memory objects. He is right imho and that would solve it. I'll make the change.

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 9:36 pm
by Andre
It works on MacOS (10.5.8 used here), but it seems to have problems getting all events from the slider. If I move the the slider by mouse, not always the fader image is updated. Even sometimes clicking on the slider does not lead to an update of the fader image.

See the following screenshot (slider is moved to the highest value, but the fader image not...):
Image

Re: 128 Slider/Faders Include - Crossplatform

Posted: Tue Mar 05, 2013 10:13 pm
by marroh
Works fine on Win8 x64, thanks for share. :P

Re: 128 Slider/Faders Include - Crossplatform

Posted: Wed Mar 06, 2013 9:02 am
by Mindphazer
Works fine on OSX 10.8 (PB 5.11 Beta) - Nice job !
I don't have the issue described by Andre...

Re: 128 Slider/Faders Include Crossplatform - Redesigned

Posted: Thu Mar 07, 2013 1:50 pm
by netmaestro
Gadget is redesigned to allow mousebutton control instead of shift key.

Re: 128 Slider/Faders Include Crossplatform - Redesigned

Posted: Thu Mar 07, 2013 3:46 pm
by Joris
Works great, thanks again.
Too me, this is also nice material to study PB.

If deactivating this line (and Endif) :
If EventType() = #PB_EventType_MouseMove
or making it like this
If EventType() = #PB_EventType_MouseMove Or #PB_Canvas_LeftButton
You can set a fader also with a mouseclick instead of click+move. Then it act's 100% equal to what I had in GB32.

Re: 128 Slider/Faders Include Crossplatform - Redesigned

Posted: Thu Mar 07, 2013 4:56 pm
by netmaestro
Event testing is updated to include leftclick and you're right, it's quite useful. Now the only unanswered question is whether or not it's still working properly on Mac and Linux.

Re: 128 Slider/Faders Include Crossplatform - Redesigned

Posted: Thu Mar 07, 2013 8:50 pm
by idle
that's much better with the mouse works fine on ubuntu 12.04