Italian Gestures e pannello trasparente

AlpVir

Well-Known Member
Licensed User
Longtime User
Ho una quarantina di label sparse nello schermo che coprono praticamente il 95% della sua superfice.
In un angoletto ho sistemato due pulsantini microscopici (per forza di cose) che svolgono la funzione di "Avanti" e "Indietro" di una serie di record di una database.
Le label supportano gli eventi _Click e _LongClick.
Tutto funziona egregiamente ed il contenuto delle label viene aggiornato correttamente premendo il pulsante "Avanti" o il pulsante "Indietro".
Per questioni grafiche vorrei eliminare i due pulsanti (perchè microscopici) e trasferire le loro funzioni al trascinamento di un dito sul bordo sinistro o sul bordo destro dello schermo (rispettivamente funzione "indietro" e "avanti").
Ho guardato libreria Gestures che probabilmente potrebbe fare il caso mio ma essa prevede un pannello che copre l'intero schermo. Il pannello può sì essere reso trasparente
B4X:
pnl.Color = Colors.ARGB (0,255,255,255)
ma non sono riuscito a fare in modo che siano gestibili ANCHE gli eventi _Click e _LongClick delle label. Sembra che il pannello "copra" le label ed impedisca di agire su di esse.
E' una cosa possibile oppure devo scordarmi di realizzare quanto descritto ?
Grazie per l'attenzione.
 

LucaMs

Expert
Licensed User
Longtime User
Personalmente farei in altro modo, ad esempio utilizzarei una scrollview per le label, visto che sono tante; anche perché i pulsantini l'utente li vedrebbe, senza si trova davanti a una videata senza l'indicazione di scorrere col dito.

Il pannello trasparente (esiste il Colors.Transparent) ti consente di agire sui controlli sottostanti ma, per quanto ne so, solo se non utilizzi l'evento Touch del pannello stesso.

Cmq, faccio delle prove e ti faccio sapere.

[Purtroppo adesso ho la conferma]
 
Last edited:

AlpVir

Well-Known Member
Licensed User
Longtime User
Lo scrollview scrolla effettivamente tutto, anche le label, cosa che non desidero e sarebbe esteticamente bruttino.
Difatti io non ho un'altra serie di label da far vedere: ho solo un diverso contenuto delle label da proporre.
E' comunque vero che non c'è alcuna indicazione visiva del fatto che si debba fare scorrere il dito per visualizzare il record precedente o successivo.
Ho realizzato perfettamente questo pannello trasparente e questo scroll fra record (con conseguente aggiornamento delle label) ma gli eventi delle label sono irraggiungibili. Probabilmente ciò può essere fatto all'interno della sub che gestisce le gestures; ma non è cosa semplice.
 

udg

Expert
Licensed User
Longtime User
Ciao a tutti,

ho avuto modo di giocare un po' con le gesture e quindi provo a suggerire una linea d'azione basata sulla richiesta iniziale.
Prova a modificare l'evento Touch del pannello trasparente, differenziando tra azione MOVE (che nel tuo caso corrisponderà agli swipe dx -sx per caricare i dati del nuovo record) e le azioni UP/DOWN.
Quando verifichi che le coordinate di UP corrispondono esattamente a quelle di DOWN vuol dire che hai "registrato" un click sul pannello trasparente; a quel punto esegui un "Return False" in modo da non consumare l'evento Touch e passarlo all'elemento sottostante.

Al momento non sono in grado di testare qunato sopra, ma lascia pure un messaggio che appena potrò darò ancora un'occhiata.

Buona giornata.

Umberto
ps: nel caso descritto non ti serve la lib Gestures
 

LucaMs

Expert
Licensed User
Longtime User
1) Dato che la soluzione pannello non funziona;
2) dato che hai solo label per la visualizzazione...
3) soluzione da matti (ma funzionerebbe): 40 label ognuna col proprio panello trasparente sovrapposto.

