B4A=true Group=Default Group ModulesStructureVersion=1 Type=Class Version=7.01 @EndOfDesignText@ Sub Class_Globals ' Public Public SV2D As ScrollView2D Public BorderColor As Int Public BorderSize As Int Public ForceColorReduction As Boolean Public MinTiltAngle As Int Public MaxTiltAngle As Int Public AlternateAngle As Boolean Public HorizontalOffset As Int Public VerticalOffset As Int Public PressedDrawable As Object Public RescaleOnlyIfBigger As Boolean Public LabelHeightInGrid As Int Public SizeInGrid As Int Public SizeInPile As Int Public SpaceBetweenThumbnails As Int Public StillVisible As Int Public MarginLeft As Int Public MarginTop As Int ' Private Private gStyle As Int Private gPreviousAngle As Int Private gCB As Object Private sub_Touch As String Private sub_Click As String Private sub_LongClick As String Private sub_Scroll As String Private gThumbnailList As List Private BmpPlus As BitmapPlus Private NewBmp As Bitmap Private C As Canvas Private gStartX, gStartY As Int Private gPressedPanel As Panel Private OldBackground As Object Private OldLeft, OldTop As Int ' Constants Private STYLE_ROW_SQUARED As Int: STYLE_ROW_SQUARED = 0 Private STYLE_ROW_RESCALED As Int: STYLE_ROW_RESCALED = 1 Private STYLE_HORZGRID_SQUARED As Int: STYLE_HORZGRID_SQUARED = 2 Private STYLE_HORZGRID_RESCALED As Int: STYLE_HORZGRID_RESCALED = 3 Private STYLE_COLUMN_SQUARED As Int: STYLE_COLUMN_SQUARED = 4 Private STYLE_COLUMN_RESCALED As Int: STYLE_COLUMN_RESCALED = 5 Private STYLE_VERTGRID_SQUARED As Int: STYLE_VERTGRID_SQUARED = 6 Private STYLE_VERTGRID_RESCALED As Int: STYLE_VERTGRID_RESCALED = 7 Private STYLE_PILE_WITH_DRAG As Int: STYLE_PILE_WITH_DRAG = 8 ' Type Type typCoord(Left As Int, Top As Int) Private BitmapCheckbox As Bitmap End Sub 'Initializes the gallery. 'Parent = activity or panel holding the gallery 'GalleryStyle: ' 0 = scrolling row with squared thumbnails ' 1 = scrolling row with rescaled thumbnails (thumbnails can be tilted) ' 2 = horizontal scrolling grid with squared thumbnails ' 3 = horizontal scrolling grid with rescaled thumbnails (thumbnails can be tilted) ' 4 = scrolling column with squared thumbnails ' 5 = scrolling column with rescaled thumbnails (thumbnails can be tilted) ' 6 = vertical scrolling grid with squared thumbnails ' 7 = vertical scrolling grid with rescaled thumbnails (thumbnails can be tilted) ' 8 = pile of thumbnails (thumbnails can be dragged out of the pile) 'Callback = Me 'subTouch = name of the sub handling touch events. Returns (Thumbnail As Panel, Action As Int) 'subClick = name of the sub handling click events. Returns (Thumbnail As Panel) 'subLongClick = name of the sub handling long click events. Returns (Thumbnail As Panel) 'subScroll = name of the Sub handling scroll change events. Returns (PosX As Int, PosY As Int) Public Sub Initialize(Parent As Panel, Left As Int, Top As Int, Width As Int, Height As Int, GalleryStyle As Int, _ Callback As Object, subTouch As String, subClick As String, subLongClick As String, subScroll As String) Dim pnl As Panel pnl = Parent If Not(pnl.IsInitialized) Then Log("'Parent' must be the current activity or an initialized panel") Return End If SV2D.Initialize(0, 0, "SV2D") pnl.AddView(SV2D, Left, Top, Width, Height) BitmapCheckbox = LoadBitmap(File.DirAssets,"checkbox.png") SV2D.Color = Colors.Transparent BorderColor = Colors.White BorderSize = 0 ForceColorReduction = False MinTiltAngle = 0 MaxTiltAngle = 0 gPreviousAngle = 0 AlternateAngle = False HorizontalOffset = 0 VerticalOffset = 0 RescaleOnlyIfBigger = False LabelHeightInGrid = 0 SizeInGrid = 80dip SizeInPile = 100dip SpaceBetweenThumbnails = 0 StillVisible = 50dip gThumbnailList.Initialize gPressedPanel = Null PressedDrawable = LoadDrawable("frame_gallery_thumb_pressed") gStyle = GalleryStyle If gStyle <= STYLE_HORZGRID_RESCALED Then 'Horizontal scrollview SV2D.Panel.Height = Height Else If gStyle <= STYLE_VERTGRID_RESCALED Then 'Vertical scrollview SV2D.Panel.Width = Width Else 'Scrollview2D SV2D.Panel.Width = Width SV2D.Panel.Height = Height End If gCB = Callback sub_Touch = subTouch sub_Click = subClick sub_LongClick = subLongClick sub_Scroll = subScroll End Sub ' Clears the gallery Public Sub ClearGallery gThumbnailList.Clear For i = SV2D.Panel.NumberOfViews - 1 To 0 Step - 1 Dim v As View v = SV2D.Panel.GetView(i) v.RemoveView Next If gStyle <= STYLE_HORZGRID_RESCALED Then SV2D.Panel.Width = 0 Else If gStyle <= STYLE_VERTGRID_RESCALED Then SV2D.Panel.Height = 0 End If End Sub #Region Bitmap processing ' Crops the given bitmap to remove its colored borders (or transparent borders if Color = Colors.Transparent) Public Sub RemoveColoredBorders(bmpToCrop As Bitmap, Color As Int) As Bitmap Dim Pixels(bmpToCrop.Width) As Int Dim Done As Boolean Dim Top, Bottom, MaxLeft, Left, Right As Int For Row = 0 To bmpToCrop.Height - 1 BmpPlus.getPixels(bmpToCrop, Pixels, 0, bmpToCrop.Width, 0, Row, bmpToCrop.Width, 1) For i = 0 To Pixels.Length - 1 If Pixels(i) <> Color Then Top = Row MaxLeft = i Done = True Exit End If Next If Done Then Exit Next Done = False Bottom = bmpToCrop.Height - 1 For Row = Bottom To Top + 1 Step - 1 BmpPlus.getPixels(bmpToCrop, Pixels, 0, bmpToCrop.Width, 0, Row, bmpToCrop.Width, 1) For i = 0 To Pixels.Length - 1 If Pixels(i) <> Color Then Bottom = Row MaxLeft = Min(i, MaxLeft) Done = True Exit End If Next If Done Then Exit Next Left = MaxLeft Right = MaxLeft For Row = Top + 1 To Bottom - 1 BmpPlus.getPixels(bmpToCrop, Pixels, 0, bmpToCrop.Width, 0, Row, bmpToCrop.Width, 1) For i = 0 To Left - 1 If Pixels(i) <> Color Then Left = i Exit End If Next For i = Pixels.Length - 1 To Right + 1 Step - 1 If Pixels(i) <> Color Then Right = i Exit End If Next Next Return BmpPlus.Crop(bmpToCrop, Left, Top, Right - Left + 1, Bottom - Top + 1) End Sub Private Sub MakeItNice(bmp As Bitmap) As Bitmap Try ' Draws the bitmap with the new dimensions and adds a colored frame NewBmp.InitializeMutable(bmp.Width + (BorderSize * 2), bmp.Height + (BorderSize * 2)) C.Initialize2(NewBmp) C.DrawColor(Colors.Transparent) Dim DestRect As Rect DestRect.Initialize(BorderSize, BorderSize, NewBmp.Width - BorderSize, NewBmp.Height - BorderSize) C.DrawBitmap(bmp, Null, DestRect) If BorderSize > 0 Then Dim DemiBord As Int DemiBord = Floor(BorderSize / 2) + 1dip DestRect.Initialize(DemiBord, DemiBord, NewBmp.Width - DemiBord, NewBmp.Height - DemiBord) C.DrawRect(DestRect, BorderColor, False, BorderSize) End If Return NewBmp Catch '出错了就返回原图 Return bmp End Try End Sub Private Sub SquareBmp(bmp As Bitmap, FixedDimension As Int) As Bitmap FixedDimension = FixedDimension - (BorderSize * 2) If bmp.Width > bmp.Height Then bmp = BmpPlus.CreateScaledBitmap(bmp, Round(FixedDimension / bmp.Height * bmp.Width), FixedDimension, True) Else bmp = BmpPlus.CreateScaledBitmap(bmp, FixedDimension, Round(FixedDimension * bmp.Height / bmp.Width), True) End If Dim BmpTop, BmpLeft As Int BmpLeft = Round((FixedDimension - bmp.Width) / 2) BmpTop = Round((FixedDimension - bmp.Height) / 2) Return MakeItNice(BmpPlus.Crop(bmp, Abs(BmpLeft), Abs(BmpTop), FixedDimension, FixedDimension)) End Sub Private Sub RescaleBmp(bmp As Bitmap, FixedDimension As Int) As Bitmap Try Dim TotalBorderSize, NewDimension As Int TotalBorderSize = BorderSize * 2 NewDimension = FixedDimension - TotalBorderSize If Not(RescaleOnlyIfBigger) Or bmp.Width > NewDimension Or bmp.Height > NewDimension Then If bmp.Width > bmp.Height Then bmp = BmpPlus.CreateScaledBitmap(bmp, NewDimension, _ Round(FixedDimension * bmp.Height / bmp.Width) - TotalBorderSize, True) Else bmp = BmpPlus.CreateScaledBitmap(bmp, Round(FixedDimension / bmp.Height * bmp.Width) - TotalBorderSize, _ NewDimension, True) End If End If Return MakeItNice(bmp) Catch '出错了就返回原图 Return bmp End Try End Sub Private Sub RotateBmp(bmp As Bitmap, FixedDimension As Int) As Bitmap ' Using the Pythagoras theorem, we calculate the maximum size after a rotation (the diagonal) ' This size becomes the new bitmap size (+ a margin for the colored border) Dim Diagonale, Scale As Double Diagonale = Sqrt(Power(bmp.Width, 2) + Power(bmp.Height, 2)) If bmp.Width > bmp.Height Then Scale = bmp.Width / Diagonale Else Scale = bmp.Height / Diagonale End If Dim TotalBorderSize As Int TotalBorderSize = BorderSize * 2 - 1dip If bmp.Width > bmp.Height Then bmp = BmpPlus.CreateScaledBitmap(bmp, Round(FixedDimension * Scale) - TotalBorderSize, _ Round(FixedDimension * bmp.Height / bmp.Width * Scale) - TotalBorderSize, True) Else bmp = BmpPlus.CreateScaledBitmap(bmp, Round(FixedDimension / bmp.Height * bmp.Width * Scale) - TotalBorderSize, _ Round(FixedDimension * Scale) - TotalBorderSize, True) End If bmp = MakeItNice(bmp) Dim Angle As Int If AlternateAngle And MinTiltAngle <= 0 And MaxTiltAngle > 0 Then If gPreviousAngle > 0 Then Angle = Rnd(MinTiltAngle, 1) Else Angle = Rnd(1, MaxTiltAngle + 1) End If Else If MinTiltAngle <= MaxTiltAngle Then Angle = Rnd(MinTiltAngle, MaxTiltAngle + 1) Else Log("Invalid angles (MinTiltAngle must be <= MaxTiltAngle)") End If bmp = BmpPlus.Rotate(bmp, bmp.Width, bmp.Height, Angle, True) gPreviousAngle = Angle Return bmp End Sub #End Region ' Gets the number of thumbnails Public Sub NumberOfThumbnails As Int Return SV2D.Panel.NumberOfViews End Sub #Region Left, Top, Width, Height Private Sub CalcLeft(Left As Int) As Int Left = Max(StillVisible - getWidth, Min(Left + HorizontalOffset, getWidth - StillVisible)) Return Left End Sub Private Sub CalcTop(Top As Int) As Int Top = Max(StillVisible - getHeight, Min(Top + VerticalOffset, getHeight - StillVisible)) Return Top End Sub ' Gets the inner panel width Private Sub getWidth As Int If SV2D.Panel.Width < 0 Then Dim r As Reflector, Largeur As Int r.Target = SV2D.Panel Largeur = r.RunMethod("getWidth") If Largeur = 0 Then DoEvents Largeur = r.RunMethod("getWidth") End If Return Largeur Else Return SV2D.Panel.Width End If End Sub ' Gets the inner panel height Private Sub getHeight As Int If SV2D.Panel.Height < 0 Then Dim r As Reflector, Hauteur As Int r.Target = SV2D.Panel Hauteur = r.RunMethod("getHeight") If Hauteur = 0 Then DoEvents Hauteur = r.RunMethod("getHeight") End If Return Hauteur Else Return SV2D.Panel.Height End If End Sub #End Region #Region Grid Private Sub CalcLeftTopInGrid(Position As Int, Horizontal As Boolean) As typCoord ' Computes the coordinates of the LeftTop corner for the given position Dim NbRows, NbCols, CellSize As Int Dim Coord As typCoord If Horizontal Then Dim TotalHeight As Int TotalHeight = SizeInGrid + LabelHeightInGrid NbRows = 1 Do While TotalHeight + SpaceBetweenThumbnails + SizeInGrid + LabelHeightInGrid < getHeight NbRows = NbRows + 1 TotalHeight = TotalHeight + SpaceBetweenThumbnails + SizeInGrid + LabelHeightInGrid Loop ' Position = -1: Add / Position > -1: Insert If Position = -1 Then Position = SV2D.Panel.NumberOfViews NbCols = Floor(Position / NbRows) CellSize = SizeInGrid + SpaceBetweenThumbnails Coord.Left = NbCols * CellSize Coord.Top = (Position Mod NbRows) * (CellSize + LabelHeightInGrid) Else Dim TotalWidth As Int TotalWidth = SizeInGrid NbCols = 1 Do While TotalWidth + SpaceBetweenThumbnails + SizeInGrid < getWidth NbCols = NbCols + 1 TotalWidth = TotalWidth + SpaceBetweenThumbnails + SizeInGrid Loop ' Position = -1: Add / Position > -1: Insert If Position = -1 Then Position = SV2D.Panel.NumberOfViews NbRows = Floor(Position / NbCols) CellSize = SizeInGrid + SpaceBetweenThumbnails Coord.Left = (Position Mod NbCols) * CellSize + MarginLeft Coord.Top = NbRows * (CellSize + LabelHeightInGrid) + MarginTop End If Return Coord End Sub Private Sub PlaceInHorzGrid(Width As Int, Height As Int, Position As Int) As typCoord ' Computes the thumbnail coordinates in a horizontal grid ' and increases the SV panel width if needed Dim Coord As typCoord Coord = CalcLeftTopInGrid(Position, True) If Coord.Left + SizeInGrid > getWidth Then SV2D.Panel.Width = Coord.Left + SizeInGrid Return Coord End Sub Private Sub PlaceInVertGrid(Width As Int, Height As Int, Position As Int) As typCoord ' Computes the thumbnail coordinates in a vertical grid ' and increases the SV panel height if needed Dim Coord As typCoord Coord = CalcLeftTopInGrid(Position, False) If Coord.Top + SizeInGrid + LabelHeightInGrid > getHeight Then SV2D.Panel.Height = Coord.Top + SizeInGrid + LabelHeightInGrid + MarginTop Return Coord End Sub Private Sub PlaceInGrid(pnl As Panel, IV As ImageView, SrcBmp As Bitmap, Position As Int) Try Dim Coord As typCoord Select gStyle Case STYLE_HORZGRID_SQUARED ' Horizontal scrolling grid with squared thumbnails SrcBmp = SquareBmp(SrcBmp, SizeInGrid) IV.Bitmap = SrcBmp Coord = PlaceInHorzGrid(SrcBmp.Width, SrcBmp.Height, Position) Case STYLE_HORZGRID_RESCALED ' Horizontal scrolling grid with rescaled thumbnails (thumbnails can be tilted) If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SizeInGrid) Else SrcBmp = RotateBmp(SrcBmp, SizeInGrid) IV.Tag = gPreviousAngle End If IV.Bitmap = SrcBmp Coord = PlaceInHorzGrid(SrcBmp.Width, SrcBmp.Height, Position) Case STYLE_VERTGRID_SQUARED ' Vertical scrolling grid with squared thumbnails SrcBmp = SquareBmp(SrcBmp, SizeInGrid) IV.Bitmap = SrcBmp Coord = PlaceInVertGrid(SrcBmp.Width, SrcBmp.Height, Position) Case STYLE_VERTGRID_RESCALED ' Vertical scrolling grid with rescaled thumbnails (thumbnails can be tilted) If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SizeInGrid) Else SrcBmp = RotateBmp(SrcBmp, SizeInGrid) IV.Tag = gPreviousAngle End If IV.Bitmap = SrcBmp Coord = PlaceInVertGrid(SrcBmp.Width, SrcBmp.Height, Position) End Select SV2D.Panel.AddView(pnl, Coord.Left, Coord.Top, SizeInGrid, SizeInGrid + LabelHeightInGrid) pnl.AddView(IV, Round((SizeInGrid - SrcBmp.Width)/2), Round((SizeInGrid - SrcBmp.Height)/2), SrcBmp.Width, SrcBmp.Height) Catch Log("") End Try End Sub Private Sub MoveInGrid(Thumbnail As Panel, FromPos As Int, ToPos As Int) ' Moves the panel reference in the thumbnail list If FromPos > -1 Then gThumbnailList.RemoveAt(FromPos) If ToPos > -1 Then gThumbnailList.InsertAt(ToPos, Thumbnail) ' Updates the gallery Dim Start As Int If FromPos < 0 Then Start = ToPos Else If ToPos < 0 Then Start = FromPos Else Start = Min(FromPos, ToPos) End If Dim pnl As Panel Dim Coord As typCoord If gStyle = STYLE_HORZGRID_SQUARED Or gStyle = STYLE_HORZGRID_RESCALED Then ' Horizontal grid SV2D.Panel.Width = SizeInGrid For i = Start To gThumbnailList.Size - 1 pnl = gThumbnailList.Get(i) Coord = PlaceInHorzGrid(pnl.Width, pnl.Height, i) pnl.Left = Coord.Left pnl.Top = Coord.Top Next Else ' Vertical grid SV2D.Panel.Height = SizeInGrid For i = Start To gThumbnailList.Size - 1 pnl = gThumbnailList.Get(i) Coord = PlaceInVertGrid(pnl.Width, pnl.Height, i) pnl.Left = Coord.Left pnl.Top = Coord.Top Next End If End Sub 'Sets the label below a thumbnail 'This function works only with the grid style. 'The thumbnail must have been created with LabelHeightInGrid > 0. Public Sub SetLabelInGrid(Thumbnail As Panel, LabelText As String, LabelColor As Int, LabelSize As Int) If gStyle = STYLE_HORZGRID_RESCALED Or gStyle = STYLE_HORZGRID_SQUARED Or _ gStyle = STYLE_VERTGRID_RESCALED Or gStyle = STYLE_VERTGRID_SQUARED Then If LabelHeightInGrid < 2dip Then Return Dim lbl As Label If Thumbnail.NumberOfViews = 1 Then lbl.Initialize("") Thumbnail.AddView(lbl, 0, Thumbnail.Height - LabelHeightInGrid + 1dip, Thumbnail.Width, LabelHeightInGrid - 1dip) Else lbl = Thumbnail.GetView(1) End If lbl.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.TOP lbl.TextColor = LabelColor lbl.TextSize = LabelSize lbl.Text = LabelText End If End Sub Public Sub AddCheckBox(Thumbnail As Panel, Value As Boolean) ' Dim chk As CheckBox ' ' chk.Initialize("") ' chk.Color = Colors.White ' chk.TextColor = Colors.Red ' ' Thumbnail.AddView(chk, 3dip, 3dip, 20dip, 20dip) Dim img As ImageView img.Initialize("") img.Gravity = Gravity.FILL img.Bitmap = BitmapCheckbox 'LoadBitmap(File.DirAssets,"checkbox.png") '使用统一图片, 节省内存 Thumbnail.AddView(img, 0, 0, Thumbnail.Width, Thumbnail.Height) img.Visible = Value img.Tag = Value End Sub #End Region Private Sub InitializePanel(pnl As Panel, IV As ImageView, Tag As Object) ' Initializes the thumbnail panel pnl.Initialize("") pnl.Tag = Tag IV.Initialize("") IV.Gravity = Gravity.NO_GRAVITY ' Dim x As ColorDrawable ' x.Initialize2(Colors.White, 0, 1, Colors.RGB(237,237,237)) ' pnl.Background = x ' Sets the listeners Dim r As Reflector r.Target = pnl r.SetOnTouchListener("Panel_Touch") If sub_Click <> "" Then r.SetOnClickListener("Panel_Click") If sub_LongClick <> "" Then r.SetOnLongClickListener("Panel_LongClick") End Sub ' Creates the bitmap to display but does not paint it on a thumbnail ' Call this function if you just want to process the bitmap Public Sub ProcessBitmap(SrcBmp As Bitmap) As Bitmap Select gStyle Case STYLE_ROW_SQUARED ' Scrolling row with squared thumbnails SrcBmp = SquareBmp(SrcBmp, SV2D.Height) Case STYLE_ROW_RESCALED ' Scrolling row with rescaled thumbnails (thumbnails can be tilted) If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SV2D.Height) Else SrcBmp = RotateBmp(SrcBmp, SV2D.Height) End If Case STYLE_HORZGRID_SQUARED, STYLE_VERTGRID_SQUARED ' Scrolling grid with squared thumbnails SrcBmp = SquareBmp(SrcBmp, SizeInGrid) Case STYLE_HORZGRID_RESCALED, STYLE_VERTGRID_RESCALED ' Scrolling grid with rescaled thumbnails (thumbnails can be tilted) If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SizeInGrid) Else SrcBmp = RotateBmp(SrcBmp, SizeInGrid) End If Case STYLE_COLUMN_SQUARED ' Scrolling column with squared thumbnails SrcBmp = SquareBmp(SrcBmp, SV2D.Width) Case STYLE_COLUMN_RESCALED ' Scrolling column with rescaled thumbnails (thumbnails can be tilted) If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SV2D.Width) Else SrcBmp = RotateBmp(SrcBmp, SV2D.Width) End If Case STYLE_PILE_WITH_DRAG ' Pile of thumbnails (thumbnails can be dragged out of the pile) If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SizeInPile) Else SrcBmp = RotateBmp(SrcBmp, SizeInPile) End If End Select If ForceColorReduction Then Return BmpPlus.ReduceColors(SrcBmp) Else Return SrcBmp End If End Sub ' Adds a thumbnail to the end of the gallery ' The tag can be used to identify your picture once clicked. Public Sub AddThumbnail(SrcBmp As Bitmap, Tag As Object) Try Dim pnl As Panel, IV As ImageView InitializePanel(pnl, IV, Tag) Select gStyle Case STYLE_ROW_SQUARED ' Scrolling row with squared thumbnails If getWidth > 0 Then SV2D.Panel.Width = getWidth + SpaceBetweenThumbnails SrcBmp = SquareBmp(SrcBmp, SV2D.Height) IV.Bitmap = SrcBmp SV2D.Panel.AddView(pnl, getWidth, 0, SV2D.Height, SV2D.Height) SV2D.Panel.Width = getWidth + SV2D.Height pnl.AddView(IV, 0, CalcTop(0), SrcBmp.Width, SrcBmp.Height) Case STYLE_ROW_RESCALED ' Scrolling row with rescaled thumbnails (thumbnails can be tilted) If getWidth > 0 Then SV2D.Panel.Width = getWidth + SpaceBetweenThumbnails If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SV2D.Height) Else SrcBmp = RotateBmp(SrcBmp, SV2D.Height) IV.Tag = gPreviousAngle End If IV.Bitmap = SrcBmp SV2D.Panel.AddView(pnl, getWidth, 0, SrcBmp.Width, SV2D.Height) SV2D.Panel.Width = getWidth + SrcBmp.Width pnl.AddView(IV, 0, CalcTop(Round((SV2D.Height - SrcBmp.Height)/2)), SrcBmp.Width, SrcBmp.Height) Case STYLE_HORZGRID_SQUARED ' Horizontal scrolling grid with squared thumbnails PlaceInGrid(pnl, IV, SrcBmp, -1) Case STYLE_HORZGRID_RESCALED ' Horizontal scrolling grid with rescaled thumbnails (thumbnails can be tilted) PlaceInGrid(pnl, IV, SrcBmp, -1) Case STYLE_COLUMN_SQUARED ' Scrolling column with squared thumbnails If getHeight > 0 Then SV2D.Panel.Height = getHeight + SpaceBetweenThumbnails SrcBmp = SquareBmp(SrcBmp, SV2D.Width) IV.Bitmap = SrcBmp SV2D.Panel.AddView(pnl, 0, getHeight, SV2D.Width, SV2D.Width) SV2D.Panel.Height = getHeight + SV2D.Width pnl.AddView(IV, CalcLeft(0), 0, SrcBmp.Width, SrcBmp.Height) Case STYLE_COLUMN_RESCALED ' Scrolling column with rescaled thumbnails (thumbnails can be tilted) If getHeight > 0 Then SV2D.Panel.Height = getHeight + SpaceBetweenThumbnails If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SV2D.Width) Else SrcBmp = RotateBmp(SrcBmp, SV2D.Width) IV.Tag = gPreviousAngle End If IV.Bitmap = SrcBmp SV2D.Panel.AddView(pnl, 0, getHeight, SV2D.Width, SrcBmp.Height) SV2D.Panel.Height = getHeight + SrcBmp.Height pnl.AddView(IV, CalcLeft(Round((SV2D.Width - SrcBmp.Width)/2)), 0, SrcBmp.Width, SrcBmp.Height) Case STYLE_VERTGRID_SQUARED ' Vertical scrolling grid with squared thumbnails PlaceInGrid(pnl, IV, SrcBmp, -1) Case STYLE_VERTGRID_RESCALED ' Vertical scrolling grid with rescaled thumbnails (thumbnails can be tilted) PlaceInGrid(pnl, IV, SrcBmp, -1) Case STYLE_PILE_WITH_DRAG ' Pile of thumbnails (thumbnails can be dragged out of the pile) If MinTiltAngle = 0 And MaxTiltAngle = 0 Then SrcBmp = RescaleBmp(SrcBmp, SizeInPile) Else SrcBmp = RotateBmp(SrcBmp, SizeInPile) IV.Tag = gPreviousAngle End If IV.Bitmap = SrcBmp Dim Margin, Left, Top As Int Margin = Round(SrcBmp.Width / 5) Left = Rnd(Margin, Max(getWidth - SrcBmp.Width - Margin, Margin) + 1) Margin = Round(SrcBmp.Height / 5) Top = Rnd(Margin, Max(getHeight - SrcBmp.Height - Margin, Margin) + 1) If HorizontalOffset <> 0 Or VerticalOffset <> 0 Then Left = Max(StillVisible - SrcBmp.Width, Min(CalcLeft(Left), getWidth - StillVisible)) Top = Max(StillVisible - SrcBmp.Height, Min(CalcTop(Top), getHeight - StillVisible)) End If SV2D.Panel.AddView(pnl, Left, Top, SrcBmp.Width, SrcBmp.Height) pnl.AddView(IV, 0, 0, SrcBmp.Width, SrcBmp.Height) End Select If ForceColorReduction Then IV.Bitmap = BmpPlus.ReduceColors(IV.Bitmap) gThumbnailList.Add(pnl) Catch Log("") End Try End Sub ' Adds a thumbnail on top of other thumbnails at the given position ' The tag can be used to identify your picture once clicked. ' This function works only with grid styles. ' It is not recommended to use AddThumbnail, InsertThumbnailAt or MoveThumbnail after that because the relative positions are wrong. Public Sub InsertOnTop(SrcBmp As Bitmap, Position As Int, Tag As Object) If gStyle = STYLE_HORZGRID_RESCALED Or gStyle = STYLE_HORZGRID_SQUARED Or _ gStyle = STYLE_VERTGRID_RESCALED Or gStyle = STYLE_VERTGRID_SQUARED Then Dim pnl As Panel, IV As ImageView InitializePanel(pnl, IV, Tag) PlaceInGrid(pnl, IV, SrcBmp, Position) If ForceColorReduction Then IV.Bitmap = BmpPlus.ReduceColors(IV.Bitmap) gThumbnailList.Add(pnl) End If End Sub ' Inserts a thumbnail at the given position ' The position is not taken into account if style = pile. ' The tag can be used to identify your picture once clicked. Public Sub InsertThumbnailAt(SrcBmp As Bitmap, Position As Int, Tag As Object) If gStyle = STYLE_HORZGRID_SQUARED Or gStyle = STYLE_HORZGRID_RESCALED Or _ gStyle = STYLE_VERTGRID_SQUARED Or gStyle = STYLE_VERTGRID_RESCALED Then If Position < 0 Then Log("Invalid position: " & Position) Position = 0 End If If Position > NumberOfThumbnails Then Log("Invalid position: " & Position) Position = NumberOfThumbnails End If Dim pnl As Panel, IV As ImageView InitializePanel(pnl, IV, Tag) PlaceInGrid(pnl, IV, SrcBmp, -1) If ForceColorReduction Then IV.Bitmap = BmpPlus.ReduceColors(IV.Bitmap) MoveInGrid(pnl, -1, Position) Else AddThumbnail(SrcBmp, Tag) MoveThumbnail(SV2D.Panel.NumberOfViews - 1, Position) End If End Sub Private Sub UpdateGallery(Start As Int) Dim pnl As Panel If gStyle <= STYLE_HORZGRID_RESCALED Then ' Horizontal ScrollView Dim Left As Int For i = Start - 1 To gThumbnailList.Size - 1 If i >= 0 Then pnl = gThumbnailList.Get(i) If i >= Start Then If Left = 0 Then pnl.Left = 0 Else pnl.Left = Left + SpaceBetweenThumbnails End If End If Left = pnl.Left + pnl.Width End If Next SV2D.Panel.Width = Left Else If gStyle <= STYLE_VERTGRID_RESCALED Then ' Vertical ScrollView Dim Top As Int For i = Start - 1 To gThumbnailList.Size - 1 If i >= 0 Then pnl = gThumbnailList.Get(i) If i >= Start Then If Top = 0 Then pnl.Top = 0 Else pnl.Top = Top + SpaceBetweenThumbnails End If End If Top = pnl.Top + pnl.Height End If Next SV2D.Panel.Height = Top End If End Sub ' Moves a thumbnail from a position to another ' First position = 0 ' Last position = NumberOfThumbnails - 1 ' This function does nothing if style = pile. Public Sub MoveThumbnail(FromPos As Int, ToPos As Int) If gStyle = STYLE_PILE_WITH_DRAG Or FromPos = ToPos Then Return If FromPos < 0 Or FromPos >= NumberOfThumbnails Then Log("FromPos: invalid position") Return End If If ToPos < 0 Or ToPos >= NumberOfThumbnails Then Log("ToPos: invalid position") Return End If Dim pnl As Panel pnl = gThumbnailList.Get(FromPos) If gStyle = STYLE_HORZGRID_SQUARED Or gStyle = STYLE_HORZGRID_RESCALED Or _ gStyle = STYLE_VERTGRID_SQUARED Or gStyle = STYLE_VERTGRID_RESCALED Then MoveInGrid(pnl, FromPos, ToPos) Else gThumbnailList.RemoveAt(FromPos) gThumbnailList.InsertAt(ToPos, pnl) Dim Start As Int Start = Min(FromPos, ToPos) UpdateGallery(Start) End If End Sub ' Removes the thumbnail at the given position Public Sub RemoveThumbnailAt(Position As Int) If Position < 0 Or Position >= NumberOfThumbnails Then Log("Invalid position") Return End If Dim pnl As Panel pnl = gThumbnailList.Get(Position) If gStyle = STYLE_HORZGRID_SQUARED Or gStyle = STYLE_HORZGRID_RESCALED Or _ gStyle = STYLE_VERTGRID_SQUARED Or gStyle = STYLE_VERTGRID_RESCALED Then MoveInGrid(pnl, Position, -1) pnl.RemoveView Else gThumbnailList.RemoveAt(Position) pnl.RemoveView If gStyle <> STYLE_PILE_WITH_DRAG Then UpdateGallery(Position) End If End Sub ' Removes the thumbnail with the given tag Public Sub RemoveThumbnailWithTag(Tag As Object) Dim pnl As Panel For Position = 0 To gThumbnailList.Size - 1 pnl = gThumbnailList.Get(Position) If pnl.Tag = Tag Then RemoveThumbnailAt(Position) Exit End If Next End Sub ' Loads a file and inserts its content at the given position ' The position is not taken into account if style = pile. ' The tag can be used to identify your picture once clicked. Public Sub InsertFileAt(Dir As String, FileName As String, InsertPosition As Int, Tag As Object) Try InsertThumbnailAt(LoadBitmapSample(Dir, FileName, SV2D.Width, SV2D.Height), InsertPosition, Tag) Catch Msgbox("Unable to load: " & File.Combine(Dir, FileName) & CRLF & CRLF & LastException.Message, "File error") Return End Try End Sub Private Sub IsPicture(Filename As String) As Boolean Return Filename.EndsWith(".bmp") Or Filename.EndsWith(".gif") Or Filename.EndsWith(".jpg") _ Or Filename.EndsWith(".jpeg") Or Filename.EndsWith(".png") End Sub ' Adds the folder content at the end of the gallery ' Accepted file extensions: .bmp, .gif, .jpg, .jpeg, .png ' The thumbnail tag is automatically set to Dir+Filename. ' MaxNbFiles: maximum number of files to load (0 = all) Public Sub AddFolder(Dir As String, MaxNbFiles As Int) Dim lst As List Try lst = File.ListFiles(Dir) Catch Msgbox("Unable to list files of " & Dir & CRLF & CRLF & LastException.Message, "Folder error") Return End Try If lst.IsInitialized Then lst.SortCaseInsensitive(True) Dim Cpt As Int For i = 0 To lst.Size - 1 If Not(File.IsDirectory(Dir, lst.Get(i))) Then If IsPicture(File.Combine(Dir, lst.Get(i)).ToLowerCase) Then AddThumbnail(LoadBitmapSample(Dir, lst.Get(i), SV2D.Width, SV2D.Height), File.Combine(Dir, lst.Get(i))) Cpt = Cpt + 1 If Cpt = MaxNbFiles Then Exit End If End If Next Else Msgbox("Unable to list files of " & Dir & CRLF & CRLF & LastException.Message, "Folder error") Return End If End Sub ' Gets the thumbnail panel at the given position ' First position = 0 ' Last position = NumberOfThumbnails - 1 Public Sub GetThumbnailAt(Position As Int) As Panel If Position < 0 Or Position >= NumberOfThumbnails Then Log("Invalid position") Return Null End If Return gThumbnailList.Get(Position) End Sub ' Gets the thumbnail panel with the given tag Public Sub GetThumbnailWithTag(Tag As Object) As Panel Dim pnl As Panel For i = 0 To SV2D.Panel.NumberOfViews - 1 pnl = SV2D.Panel.GetView(i) If pnl.Tag = Tag Then Return pnl Next Return Null End Sub ' Jumps to the given position Public Sub JumpTo(Position As Int) Dim pnl As Panel pnl = gThumbnailList.Get(Position) Dim PreviousPosition, NewPosition As Int PreviousPosition = -1 If gStyle <= STYLE_HORZGRID_RESCALED Then NewPosition = Min(Max(0, pnl.Left - 5dip), getWidth - SV2D.Width) Do Until PreviousPosition = SV2D.HorizontalScrollPosition PreviousPosition = SV2D.HorizontalScrollPosition SV2D.HorizontalScrollPosition = NewPosition DoEvents Loop Else If gStyle <= STYLE_VERTGRID_RESCALED Then NewPosition = Min(Max(0, pnl.Top - 5dip), getHeight - SV2D.Height) Do Until PreviousPosition = SV2D.VerticalScrollPosition PreviousPosition = SV2D.VerticalScrollPosition SV2D.VerticalScrollPosition = NewPosition DoEvents Loop End If End Sub #Region Events Private Sub Panel_Touch(ViewTag As Object, Action As Int, X As Float, Y As Float, MotionEvent As Object) As Boolean Dim pnl As Panel, IV As View pnl = Sender IV = pnl.GetView(0) Try If gStyle = STYLE_PILE_WITH_DRAG Then Dim r As Reflector r.Target = SV2D ' We prevent the SV from intercepting this touch event r.RunMethod2("requestDisallowInterceptTouchEvent", True, "java.lang.boolean") End If If Action <> 2 Then ' <> ACTION_MOVE If gPressedPanel.IsInitialized Then IV.Background = OldBackground gPressedPanel = Null If gStyle <> STYLE_PILE_WITH_DRAG Then If IV.Left <> OldLeft Then IV.Left = OldLeft If IV.Top <> OldTop Then IV.Top = OldTop End If End If End If If Action = 0 Then ' = ACTION_DOWN OldBackground = IV.Background gPressedPanel = pnl If PressedDrawable <> Null Then AddDrawableTo(pnl, PressedDrawable) pnl.BringToFront If gStyle = STYLE_PILE_WITH_DRAG Then gStartX = X gStartY = Y Else ' We ensure the thumbnail image is fully visible. ' It can be partially hidden because: ' 1) There's an offset: OldLeft = IV.Left If HorizontalOffset > 0 Then IV.Left = Min(getWidth - IV.Width, IV.Left) Else If HorizontalOffset < 0 Then IV.Left = Max(0, IV.Left) End If OldTop = IV.Top If VerticalOffset > 0 Then IV.Top = Min(getHeight - IV.Height, IV.Top) Else If VerticalOffset < 0 Then IV.Top = Max(0, IV.Top) End If ' 2) The ScrollView has not scrolled enough: If pnl.Left + pnl.Width > SV2D.HorizontalScrollPosition + SV2D.Width Then SV2D.HorizontalScrollPosition = pnl.Left + pnl.Width - SV2D.Width + 5dip Else If pnl.Left < SV2D.HorizontalScrollPosition Then SV2D.HorizontalScrollPosition = pnl.Left - 5dip End If If pnl.Top + pnl.Height > SV2D.VerticalScrollPosition + SV2D.Height Then SV2D.VerticalScrollPosition = pnl.Top + pnl.Height - SV2D.Height + 5dip Else If pnl.Top < SV2D.VerticalScrollPosition Then SV2D.VerticalScrollPosition = pnl.Top - 5dip End If End If Else If Action = 1 Then ' = ACTION_UP Else If Action = 2 Then ' = ACTION_MOVE If gStyle = STYLE_PILE_WITH_DRAG Then pnl.Left = Max(StillVisible - pnl.Width, Min(pnl.Left + X - gStartX, getWidth - StillVisible)) pnl.Top = Max(StillVisible - pnl.Height, Min(pnl.Top + Y - gStartY, getHeight - StillVisible)) End If End If If SubExists(gCB, sub_Touch) Then CallSub3(gCB, sub_Touch, pnl, Action) Catch Log("Touch exception: " & LastException.Message) End Try Return (sub_Click = "" And sub_LongClick = "") End Sub Private Sub Panel_Click(ViewTag As Object) As Boolean Dim pnl As Panel pnl = Sender If SubExists(gCB, sub_Click) Then CallSub2(gCB, sub_Click, pnl) Return True End Sub Private Sub Panel_LongClick(ViewTag As Object) As Boolean Dim pnl As Panel pnl = Sender If SubExists(gCB, sub_LongClick) Then CallSub2(gCB, sub_LongClick, pnl) Return True End Sub Private Sub SV2D_ScrollChanged(PosX As Int, PosY As Int) If SubExists(gCB, sub_Scroll) Then CallSub3(gCB, sub_Scroll, PosX, PosY) End Sub #End Region #Region Drawables ' Gets a drawable from the Android system resources Public Sub LoadDrawable(Name As String) As Object Dim r As Reflector r.Target = r.GetContext r.Target = r.RunMethod("getResources") r.Target = r.RunMethod("getSystem") Dim ID_Drawable As Int ID_Drawable = r.RunMethod4("getIdentifier", Array As Object(Name, "drawable", "android"), _ Array As String("java.lang.String", "java.lang.String", "java.lang.String")) r.Target = r.GetContext r.Target = r.RunMethod("getResources") Return r.RunMethod2("getDrawable", ID_Drawable, "java.lang.int") End Sub ' Draws a drawable on the thumbnail Public Sub AddDrawableTo(Thumbnail As Panel, Drawable As Object) C.Initialize(Thumbnail.GetView(0)) Dim DestRect As Rect DestRect.Initialize(0, 0, Thumbnail.GetView(0).Width, Thumbnail.GetView(0).Height) C.DrawDrawable(Drawable, DestRect) End Sub #End Region