I found this nice piece of code to display a CloverFlow (viewtopic.php?f=13&t=45835 and converted it into a UserGadget. It generally works, but needs to be beautified.
Suggestions for enhancements:
- improved aligment (width/spacing)
- smooth scrolling
- reduction of flickering
- dynamical adding of entries
- highlightning of selected item
...
Note:
You need the include file from http://www.purebasic.fr/german/viewtopi ... =8&t=26471
Oliver
Code: Select all
; CoverFlowGadget
; Cover flow written by Michael Vogel
; ---------------------------------------------
; done...
; + configurable sizes, background color etc.
; + cursor keys to scroll left and right
; to do...
; – faster scrolling with shift ???
; – mouse drag and drop?
; – fast (!) shadow effects?
; http://forums.purebasic.com/english/viewtopic.php?f=13&t=45835
XIncludeFile "EM_EventManager.pbi"
; http://www.purebasic.fr/german/viewtopic.php?f=8&t=26471
Enumeration
#ShelfLeft
#ShelfRight
#ShelfQuit
#Cover
#CoverImage
#CoverImageTemp
#CoverImagePool=200
EndEnumeration
#LovelyBird=$0A9C5E
#MaxCoverImages=30
#ShelfColor=#White
#ShelfSize=12; Anzahl der Covers in einer Zeile (äußerste nicht sichtbar)
#ShelfPhase=5; Anzahl der Phasen beim Durchblättern
#ShelfSpace=6; Pixel zwischen Thumbnails
#ShelfMin=128; Verkleinerung in Relation zum zentralen Cover (256)
#ShelfVert=150; Vertikaler Versatz (0..256)
#ShelfWave=4; Sinuswellenbreite
#ShelfMid=#ShelfSize>>1
#FontSize=20
Structure tCoverSizeType
rx.i
ry.i
ox.i
oy.i
EndStructure
Structure tCoverFlowGadget
id.i
canvas.i
buttonleft.i
buttonright.i
MaxCoverImages.i;=30
ShelfColor.i;=White
ShelfSize.i;=12; Anzahl der Covers in einer Zeile (äußerste nicht sichtbar)
ShelfPhase.i;=5; Anzahl der Phasen beim Durchblättern
ShelfSpace.i;=6; Pixel zwischen Thumbnails
ShelfMin.i;=128; Verkleinerung in Relation zum zentralen Cover (256)
ShelfVert.i;=150; Vertikaler Versatz (0..256)
ShelfWave.i;=4; Sinuswellenbreite
ShelfMid.i;=ShelfSize>>1
FontSize.i;=20
thumbsizeX.i
thumbsizeY.i
ShelfX.i
ShelfY.i
CacheImage.i
x.i
y.i
w.i
h.i
CoverImage.i
Map CoverImagePool.i()
Array CoverSize.tCoverSizeType(0,0)
iCurrentShelf.i
EndStructure
Procedure.i CoverFlowGadget_Phaser(min,max,phase)
ProcedureReturn min+(max-min)*phase/(#ShelfPhase+1)
EndProcedure
Procedure CoverFlowGadget_ShelfCalc(id)
If IsGadget(id)
Protected *CoverFlowObject .tCoverFlowGadget = GetGadgetData (id)
If Not *CoverFlowObject
ProcedureReturn
EndIf
EndIf
With *CoverFlowObject
; Calculate Cover Sizes and Offsets...
n=0
p=0
m=\ShelfSize>>1
For i=0 To \ShelfSize
z=m-i
If z<0
z=-z
EndIf
If z>\ShelfWave
f=\ShelfMin
Else
f=256-(256-\ShelfMin)*Sin(#PI*z/\ShelfWave/2)
EndIf
\CoverSize(i,0)\rx=21+(\ThumbSizeX*f)>>8
\CoverSize(i,0)\ry=(\ThumbSizeY*f)>>8
\CoverSize(i,0)\oy=\ShelfSpace+\ThumbSizeY-(\CoverSize(i,0)\ry*\ShelfVert+\ThumbSizeY*(256-\ShelfVert))>>8
If i=0
\CoverSize(i,0)\ox=-(\ThumbSizeX*\ShelfMin)>>8
Else
\CoverSize(i,0)\ox=\CoverSize(i-1,0)\ox+\CoverSize(i-1,0)\rx+\ShelfSpace
EndIf
Next i
; Calculate Values for Phases...
For i=0 To \ShelfSize-1
rxmin=\CoverSize(i,0)\rx
rxmax=\CoverSize(i+1,0)\rx
rymin=\CoverSize(i,0)\ry
rymax=\CoverSize(i+1,0)\ry
oxmin=\CoverSize(i,0)\ox
oxmax=\CoverSize(i+1,0)\ox
oymin=\CoverSize(i,0)\oy
oymax=\CoverSize(i+1,0)\oy
For p=1 To \ShelfPhase
\CoverSize(i,p)\rx=CoverFlowGadget_Phaser(rxmin,rxmax,p)
\CoverSize(i,p)\ry=CoverFlowGadget_Phaser(rymin,rymax,p)
\CoverSize(i,p)\ox=CoverFlowGadget_Phaser(oxmin,oxmax,p)
\CoverSize(i,p)\oy=CoverFlowGadget_Phaser(oymin,oymax,p)
Next p
Next i
\ShelfX=\w-42;\CoverSize(\ShelfSize,0)\ox
\ShelfY=\ShelfSpace*4+\ThumbSizeY+\FontSize
SetGadgetData (id, *CoverFlowObject)
EndWith
EndProcedure
Procedure CoverFlowGadget_GetCurrentShelf(id)
If IsGadget(id)
Protected *CoverFlowObject .tCoverFlowGadget = GetGadgetData (id)
If Not *CoverFlowObject
ProcedureReturn
EndIf
EndIf
ProcedureReturn *CoverFlowObject\iCurrentShelf
EndProcedure
Procedure CoverFlowGadget_CreateImages(id, iNum)
If IsGadget(id)
Protected *CoverFlowObject .tCoverFlowGadget = GetGadgetData (id)
If Not *CoverFlowObject
ProcedureReturn
EndIf
EndIf
With *CoverFlowObject
; Create Cover Images...
While NextMapElement(\CoverImagePool())
If IsImage(\CoverImagePool())
FreeImage(\CoverImagePool())
EndIf
Wend
ClearMap (\coverimagePool())
For i=0 To iNum
\CoverImagePool(Str(i))=CreateImage(#PB_Any,\ThumbSizeX,\ThumbSizeY)
StartDrawing(ImageOutput(\CoverImagePool(Str(i))))
Box(0,0,\ThumbSizeX,\ThumbSizeY,#LovelyBird)
Circle(Random(\ThumbSizeX),Random(\ThumbSizeY),Random(\ThumbSizeY),Random($FFFFFF))
DrawingMode(#PB_2DDrawing_Outlined)
Box(0,0,\ThumbSizeX,\ThumbSizeY,#White-#ShelfColor)
s.s="#"+Str(i)
DrawText((\ThumbSizeX-TextWidth(s))>>1,(\ThumbSizeY-TextHeight(s))>>1,s,#LovelyBird)
StopDrawing()
Next i
EndWith
SetGadgetData (id, *CoverFlowObject)
EndProcedure
Procedure CoverFlowGadget_ShelfShow(id,nShow,p=0)
If IsGadget(id)
Protected *CoverFlowObject .tCoverFlowGadget = GetGadgetData (id)
If Not *CoverFlowObject
ProcedureReturn
EndIf
EndIf
With *CoverFlowObject
Protected i,NewID
Protected mode,n
Protected s.s
If nShow<0: nShow=0:EndIf
If nShow>MapSize(\CoverImagePool())-1: nShow=MapSize(\CoverImagePool())-1:EndIf
n=nShow
; Show Covers...
StartDrawing(ImageOutput(\CacheImage))
Box(0,0,\ShelfX,\ShelfY,\ShelfColor)
; DrawingFont(ShelfFont)
i=n
If p>\ShelfPhase>>1
i-1
EndIf
s="Image #"+Str(i)
i=TextWidth(s)
DrawText((\ShelfX-i)>>1,\ShelfSpace<<1+\ThumbSizeY,s,$c0c0c0,\ShelfColor)
If p
mode=#PB_Image_Raw
Else
mode=#PB_Image_Smooth
EndIf
n-\ShelfMid
For i=0 To \ShelfSize-1
If n+i>=0 And n+i<=MapSize(\CoverImagePool())-1
CopyImage(\CoverImagePool(Str(n+i)),#CoverImageTemp)
newID=ResizeImage(#CoverImageTemp,\CoverSize(i,p)\rx,\CoverSize(i,p)\ry,mode)
DrawImage(NewID,\CoverSize(i,p)\ox,\CoverSize(i,p)\oy)
EndIf
Next i
StopDrawing()
; SetGadgetState(\CoverImage,\CacheImage)
StartDrawing(CanvasOutput(\canvas))
DrawImage(ImageID(\CacheImage),0,0)
StopDrawing()
FreeImage(#CoverImageTemp)
\iCurrentShelf=nShow
SetGadgetData(id,*CoverFlowObject)
EndWith
EndProcedure
Procedure CoverFlowGadget_ButtonClick(*ev.EM_Events)
Protected id=GetGadgetData(*ev\eventgadget)
If IsGadget(id)
Protected *CoverFlowObject .tCoverFlowGadget = GetGadgetData (id)
If Not *CoverFlowObject
ProcedureReturn
EndIf
EndIf
With *CoverFlowObject
Protected iCurrentShelf=\iCurrentShelf
If GetGadgetText(*ev\eventgadget)="<"
iCurrentShelf-1
Else
iCurrentShelf+1
EndIf
EndWith
For pp=1 To *CoverFlowObject\ShelfPhase
CoverFlowGadget_ShelfShow(id,iCurrentShelf,pp)
;WaitWindowEvent(1)
Next pp
CoverFlowGadget_ShelfShow(id,iCurrentShelf)
EndProcedure
Procedure CoverFlowGadget(id.i, x.i, y.i, width.i, height.i, ThumbnailX=120, ThumbnailY=120)
Protected *GadgetObject.tCoverFlowGadget = AllocateMemory ( SizeOf ( tCoverFlowGadget) )
If id = #PB_Any
id = ContainerGadget(#PB_Any, x, y, width, height)
Else
ContainerGadget(id, x, y, width, height)
EndIf
With *GadgetObject
\thumbsizeX=ThumbnailX
\thumbsizeY=ThumbnailY
\id=id
\canvas=CanvasGadget(#PB_Any,21,0,width-42,\thumbsizeY+12)
\buttonleft=ButtonGadget(#PB_Any,0,0,20,\thumbsizeY+12,"<")
SetGadgetData(\buttonleft,id)
\buttonright=ButtonGadget(#PB_Any,width-20,0,20,\thumbsizeY+12,">")
SetGadgetData(\buttonright,id)
CloseGadgetList()
\MaxCoverImages.i=30
EM_Seteventhandler(\buttonleft,#EM_Gadget,@CoverFlowGadget_ButtonClick())
EM_Seteventhandler(\buttonright,#EM_Gadget,@CoverFlowGadget_ButtonClick())
\ShelfColor=$FFFFFF;White
\ShelfSize=(width-42)/\thumbsizeX; Anzahl der Covers in einer Zeile (äußerste nicht sichtbar)
\ShelfPhase=20; Anzahl der Phasen beim Durchblättern
\ShelfSpace=6; Pixel zwischen Thumbnails
\ShelfMin=128; Verkleinerung in Relation zum zentralen Cover (256)
\ShelfVert=150; Vertikaler Versatz (0..256)
\ShelfWave=4; Sinuswellenbreite
\ShelfMid=\ShelfSize>>1
\FontSize=20
\x=x
\y=y
\w=width
\h=height
NewMap \CoverImagePool()
Dim \CoverSize(\ShelfSize,\ShelfPhase)
SetGadgetData (id , *GadgetObject )
EndWith
CoverFlowGadget_ShelfCalc(id)
*GadgetObject =GetGadgetData(id)
With *GadgetObject
\CacheImage=CreateImage(#PB_Any,\ShelfX,\ShelfY)
EndWith
SetGadgetData (id , *GadgetObject )
CoverFlowGadget_CreateImages(id,*GadgetObject\ShelfPhase )
ProcedureReturn id
EndProcedure
Procedure IsCoverFlowGadget (id)
If IsGadget(id)
Protected *CoverFlowObject .tCoverFlowGadget = GetGadgetData (id)
If Not *CoverFlowObject
ProcedureReturn
EndIf
Else
ProcedureReturn
EndIf
ProcedureReturn #True
EndProcedure
Macro DoEvent()
Repeat : WaitWindowEvent() : ForEver
EndMacro
CompilerIf #PB_Compiler_IsIncludeFile=0
Procedure Event_CloseWindow()
End
EndProcedure
Procedure Test()
; Open Window...
OpenWindow(#Cover,0,0,1000,200,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
; AddKeyboardShortcut(#Cover,#PB_Shortcut_Right,#ShelfRight)
; AddKeyboardShortcut(#Cover,#PB_Shortcut_Left,#ShelfLeft)
; AddKeyboardShortcut(#Cover,#PB_Shortcut_Escape,#ShelfQuit)
EM_SetEventHandler(#PB_Event_CloseWindow, #EM_Special, @Event_CloseWindow())
id=CoverFlowGadget(#PB_Any,0,0,1000,200,120,180)
CoverFlowGadget_ShelfShow(id,6)
doevent()
EndProcedure
Test()
CompilerEndIf