Accetto i "buuuuuu" ma solo finché non trovate una soluzione migliore :)
 

AlpVir

Well-Known Member
Licensed User
Longtime User
Sempre più difficile !!!
No, no. Non devo mica "stupirvi con effetti speciali".
In realtà sembra proprio che sia riuscito ad ottenere quanto desiderato: swipe del pannello trasparente e _click sulle label sottostanti. Manca ancora in _LongClick ma penso di riuscirci a breve.
Poi posto il codice relativo.
 

AlpVir

Well-Known Member
Licensed User
Longtime User
Non ho ancora implementato il sostituto dell'evento _LongClick ma non dovrebbe essere difficile farlo.
Prima bisogna mettere in Activity_Create :
B4X:
    '--- pannello trasparente per lo swipe   
    PanelA.Initialize ("panelA")
    Activity.AddView (PanelA, 0dip,50dip,100%x,100%y-50dip)
    PanelA.Color =  Colors.ARGB (0,255,255,255) 
    Gestures1.SetOnTouchListener(PanelA, "Handle_Touch")
    CurrentPointerId=-1
    MinDragMove= 50
Poi bisogna inserire la seguente sub a cui ho eliminato qualche linea di codice che non riguarda questo specifico problema
B4X:
Sub Handle_Touch(Object1 As Object, PointerId As Int, Action As Int, X As Float, Y As Float)  As Boolean
    Dim i  As Int
    Dim GO  As Int
    Dim S                  As String
    Select Action
        Case Gestures1.ACTION_DOWN
            Log ("DOWN")
            If CurrentPointerId=-1 Then
                LastX=X
                LastY=Y
                CurrentPointerId=PointerId
                TempoTouchDown = DateTime.Now  ' ticket in cui tocco
                XTouchDown = X                  ' coordinata X in cui tocco
                YTouchDown = Y                  ' coordinata X in cui tocco
            End If
        Case Gestures1.ACTION_MOVE
            Log ("MOVE")
            If CurrentPointerId=PointerId Then
                Dim MoveX, MoveY As Int
                MoveX=LastX-X
                MoveY=LastY-Y
                If MoveX>=MinDragMove OR MoveX<=-(MinDragMove) Then
                    LastX=X
                    LastY=Y
                End If
            End If
        Case Gestures1.ACTION_UP
            Log("UP " & " PointerID=" & PointerId & " X-XToucDown=" & (X-XTouchDown))
            If CurrentPointerId=PointerId Then
                If Abs(X-XTouchDown) > 150 Then
                    CurrentPointerId=-1
                    If X>XTouchDown Then
                        RecordIndietro
                    End If   
                    If X<XTouchDown Then
                        RecordAvantiDocente
                    End If
                Else
                    '--- individuo quale delle 36 label ho toccato
                    GO=-1
                    For i=0 To 35
                        If X>LbOre(i).Left AND X<(LbOre(i).Left+LbOre(i).Width) AND Y>LbOre(i).Top AND Y<(LbOre(i).Top+LbOre(i).Height) Then
                            GO=i
                            Exit
                        End If   
                    Next
                    If GO>-1 Then
                        ' adesso posso agire sulla singola label come meglio credo
                        ' ad esempio LbOre(GO).text = "ciao"
                        Return True
                    End If
                End If   
            End If
    End Select
    Return True
End Sub

Ovviamente bisogna utilizzare la libreria Gestures 1.2
 

LucaMs

Expert
Licensed User
Longtime User
Ah ecco, se ho capito bene (ho letto in fretta) era un po' quello che volevo consigliarti dopo aver dato un'occhiata alla Gestures: trovare quale view è compresa nelle coordinate, ma pensavo di darti troppe rogne, anche perché non è generalizzabile al massimo (ma lo sarebbe stato ancora meno aggiungendo un panel per ogni label!)

