Version 8.1

This commit is contained in:
2025-09-14 16:24:25 +02:00
parent 0f6640be83
commit 1558b452f4

View File

@@ -1,7 +1,7 @@
; ******************************************************************** ; ********************************************************************
; Program: Thumbnails ; Program: Thumbnails
; Description: add a Thumbnails to select image ; Description: add a Thumbnails to select image
; Version: 7 ; Version: 8.1
; Author: Thyphoon ; Author: Thyphoon
; Date: August, 2021 ; Date: August, 2021
; License: Free, unrestricted, credit ; License: Free, unrestricted, credit
@@ -121,7 +121,7 @@ DeclareModule Cache
EndStructure EndStructure
Global Param.Param Global Param.Param
Param\LoadListSemaphore=CreateSemaphore(16) Param\LoadListSemaphore=CreateSemaphore(1)
Param\LoadListMutex=CreateMutex() Param\LoadListMutex=CreateMutex()
Param\CacheListMutex=CreateMutex() Param\CacheListMutex=CreateMutex()
param\SignalMutex=CreateMutex() param\SignalMutex=CreateMutex()
@@ -146,12 +146,15 @@ Module Cache
Protected *Ptr Protected *Ptr
LockMutex(param\CacheListMutex) LockMutex(param\CacheListMutex)
*Ptr=AddMapElement(param\CacheList(),FilePath) *Ptr=AddMapElement(param\CacheList(),FilePath)
param\CacheList()\FilePath=FilePath param\CacheList()\FilePath=FilePath
param\CacheList()\State=0 param\CacheList()\State=0
UnlockMutex(param\CacheListMutex) UnlockMutex(param\CacheListMutex)
LockMutex(Param\LoadListMutex) LockMutex(Param\LoadListMutex)
LastElement(param\LoadList())
AddElement(param\LoadList()) AddElement(param\LoadList())
Debug "AddFileToLoadList:"+Str(ListIndex(param\LoadList()))
param\LoadList()=*Ptr param\LoadList()=*Ptr
UnlockMutex(Param\LoadListMutex) UnlockMutex(Param\LoadListMutex)
EndProcedure EndProcedure
@@ -206,10 +209,12 @@ Module Cache
Repeat Repeat
LockMutex(Param\LoadListMutex) LockMutex(Param\LoadListMutex)
;Select Data from Id ;Select Data from Id
If FirstElement(Param\LoadList())<>0 If LastElement(Param\LoadList())<>0
Debug "BackgroundThread:"+Str(ListIndex(param\LoadList()))
Protected *Ptr.core::FileData Protected *Ptr.core::FileData
*Ptr=Param\LoadList() *Ptr=Param\LoadList()
WaitSemaphore(Param\LoadListSemaphore) WaitSemaphore(Param\LoadListSemaphore)
Debug "LoadList index:"+Str(ListIndex(Param\LoadList()))+"/"+ListSize(Param\LoadList())
If CreateThread(@LoadCacheDataThread(),*Ptr)<>0 If CreateThread(@LoadCacheDataThread(),*Ptr)<>0
DeleteElement(Param\LoadList()) DeleteElement(Param\LoadList())
@@ -231,7 +236,7 @@ Module Cache
UnlockMutex(Param\QuitMutex) UnlockMutex(Param\QuitMutex)
Until ListSize(Param\LoadList())=0 Or Quit=#True Until ListSize(Param\LoadList())=0 Or Quit=#True
Delay(5) Delay(1)
Until Quit=#True Until Quit=#True
Debug "Bye Bye ! Cache::BackgroundThread()" Debug "Bye Bye ! Cache::BackgroundThread()"
EndProcedure EndProcedure
@@ -255,10 +260,8 @@ Module Cache
EndProcedure EndProcedure
Procedure Free(*Ptr.core::FileData) Procedure Free(*Ptr.core::FileData)
LockMutex(Param\CacheListMutex)
If IsImage(*Ptr\Image):FreeImage(*Ptr\Image):EndIf If IsImage(*Ptr\Image):FreeImage(*Ptr\Image):EndIf
FreeMap(*Ptr\MetaData()) FreeMap(*Ptr\MetaData())
UnlockMutex(Param\CacheListMutex)
EndProcedure EndProcedure
@@ -301,6 +304,8 @@ Module Cache
EndIf EndIf
UnlockMutex(Param\CacheListMutex) UnlockMutex(Param\CacheListMutex)
LockMutex(Param\LoadListMutex) LockMutex(Param\LoadListMutex)
Debug "ListSize:"+Str(ListSize(param\LoadList()))
FirstElement(param\LoadList())
AddElement(param\LoadList()) AddElement(param\LoadList())
Param\LoadList()=*Ptr Param\LoadList()=*Ptr
UnlockMutex(Param\LoadListMutex) UnlockMutex(Param\LoadListMutex)
@@ -336,8 +341,11 @@ Module Thumbs
Structure Gdt Structure Gdt
GadgetId.i ;Canvas Gadget number GadgetId.i ;Canvas Gadget number
BufferCanvasImage.i[1]
SelectedBufferCanvasImage.b
Size.l ;Thumb Size Width and Height Size.l ;Thumb Size Width and Height
Index.i ;ThumbIndex Index.i ;ThumbIndex
OldIndex.i ;Last Index to Clean
IndexMax.i ; -1 infinity else Maximum index to limit scroll IndexMax.i ; -1 infinity else Maximum index to limit scroll
NbH.l ;Number of horizontal thumbnails NbH.l ;Number of horizontal thumbnails
NbV.l ;Number of Vertical thumbnails NbV.l ;Number of Vertical thumbnails
@@ -359,15 +367,25 @@ Module Thumbs
_ThumbsHeight.l _ThumbsHeight.l
_MarginH.l _MarginH.l
_MarginV.l _MarginV.l
_TimeLineWidth.l
ThumbPointerlistMutex.i ThumbPointerlistMutex.i
Map ThumbPointerList.i() Map ThumbPointerList.i()
LoadFromIndexInitialized.b ;#True CallBack is Ok # Else not initialized (See SetCallBackLoadFromindex() ) LoadFromIndexInitialized.b ;#True CallBack is Ok # Else not initialized (See SetCallBackLoadFromindex() )
CallBackLoadFromIndex.CallBackLoadFromIndex CallBackLoadFromIndex.CallBackLoadFromIndex
CallBackUpdateThread.i
CallBackMutex.i
CallBackIndex.i
CallBackNbThumbs.l
CallBackNeedReload.b
DrawSemaphore.i
Quit.b Quit.b
ThreadDrawCanvasImage.i ThreadDrawCanvasImage.i
EndStructure EndStructure
@@ -379,6 +397,8 @@ Module Thumbs
Global param.param Global param.param
param\DrawAlphaImageMutex=CreateMutex() param\DrawAlphaImageMutex=CreateMutex()
Procedure InitGadgetValue(GadgetId.i) Procedure InitGadgetValue(GadgetId.i)
Protected *Gdt.Gdt Protected *Gdt.Gdt
*Gdt=GetGadgetData(GadgetId) *Gdt=GetGadgetData(GadgetId)
@@ -387,7 +407,8 @@ Module Thumbs
*Gdt\_Size=DesktopScaledX(*Gdt\Size) *Gdt\_Size=DesktopScaledX(*Gdt\Size)
*Gdt\_ScrollWidth=DesktopScaledX(25) *Gdt\_ScrollWidth=DesktopScaledX(25)
*Gdt\_ScrollHeight=*Gdt\_ScrollWidth*2 *Gdt\_ScrollHeight=*Gdt\_ScrollWidth*2
*Gdt\_ThumbsWidth.l=*Gdt\_GadgetWidth-*Gdt\_ScrollWidth *Gdt\_TimeLineWidth=DesktopScaledX(50)
*Gdt\_ThumbsWidth.l=*Gdt\_GadgetWidth-*Gdt\_ScrollWidth-*Gdt\_TimeLineWidth
*Gdt\_ThumbsHeight.l=*Gdt\_GadgetHeight *Gdt\_ThumbsHeight.l=*Gdt\_GadgetHeight
*Gdt\NbH.l=Int(*Gdt\_ThumbsWidth/*Gdt\_Size) *Gdt\NbH.l=Int(*Gdt\_ThumbsWidth/*Gdt\_Size)
*Gdt\NbV.l=Int(*Gdt\_GadgetHeight/*Gdt\_Size) *Gdt\NbV.l=Int(*Gdt\_GadgetHeight/*Gdt\_Size)
@@ -409,37 +430,74 @@ Module Thumbs
UnlockMutex(*Gdt\ThumbPointerlistMutex) UnlockMutex(*Gdt\ThumbPointerlistMutex)
EndProcedure EndProcedure
Procedure LoadFromIndex(GadgetId.i) Procedure UpdateIndexs(GadgetId.i)
Protected *Gdt.gdt Protected *Gdt.gdt
Protected *Ptr.core::FileData Protected *Ptr.core::FileData
Static counter.l
*Gdt=GetGadgetData(GadgetId) *Gdt=GetGadgetData(GadgetId)
If *Gdt\LoadFromIndexInitialized=#True If *Gdt\LoadFromIndexInitialized=#True
Debug "COUNTER="+Str(counter)
counter=counter+1
Protected Index.i=*Gdt\Index-*Gdt\Nbh Protected Index.i=*Gdt\Index-*Gdt\Nbh
Protected NThumbs.l=(*Gdt\NbV+2)**Gdt\Nbh ;Number of Thumbs must be Loaded Protected NThumbs.l=(*Gdt\NbV+2)**Gdt\Nbh ;Number of Thumbs must be Loaded
;-Clean index ;-Clean index
LockMutex(*Gdt\ThumbPointerlistMutex) LockMutex(*Gdt\ThumbPointerlistMutex)
ForEach *Gdt\ThumbPointerList() Protected.l DeltaIndex=Index-*Gdt\OldIndex
; *Ptr=*Gdt\ThumbPointerList() *Gdt\OldIndex=Index
; Protected Value.i=Val(MapKey(*Gdt\ThumbPointerList())) Protected n.l
; If *Ptr>0 And (Value<Index Or Value>Index+Nthumbs-1) For n=0 To Abs(DeltaIndex)
; If *Ptr\State=2:*Ptr\State=1:EndIf ;Image not Display If DeltaIndex>0
; Debug "Clean Map:"+Str(Value) If FindMapElement(*Gdt\ThumbPointerList(),Str(*Gdt\OldIndex+DeltaIndex))
; EndIf DeleteMapElement(*Gdt\ThumbPointerList())
; DeleteMapElement(*Gdt\ThumbPointerList()) EndIf
ElseIf DeltaIndex<0
If FindMapElement(*Gdt\ThumbPointerList(),Str(*Gdt\OldIndex+NThumbs-DeltaIndex))
DeleteMapElement(*Gdt\ThumbPointerList())
EndIf
EndIf
Next Next
UnlockMutex(*Gdt\ThumbPointerlistMutex) UnlockMutex(*Gdt\ThumbPointerlistMutex)
LockMutex(*Gdt\CallBackMutex)
*Gdt\CallBackIndex=Index+DeltaIndex
*Gdt\CallBackNbThumbs=NThumbs-DeltaIndex
*Gdt\CallBackNeedReload=#True
UnlockMutex(*Gdt\CallBackMutex)
EndIf
EndProcedure
Procedure UpdateImage2Index(GadgetId.i)
Protected Index.i,Thumbs.l
Protected NeedReload.b=#False
Protected *Gdt.gdt
*Gdt=GetGadgetData(GadgetId)
;-Load new File on Index ;-Load new File on Index
Repeat
LockMutex(*Gdt\CallBackMutex)
If *Gdt\CallBackNeedReload=#True
Index.i=*Gdt\CallBackIndex
Thumbs.l=*Gdt\CallBackNbThumbs
*Gdt\CallBackNeedReload=#False
NeedReload=#True
Else
NeedReload=#False
EndIf
UnlockMutex(*Gdt\CallBackMutex)
If *Gdt\CallBackLoadFromIndex>0 If NeedReload=#True
*Gdt\CallBackLoadFromIndex(*Gdt\GadgetId,Index,NThumbs) If *Gdt\CallBackLoadFromIndex>0
Debug "param\CallBackLoadFromIndex("+Str(Index)+","+Str(NThumbs)+")" *Gdt\CallBackLoadFromIndex(*Gdt\GadgetId,*Gdt\CallBackIndex,*Gdt\CallBackNbThumbs)
Else Debug "param\CallBackLoadFromIndex("+Str(*Gdt\CallBackIndex)+","+Str(*Gdt\CallBackNbThumbs)+")"
Delay(10) Else
Debug "No Set CallBackLoadFromIndex" Delay(10)
Debug "No Set CallBackLoadFromIndex"
EndIf
Cache::AutoLoadStart()
EndIf EndIf
Cache::AutoLoadStart() Delay(5)
EndIf ForEver
EndProcedure EndProcedure
Procedure LimitIndex(GadgetId.i,IndexMax.i=-1) Procedure LimitIndex(GadgetId.i,IndexMax.i=-1)
@@ -486,14 +544,14 @@ Module Thumbs
DeltaIndex=Int(*Gdt\ThumbsDeltaY/*Gdt\_Size)* *Gdt\NbH DeltaIndex=Int(*Gdt\ThumbsDeltaY/*Gdt\_Size)* *Gdt\NbH
*Gdt\Index=*Gdt\Index-DeltaIndex *Gdt\Index=*Gdt\Index-DeltaIndex
*Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY%*Gdt\_Size *Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY%*Gdt\_Size
CreateThread(@LoadFromIndex(),GadgetId) CreateThread(@UpdateIndexs(),GadgetId)
EndIf EndIf
If *Gdt\ThumbsDeltaY<=-*Gdt\_Size If *Gdt\ThumbsDeltaY<=-*Gdt\_Size
DeltaIndex=Abs(Int(*Gdt\ThumbsDeltaY/*Gdt\_Size)* *Gdt\NbH) DeltaIndex=Abs(Int(*Gdt\ThumbsDeltaY/*Gdt\_Size)* *Gdt\NbH)
*Gdt\Index=*Gdt\Index+DeltaIndex *Gdt\Index=*Gdt\Index+DeltaIndex
*Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY%*Gdt\_Size *Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY%*Gdt\_Size
CreateThread(@LoadFromIndex(),GadgetId) CreateThread(@UpdateIndexs(),GadgetId)
EndIf EndIf
;Limit Scroll ;Limit Scroll
@@ -515,9 +573,8 @@ Module Thumbs
Protected Selected.b Protected Selected.b
Protected FileName.s Protected FileName.s
;LockMutex(param\DrawAlphaImageMutex) ;LockMutex(param\DrawAlphaImageMutex)
Protected BufferImage.i If (Cache::GetSignalAndReset()=#True Or TrySemaphore(*Gdt\DrawSemaphore)) And StartVectorDrawing(CanvasVectorOutput(*Gdt\GadgetId))
BufferImage.i=CreateImage(#PB_Any,*Gdt\_GadgetWidth,*Gdt\_GadgetHeight) Debug"DRAW IMAGE"
If StartVectorDrawing(ImageVectorOutput(BufferImage))
VectorSourceColor(RGBA(128, 128, 128, 255)) VectorSourceColor(RGBA(128, 128, 128, 255))
FillVectorOutput() FillVectorOutput()
Protected ListIndex.l=-1 Protected ListIndex.l=-1
@@ -533,6 +590,8 @@ Module Thumbs
AddPathBox(x, y,*Gdt\_Size,*Gdt\_Size) AddPathBox(x, y,*Gdt\_Size,*Gdt\_Size)
VectorSourceColor(RGBA(100, 100, 100, 255)) VectorSourceColor(RGBA(100, 100, 100, 255))
SaveVectorState()
ClipPath(#PB_Path_Preserve)
FillPath() FillPath()
Selected=0 Selected=0
State=0 State=0
@@ -590,161 +649,31 @@ Module Thumbs
VectorSourceColor(RGBA(255, 255, 255, 255)) VectorSourceColor(RGBA(255, 255, 255, 255))
MovePathCursor(x+5,y+5) MovePathCursor(x+5,y+5)
DrawVectorText(Str(i)+" "+Filename) DrawVectorText(Str(i)+" "+Filename)
RestoreVectorState()
Next Next
Next Next
;ScrollBar ;ScrollBar
AddPathBox(*Gdt\_ThumbsWidth,0,*Gdt\_ScrollWidth,*Gdt\_GadgetHeight):VectorSourceColor(RGBA(100, 100, 100, 255)):FillPath() AddPathBox(*Gdt\_ThumbsWidth,0,*Gdt\_ScrollWidth,*Gdt\_GadgetHeight):VectorSourceColor(RGBA(100, 100, 100, 255)):FillPath()
AddPathBox(*Gdt\_ThumbsWidth,CursorY,*Gdt\_ScrollWidth,*Gdt\_ScrollHeight):VectorSourceColor(RGBA(200, 200, 200, 255)):FillPath() AddPathBox(*Gdt\_ThumbsWidth,CursorY,*Gdt\_ScrollWidth,*Gdt\_ScrollHeight):VectorSourceColor(RGBA(200, 200, 200, 255)):FillPath()
StopVectorDrawing() ;Timeline
;UnlockMutex(param\DrawAlphaImageMutex) If *Gdt\_TimeLineWidth>0
If StartVectorDrawing(CanvasVectorOutput(*Gdt\GadgetId)) Protected.l Date_Start=1921
MovePathCursor(0,0) Protected.l Date_End=2021
DrawVectorImage(ImageID(BufferImage)) Protected.l TH=VectorTextHeight("Ty")
StopVectorDrawing() Protected.l Nb=*Gdt\_GadgetHeight/(Date_End-Date_Start)
FreeImage(BufferImage) Protected.l z,zy=0
For z=0 To (Date_End-Date_Start)
zy=zy+TH
If zy>=TH*2
zy=0
VectorSourceColor(RGBA(255, 255, 255, 255))
Protected date.s=Str(Date_End-z)
MovePathCursor(*Gdt\_GadgetWidth-VectorTextWidth(Date),z*TH)
DrawVectorText(date)
EndIf
Next
EndIf EndIf
EndIf
Delay(50)
Until *Gdt\Quit=#True
Debug "DrawCanvasImage "+Str(*Gdt\GadgetId)+" Say Bye Bye !"
EndProcedure
Procedure DrawCanvasImage_old(GadgetId.i)
Protected *Gdt.gdt
Protected CursorY.l
*Gdt=GetGadgetData(GadgetId)
Repeat
If *Gdt\StartScroll=#True
*Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY+(*Gdt\CursorDeltaY/10)
EndIf
CursorY=*Gdt\_GadgetHeight/2-*Gdt\_ScrollHeight-*Gdt\CursorDeltaY
;Limit Cursor Up
If CursorY<0
CursorY=0
*Gdt\ThumbsDeltaY=*Gdt\_Size ;<-Fast Mode
EndIf
;Limit Cursor Down
If CursorY>*Gdt\_GadgetHeight-*Gdt\_ScrollHeight
CursorY=*Gdt\_GadgetHeight-*Gdt\_ScrollHeight
*Gdt\ThumbsDeltaY=-*Gdt\_Size ;<-Fast Mode
EndIf
Protected DeltaIndex.l
If *Gdt\ThumbsDeltaY>=*Gdt\_Size
DeltaIndex=Int(*Gdt\ThumbsDeltaY/*Gdt\_Size)* *Gdt\NbH
*Gdt\Index=*Gdt\Index-DeltaIndex
*Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY%*Gdt\_Size
CreateThread(@LoadFromIndex(),GadgetId)
EndIf
If *Gdt\ThumbsDeltaY<=-*Gdt\_Size
DeltaIndex=Abs(Int(*Gdt\ThumbsDeltaY/*Gdt\_Size)* *Gdt\NbH)
*Gdt\Index=*Gdt\Index+DeltaIndex
*Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY%*Gdt\_Size
CreateThread(@LoadFromIndex(),GadgetId)
EndIf
;Limit Scroll
If *Gdt\Index<=0
*Gdt\Index=0
If *Gdt\ThumbsDeltaY>0:*Gdt\ThumbsDeltaY=0:EndIf
EndIf
If *Gdt\IndexMax>-1
If *Gdt\Index>=*Gdt\IndexMax
*Gdt\Index=*Gdt\IndexMax
If *Gdt\ThumbsDeltaY<0:*Gdt\ThumbsDeltaY=0:EndIf
EndIf
EndIf
Protected *Ptr.core::FileData
Protected State.l
Protected Image.i
Protected Selected.b
Protected FileName.s
;LockMutex(param\DrawAlphaImageMutex)
If StartVectorDrawing(CanvasVectorOutput(*Gdt\GadgetId))
VectorSourceColor(RGBA(128, 128, 128, 255))
FillVectorOutput()
Protected ListIndex.l=-1
Protected.l nx,ny,x,y
Protected i.i
For ny=-1 To *Gdt\NbV+1
For nx=0 To *Gdt\NbH-1
ListIndex=ListIndex+1
;Position
x=nx * *Gdt\_Size+ *Gdt\_MarginH * nx + ( *Gdt\_MarginH )
y=ny * *Gdt\_Size+ *Gdt\_MarginV * ny + ( *Gdt\_MarginV ) + *Gdt\ThumbsDeltaY
i=nx+ny* *Gdt\NbH + *Gdt\Index
AddPathBox(x, y,*Gdt\_Size,*Gdt\_Size)
VectorSourceColor(RGBA(100, 100, 100, 255))
FillPath()
Selected=0
State=0
Image=-1
FileName=""
LockMutex(*Gdt\ThumbPointerlistMutex)
If FindMapElement(*Gdt\ThumbPointerList(),Str(i))
*Ptr=*Gdt\ThumbPointerList()
Else
*Ptr=0
EndIf
UnlockMutex(*Gdt\ThumbPointerlistMutex)
If *Ptr>0
If *Ptr\State>0 And IsImage(*Ptr\Image) ;If Image loaded
*Ptr\State=2 ; 0 No Loaded ; 1 loaded; 2 Displayed
State=2
Image.i=*Ptr\Image
Selected=*Ptr\Selected
FileName.s=GetFilePart(*Ptr\FilePath)
Protected result.ImgTools::DefDisplayImage
ImgTools::ImageToContainer(@result,Image,*Gdt\_Size,*Gdt\_Size,ImgTools::#Image_Style_Fit)
;If element selected display green
Protected _Border.l,_BorderX2.l
;Draw Green Border when selected
If Selected=1
AddPathBox(result\X+x, result\Y+y,result\Width,result\Height)
VectorSourceColor(RGBA(0, 255, 0, 255))
FillPath()
_Border=DesktopScaledX(2)
_BorderX2=_Border*2
Else
_Border=0
_BorderX2=0
EndIf
;Draw Image
AddPathBox(result\X+x+_Border, result\Y+y+_Border,result\Width-_BorderX2,result\Height-_BorderX2)
VectorSourceColor(RGBA(0, 0, 0, 255))
FillPath()
MovePathCursor(result\X+x+_Border,result\Y+y+_Border)
DrawVectorImage(ImageID(Image),255,result\Width-_BorderX2,result\Height-_BorderX2)
Else ;If Image no Loaded
;AddPathBox(result\X+x, result\Y+y,result\Width,result\Height)
;VectorSourceColor(RGBA(255, 255, 0, 255))
;FillPath()
EndIf
;If *Ptr=0 No Image
Else
;AddPathBox(result\X+x, result\Y+y,result\Width,result\Height)
;VectorSourceColor(RGBA(0, 255, 255, 128))
;FillPath()
EndIf
VectorSourceColor(RGBA(255, 255, 255, 255))
MovePathCursor(x+5,y+5)
DrawVectorText(Str(i)+" "+Filename)
Next
Next
;ScrollBar
AddPathBox(*Gdt\_ThumbsWidth,0,*Gdt\_ScrollWidth,*Gdt\_GadgetHeight):VectorSourceColor(RGBA(100, 100, 100, 255)):FillPath()
AddPathBox(*Gdt\_ThumbsWidth,CursorY,*Gdt\_ScrollWidth,*Gdt\_ScrollHeight):VectorSourceColor(RGBA(200, 200, 200, 255)):FillPath()
StopVectorDrawing() StopVectorDrawing()
;UnlockMutex(param\DrawAlphaImageMutex) ;UnlockMutex(param\DrawAlphaImageMutex)
EndIf EndIf
@@ -766,30 +695,36 @@ Module Thumbs
Case #PB_Shortcut_Down Case #PB_Shortcut_Down
If *Gdt\Index<*Gdt\IndexMax If *Gdt\Index<*Gdt\IndexMax
*Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY-DesktopScaledY(5) *Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY-DesktopScaledY(5)
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
EndIf EndIf
Case #PB_Shortcut_Up Case #PB_Shortcut_Up
If *Gdt\Index>0 If *Gdt\Index>0
*Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY+DesktopScaledY(5) *Gdt\ThumbsDeltaY=*Gdt\ThumbsDeltaY+DesktopScaledY(5)
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
EndIf EndIf
Case #PB_Shortcut_PageDown Case #PB_Shortcut_PageDown
If *Gdt\Index<*Gdt\IndexMax If *Gdt\Index<*Gdt\IndexMax
*Gdt\ThumbsDeltaY=0 *Gdt\ThumbsDeltaY=0
*Gdt\Index=*Gdt\Index+*Gdt\NbH *Gdt\Index=*Gdt\Index+*Gdt\NbH
CreateThread(@LoadFromIndex(),*Gdt\GadgetId) CreateThread(@UpdateIndexs(),*Gdt\GadgetId)
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
EndIf EndIf
Case #PB_Shortcut_PageUp Case #PB_Shortcut_PageUp
If *Gdt\Index>0 If *Gdt\Index>0
*Gdt\ThumbsDeltaY=0 *Gdt\ThumbsDeltaY=0
*Gdt\Index=*Gdt\Index-*Gdt\NbH *Gdt\Index=*Gdt\Index-*Gdt\NbH
CreateThread(@LoadFromIndex(),*Gdt\GadgetId) CreateThread(@UpdateIndexs(),*Gdt\GadgetId)
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
EndIf EndIf
EndSelect EndSelect
Case #PB_EventType_Resize Case #PB_EventType_Resize
InitGadgetValue(*Gdt\GadgetId) InitGadgetValue(*Gdt\GadgetId)
CreateThread(@LoadFromIndex(),*Gdt\GadgetId) CreateThread(@UpdateIndexs(),*Gdt\GadgetId)
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
Case #PB_EventType_LostFocus Case #PB_EventType_LostFocus
*Gdt\StartScroll=#False *Gdt\StartScroll=#False
*Gdt\CursorDeltaY=0 *Gdt\CursorDeltaY=0
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
Case #PB_EventType_MouseMove Case #PB_EventType_MouseMove
;Icon dans la zone ;Icon dans la zone
If Mx>*Gdt\_ThumbsWidth If Mx>*Gdt\_ThumbsWidth
@@ -800,7 +735,8 @@ Module Thumbs
If *Gdt\StartScroll=#True If *Gdt\StartScroll=#True
;If GetGadgetAttribute(*Gdt\GadgetId, #PB_Canvas_MouseY)<>0 ;PB Bug ? sometime return 0 ;If GetGadgetAttribute(*Gdt\GadgetId, #PB_Canvas_MouseY)<>0 ;PB Bug ? sometime return 0
*Gdt\CursorDeltaY=*Gdt\CursorStartY-GetGadgetAttribute(*Gdt\GadgetId, #PB_Canvas_MouseY) *Gdt\CursorDeltaY=*Gdt\CursorStartY-GetGadgetAttribute(*Gdt\GadgetId, #PB_Canvas_MouseY)
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
;EndIf ;EndIf
EndIf EndIf
@@ -808,7 +744,7 @@ Module Thumbs
;scroll Bar Event ;scroll Bar Event
If Mx>*Gdt\_ThumbsWidth If Mx>*Gdt\_ThumbsWidth
*Gdt\ZoneClick=1 ; You click in Scroll Zone *Gdt\ZoneClick=1 ; You click in Scroll Zone
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
If *Gdt\StartScroll=#False If *Gdt\StartScroll=#False
*Gdt\CursorStartY=My *Gdt\CursorStartY=My
*Gdt\StartScroll=#True *Gdt\StartScroll=#True
@@ -825,6 +761,7 @@ Module Thumbs
*Gdt\StartScroll=#False *Gdt\StartScroll=#False
*Gdt\CursorDeltaY=0 *Gdt\CursorDeltaY=0
Debug "Stop Scroll" Debug "Stop Scroll"
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
EndIf EndIf
;Thumbs ;Thumbs
@@ -837,17 +774,20 @@ Module Thumbs
Protected index.l=nx+ny**Gdt\NbH Protected index.l=nx+ny**Gdt\NbH
index=*Gdt\Index+index index=*Gdt\Index+index
LockMutex(*Gdt\ThumbPointerlistMutex) LockMutex(*Gdt\ThumbPointerlistMutex)
Debug FindMapElement(*Gdt\ThumbPointerList(),Str(index))
If FindMapElement(*Gdt\ThumbPointerList(),Str(index)) If FindMapElement(*Gdt\ThumbPointerList(),Str(index))
*Ptr=*Gdt\ThumbPointerList() *Ptr=*Gdt\ThumbPointerList()
If *Ptr>0 If *Ptr>0
*Ptr\Selected=1-*Ptr\Selected *Ptr\Selected=1-*Ptr\Selected
EndIf Debug "["+Str(index)+"] Selected="+Str(*Ptr\Selected)
EndIf
EndIf EndIf
UnlockMutex(*Gdt\ThumbPointerlistMutex) UnlockMutex(*Gdt\ThumbPointerlistMutex)
SignalSemaphore(*Gdt\DrawSemaphore) ; Redraw Image
EndIf EndIf
EndSelect EndSelect
EndProcedure EndProcedure
Procedure SetCallBackLoadFromIndex(GadgetId.i,CallBackLoadFromIndex.i) Procedure SetCallBackLoadFromIndex(GadgetId.i,CallBackLoadFromIndex.i)
If IsGadget(GadgetId) And GadgetType(GadgetId)=#PB_GadgetType_Canvas If IsGadget(GadgetId) And GadgetType(GadgetId)=#PB_GadgetType_Canvas
@@ -862,15 +802,18 @@ Module Thumbs
Procedure ThumbsGadget(GadgetId.i,X.l,Y.l,Width.l,Height.l,Size.l,CallBack.i=0) Procedure ThumbsGadget(GadgetId.i,X.l,Y.l,Width.l,Height.l,Size.l,CallBack.i=0)
Protected newGadgetId.i Protected newGadgetId.i
newGadgetId=CanvasGadget(GadgetId.i,X.l,Y.l,Width.l,Height.l,#PB_Canvas_Keyboard|#PB_Canvas_DrawFocus|#PB_Canvas_Border) newGadgetId=CanvasGadget(GadgetId.i,X.l,Y.l,Width.l,Height.l,#PB_Canvas_Keyboard|#PB_Canvas_Border) ; Note that the #PB_Canvas_DrawFocus actually involves a 2nd image to draw the focus rectangle and make flicker / black Flash
If GadgetId=#PB_Any If GadgetId=#PB_Any
GadgetId=newGadgetId GadgetId=newGadgetId
EndIf EndIf
Protected *Gdt.Gdt Protected *Gdt.Gdt
*Gdt=AddMapElement(param\Gdt(),Str(GadgetId)) *Gdt=AddMapElement(param\Gdt(),Str(GadgetId))
Debug *Gdt Debug *Gdt
If *Gdt If *Gdt
*Gdt\DrawSemaphore=CreateSemaphore(1)
*Gdt\CallBackMutex=CreateMutex()
*Gdt\ThumbPointerlistMutex=CreateMutex() *Gdt\ThumbPointerlistMutex=CreateMutex()
*Gdt\GadgetId=GadgetId *Gdt\GadgetId=GadgetId
*Gdt\Size=Size *Gdt\Size=Size
@@ -879,9 +822,9 @@ Module Thumbs
InitGadgetValue(GadgetId) InitGadgetValue(GadgetId)
If CallBack If CallBack
SetCallBackLoadFromIndex(GadgetId,CallBack) SetCallBackLoadFromIndex(GadgetId,CallBack)
CreateThread(@LoadFromIndex(),GadgetId) CreateThread(@UpdateIndexs(),GadgetId)
EndIf EndIf
;DrawCanvasImage(GadgetId) CreateThread(@UpdateImage2Index(),GadgetId)
*Gdt\ThreadDrawCanvasImage=CreateThread(@DrawCanvasImage(),GadgetId) *Gdt\ThreadDrawCanvasImage=CreateThread(@DrawCanvasImage(),GadgetId)
BindGadgetEvent(GadgetId,@ThumbsEvent(),#PB_All) BindGadgetEvent(GadgetId,@ThumbsEvent(),#PB_All)
Else Else
@@ -896,6 +839,8 @@ Module Thumbs
*Gdt\Quit=#True *Gdt\Quit=#True
WaitThread(*Gdt\ThreadDrawCanvasImage) WaitThread(*Gdt\ThreadDrawCanvasImage)
FreeMutex(*Gdt\ThumbPointerListMutex) FreeMutex(*Gdt\ThumbPointerListMutex)
FreeMutex(*Gdt\CallBackMutex)
FreeSemaphore(*Gdt\DrawSemaphore)
FreeMap(*Gdt\ThumbPointerList()) FreeMap(*Gdt\ThumbPointerList())
DeleteMapElement(param\Gdt(),Str(GadgetId)) DeleteMapElement(param\Gdt(),Str(GadgetId))
EndIf EndIf
@@ -930,34 +875,47 @@ Module Thumbs
*Ptr=*Gdt\ThumbPointerList() *Ptr=*Gdt\ThumbPointerList()
If *Ptr>0 If *Ptr>0
If *Ptr\State=2:*Ptr\State=1:EndIf ;Image not Display If *Ptr\State=2:*Ptr\State=1:EndIf ;Image not Display
DeleteMapElement(*Gdt\ThumbPointerList())
EndIf EndIf
DeleteMapElement(*Gdt\ThumbPointerList())
Next Next
UnlockMutex(*Gdt\ThumbPointerlistMutex) UnlockMutex(*Gdt\ThumbPointerlistMutex)
LoadFromIndex(GadgetId) CreateThread(@UpdateIndexs(),GadgetId)
EndProcedure EndProcedure
EndModule EndModule
;- TEST PART ;- TEST PART
CompilerIf #PB_Compiler_IsMainFile CompilerIf #PB_Compiler_IsMainFile
UseJPEGImageDecoder()
UsePNGImageDecoder() Enumeration
UseMD5Fingerprint() #Win_main
#Gdt_Nav
#Gdt_Folder
#Gdt_ThumbA
#Gdt_ThumbB
EndEnumeration
Global NewList CurrentList.s() Global NewList CurrentList.s()
Global CurrentListMutex.i
Procedure CallBackLoadFromIndexB(GadgetId.i,Index.i,Lenght.l) Procedure CallBackLoadFromIndexB(GadgetId.i,Index.i,Lenght.l)
Protected n.l Protected n.l
Protected TmpIndex.i Protected TmpIndex.i
Protected relativeIndex.l Protected relativeIndex.l
Protected *Ptr.Core::FileData
Debug "CallBackLoadFromIndexB("+Str(Index)+","+Str(Lenght)+")" Debug "CallBackLoadFromIndexB("+Str(Index)+","+Str(Lenght)+")"
LockMutex(CurrentListMutex)
For n=1 To Lenght For n=1 To Lenght
TmpIndex=Index+n-1 TmpIndex=Index+n-1
If TmpIndex>=0 And TmpIndex<ListSize(CurrentList()) If TmpIndex>=0 And TmpIndex<ListSize(CurrentList())
SelectElement(CurrentList(),TmpIndex) SelectElement(CurrentList(),TmpIndex)
relativeIndex=relativeIndex+1 relativeIndex=relativeIndex+1
Protected *Ptr.Core::FileData
*Ptr=Cache::GetFileDataFromCache(CurrentList()) *Ptr=Cache::GetFileDataFromCache(CurrentList())
If *Ptr If *Ptr
Thumbs::AddImageToThumb(GadgetId,TmpIndex,*Ptr) Thumbs::AddImageToThumb(GadgetId,TmpIndex,*Ptr)
@@ -969,43 +927,36 @@ CompilerIf #PB_Compiler_IsMainFile
EndIf EndIf
Next Next
Thumbs::LimitIndex(GadgetId,ListSize(CurrentList())) Thumbs::LimitIndex(GadgetId,ListSize(CurrentList()))
UnlockMutex(CurrentListMutex)
EndProcedure EndProcedure
Define Repertoire$ Define Repertoire$
Define Event.i Define Event.i
Repertoire$="G:\Documents\Photos\Photos a trier\2017-04-11 Photos a trier\"
Repertoire$=PathRequester("Chose Directory", Repertoire$)
If ExamineDirectory(0, Repertoire$, "*.jpg")
While NextDirectoryEntry(0)
If DirectoryEntryType(0) = #PB_DirectoryEntry_File
AddElement(CurrentList())
CurrentList()=Repertoire$+DirectoryEntryName(0)
EndIf
Wend
FinishDirectory(0)
EndIf
Enumeration
#Win_main UseJPEGImageDecoder()
#Gdt_Nav UsePNGImageDecoder()
#Gdt_Folder UseMD5Fingerprint()
#Gdt_ThumbA
#Gdt_ThumbB CurrentListMutex = CreateMutex()
EndEnumeration
If OpenWindow(#Win_main, 0, 0, 1024, 600, "Thumbnails", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget) If OpenWindow(#Win_main, 0, 0, 1024, 600, "Thumbnails", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
ButtonGadget(#Gdt_Folder,0,0,100,25,"Choose Folder") ButtonGadget(#Gdt_Folder,0,0,100,25,"Choose Folder")
Thumbs::ThumbsGadget(#Gdt_ThumbA,0,50,WindowWidth(#Win_main),WindowHeight(#Win_main)-50,128,@CallBackLoadFromIndexB()) Thumbs::ThumbsGadget(#Gdt_ThumbA,0,50,WindowWidth(#Win_main),WindowHeight(#Win_main)-50,128,@CallBackLoadFromIndexB())
Repeat Repeat
Delay(1)
Event = WaitWindowEvent() Event = WaitWindowEvent()
If Event=#PB_Event_Gadget If Event=#PB_Event_Gadget
If EventGadget()=#Gdt_Folder If EventGadget()=#Gdt_Folder
Repertoire$="G:\Documents\Photos\Photos a trier\2017-04-11 Photos a trier\" Repertoire$=PathRequester("Chose Directory", "G:\Documents\Photos\Photos a trier")
;Repertoire$=PathRequester("Chose Directory", Repertoire$) If Repertoire$ <> ""
If Repertoire$<>"" If ExamineDirectory(0, Repertoire$, "*.jpg")
ClearList(CurrentList())
If ExamineDirectory(0, Repertoire$, "*.jpg") LockMutex(CurrentListMutex)
ClearList(CurrentList())
While NextDirectoryEntry(0) While NextDirectoryEntry(0)
If DirectoryEntryType(0) = #PB_DirectoryEntry_File If DirectoryEntryType(0) = #PB_DirectoryEntry_File
AddElement(CurrentList()) AddElement(CurrentList())
@@ -1013,18 +964,23 @@ CompilerIf #PB_Compiler_IsMainFile
EndIf EndIf
Wend Wend
FinishDirectory(0) FinishDirectory(0)
UnlockMutex(CurrentListMutex)
Debug "LISTSIZE="+Str(ListSize(CurrentList())) Debug "LISTSIZE="+Str(ListSize(CurrentList()))
Thumbs::LimitIndex(#Gdt_ThumbA,ListSize(CurrentList())) Thumbs::LimitIndex(#Gdt_ThumbA, ListSize(CurrentList()))
Thumbs::ForceUpdate(#Gdt_ThumbA) Thumbs::ForceUpdate(#Gdt_ThumbA)
EndIf EndIf
EndIf EndIf
EndIf EndIf
EndIf
If Event=#PB_Event_SizeWindow
Debug "coucou"
ResizeGadget(#Gdt_ThumbA,0,50,WindowWidth(#Win_main),WindowHeight(#Win_main)-50)
EndIf EndIf
If Event=#PB_Event_SizeWindow
Debug "coucou"
ResizeGadget(#Gdt_ThumbA,0,50,WindowWidth(#Win_main),WindowHeight(#Win_main)-50)
EndIf
Until Event = #PB_Event_CloseWindow Until Event = #PB_Event_CloseWindow
Thumbs::FreeThumbsGadget(#Gdt_ThumbA) Thumbs::FreeThumbsGadget(#Gdt_ThumbA)
EndIf EndIf