﻿B4A=true
Group=app
ModulesStructureVersion=1
Type=Class
Version=9
@EndOfDesignText@
'version 1.10
'Author: Biswajit

Sub Class_Globals
	Private mCLV As CustomListView
	Private Base,IndexViewer As B4XView
	Private xui As XUI
	Private AllView As B4XView
	
	Private mTheme As String = "fixed"
	Private backColor,textColor As Int
	Private ActiveColor As Int = xui.Color_Green
	
	Private fromChr As Int = 65
	Private toChr As Int = 90
	Private count As Int = 26
	
	Private TypeNumeric,AscOrder As Boolean
	
	Public const ACTIVE_INDEX_THEME_FIXED As String = "fixed"
	Public const ACTIVE_INDEX_THEME_AUTOPOS As String = "autopos"
End Sub

Public Sub Initialize (clv As CustomListView, IndexTypeNumeric As Boolean, DarkTheme As Boolean, AscendingOrder As Boolean)
	mCLV = clv
	TypeNumeric = IndexTypeNumeric
	AscOrder = AscendingOrder
	
	If DarkTheme Then
		backColor = xui.Color_ARGB(100,0,0,0)
		textColor = xui.Color_white
	Else
		backColor = xui.Color_ARGB(100,255,255,255)
		textColor = xui.Color_Black
	End If
	
	Base = xui.CreatePanel("IndexScroller")
	Base.SetColorAndBorder(backColor,0,xui.Color_Transparent,5dip)
	
	IndexViewer = xui.CreatePanel("")
	IndexViewer.SetColorAndBorder(backColor,0,xui.Color_Transparent,5dip)
	IndexViewer.Visible = False
	
	mCLV.AsView.AddView(Base,mCLV.AsView.Width - 30dip, (mCLV.asview.height/2) - (mCLV.AsView.Height - mCLV.AsView.Height/3)/2,20dip,(mCLV.AsView.Height - mCLV.AsView.Height/3))
	mCLV.AsView.AddView(IndexViewer,mCLV.AsView.Width/2 - 30dip, (mCLV.asview.height/2) - 30dip,60dip,60dip)
	
	Dim l As Label:l.Initialize("")
	AllView = l:AllView.TextColor = textColor:AllView.TextSize = 30:AllView.SetTextAlignment("CENTER","CENTER")
	IndexViewer.AddView(l,0,0,IndexViewer.Width,IndexViewer.Height)
	
	Refresh
End Sub

Private Sub IndexScroller_Touch (Action As Int, X As Float, Y As Float)
	Select Action
		Case Base.TOUCH_ACTION_DOWN,Base.TOUCH_ACTION_MOVE
			If y > 0 And y < Base.Height Then
				For Each l As B4XView In Base.GetAllViewsRecursive
					l.TextColor = textColor
					If l.Top < y And (l.Top+l.Height) > y Then
						IndexViewer.GetView(0).Text = l.Text
						IndexViewer.SetVisibleAnimated(200,True)
						
						If mTheme = "fixed" Then
							IndexViewer.SetLayoutAnimated(100,mCLV.AsView.Width/2 - 30dip, (mCLV.asview.height/2) - 30dip,60dip,60dip)
						Else
							IndexViewer.SetLayoutAnimated(100,Base.left - 65dip, Base.Top+y-30dip ,60dip,60dip)
						End If
						
						If l.Tag > -1 Then mCLV.ScrollToItem(l.Tag)
						l.TextColor = ActiveColor
					End If
				Next
			End If
		Case Base.TOUCH_ACTION_UP
			IndexViewer.SetVisibleAnimated(200,False)
	End Select
End Sub

'Change active index color
Public Sub SetActiveColor(color As Int)
	ActiveColor = color
	Update
End Sub

'theme = one of active index theme constant
Public Sub SetActiveIndexTheme(theme As String)
	mTheme = theme
End Sub

'Call update to refresh the active index while manual scrolling
Public Sub Update
	For Each v As B4XView In mCLV.GetPanel(mCLV.FirstVisibleIndex).GetAllViewsRecursive
		If v Is Label Then
			For Each l As B4XView In Base.GetAllViewsRecursive
				l.TextColor = textColor
				If l.Text.ToUpperCase.CharAt(0) = v.Text.ToUpperCase.CharAt(0) Then
					l.TextColor = ActiveColor
				End If
			Next
		End If
	Next
End Sub

'You should call this after adding/removing CLV items
Public Sub Refresh
	If Not(TypeNumeric) Then
		fromChr = 65
		toChr = 90
		count = 26
	Else
		fromChr = 48
		toChr = 57
		count = 10
	End If
	For i=0 To count
		Dim lbl As Label:lbl.Initialize("")
		If AscOrder Then
			Base.AddView(lbl,0,(Base.Height/(count+1)) * i,Base.Width,Base.Height/(count+1))
		Else
			Base.AddView(lbl,0,(Base.Height/(count+1))  *(count-i),Base.Width,Base.Height/(count+1))
		End If
		AllView = lbl:AllView.Text = Chr(i+fromChr):AllView.TextColor = textColor:AllView.TextSize = 14:AllView.SetTextAlignment("CENTER","CENTER"):AllView.Tag = -1
		If i = count Then AllView.Text = "#"
	Next
	For i = 0 To mCLV.Size - 1
		For Each v As B4XView In mCLV.GetPanel(i).GetAllViewsRecursive
			If v Is Label Then
				If ((v.Text.ToUpperCase.CharAt(0)&"").GetBytes("ASCII")(0) >= fromChr And (v.Text.ToUpperCase.CharAt(0)&"").GetBytes("ASCII")(0) <= toChr) Then
					For Each la As B4XView In Base.GetAllViewsRecursive
						If la.Text.CharAt(0) = v.Text.ToUpperCase.CharAt(0) Then
							If Round(la.Tag) = -1 Then la.Tag = i
						End If
					Next
				Else
					If AscOrder Then
						If Round(Base.GetView(Base.NumberOfViews-1).Tag) = -1 Then Base.GetView(Base.NumberOfViews-1).Tag = i
					Else
						If Round(Base.GetView(0).Tag) = -1 Then Base.GetView(0).Tag = i
					End If
				End If
				Exit
			End If
		Next
	Next
	Update
End Sub