Almeno, a occhio mi sembra che tu faccia così, ora guardo meglio :)
 

LucaMs

Expert
Licensed User
Longtime User
Eppure, proprio qualche giorno fà stavo pensando, non troppo intensamente a dire il vero, alla home di Android; è possibile scorrere le "videate" con le icone delle app, addirittura facendolo lentamente, si può vedere quella "sottostante" in arrivo.

Pensavo di chiedere come si possa realizzare una cosa del genere, poi ho dato un'occhiatina a questo:
Custom transitions between activities e, infine... ho posposto la faccenda, come faccio spesso :D
 

udg

Expert
Licensed User
Longtime User
Ciao a tutti,

mi fa piacere che il problema sia ormai risolto. Ma visto che intanto ero tornato a casa ed avevo imbastito due righe di esempio..le posto lo stesso!
Approfitto per precisare che l'indicazione di usare "return false" nel touch era valida nel caso sotto il panel trasparente ci fossero altri pannelli in grado quindi di ricevere l'vento touch; ovviamente OT rispetto alle label di cui si parlava nel post #1..

Il codice seguente non usa la lib Gestures
B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
  Dim TouchX,TouchY As Float
   Dim l1,l2 As Label
   Dim p1 As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
   'Do not forget to load the layout file created with the visual designer. For example:
   'Activity.LoadLayout("Layout1")
  l1.Initialize("lbl1")
   l1.Tag="lbl1"
   l1.Text="uno"
   Activity.AddView(l1,10,10,100,50)
   l2.Initialize("lbl2")
   l2.tag="lbl2"
   l2.Text="due"
   Activity.AddView(l2,150,10,100,50)
   p1.Initialize("pnl1")
   p1.Color=Colors.Transparent
   Activity.AddView(p1,0%x,0%y,100%x,100%y)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub pnl1_Touch(Action As Int, X As Float, Y As Float)
Select Action
  Case Activity.ACTION_DOWN
    TouchX = X
     TouchY = Y
   Case Activity.ACTION_UP   
    If (X = TouchX) AND (Y=TouchY) Then
      cliccalabel(X,Y)
  Else
  If (X > TouchX) AND Abs (X-TouchX)>150 Then swipe("dx")
      If (X < TouchX) AND Abs (X-TouchX)>150 Then swipe("sx")
     End If   
   Case Else
    'non interessano gli step di movimento
End Select   
Return True
End Sub

Sub swipe(dir As String)
If dir = "dx" Then
  l1.Color=Colors.green
  l2.Color=Colors.green
Else
  l1.Color=Colors.Red
  l2.Color=Colors.Red
End If
End Sub

Sub lbl1_click
l1.text="click"
End Sub

Sub lbl2_click
l2.Text="clack"
End Sub

Sub cliccalabel(x As Float, y As Float)
For Each lbl As Label In Activity.GetAllViewsRecursive
  If (x > lbl.Left) AND (x<lbl.Left+lbl.Width) AND (y > lbl.Top) AND (y<lbl.Top+lbl.height) Then
    CallSub(Me,lbl.tag&"_click")
     Exit
   End If
Next
End Sub

Tutto buttato un po lì, ma funziona..

Umberto
 

LucaMs

Expert
Licensed User
Longtime User
Torno su questo argomento perché, per la prima volta, ho utilizzato un HorizontalScrollView.

Aggiungendo dei button in uno HorizontalScrollView, si possono scorrere senza che vengano clickati!

Quindi, un modo di ottenere quanto chiedeva AlpVir dev'esserci!
 

AlpVir

Well-Known Member
Licensed User
Longtime User
Preciso che il codice che ho postato tempo fa consente di ottenere quanto desiderato; è già da svariato tempo che la parte dell'app deputata allo scroll orizzontale è perfettamente funzionante (tranne la "finta" gestione del "_Long_Click" che - per motivi di tempo - non ho ancora implementato).
 
Top