Vážená komunito,
pro FMX si často dělám vlastní komponenty a rozhodl jsem se nahradit nevhodné ScrollBoxy, které postrádají některé moderní funkce. Narazil jsem ale na problém, který se mi nedaří vyřešit - hlavně z důvodu, že mi v FMX nejde "vynutit" kliknutí myši na mnou požadované pozici.
Rád bych měl posuvný panel u kterého lze posouvat pomocí myši nahoru a dolu i v případě, že dojde ke kliku na jiné komponentě na posuvném panelu. V podstatě událost kliku se má provést jen tehdy, když nedojde k posunu panelu, tj. rozdíl hodnoty osy Y u MouseDown a MouseUp musí být menší než nějaká malá konstanta. Uživatel se tak pro posun nemusí trefovat např. mimo tlačítka. Fungují tak moderní mobilní aplikace. Z nějakého důvodu ale ScrollBoxy tuto funkci postrádají.
Nemá smysl zde popisovat celou komponentu - jen to kritické: nad všema dětma umístěné v posuvné komponentě mám TLayout s HitTest := true, která slouží jako maska. Tato maska zachytí událost MouseDown, MouseUp, MouseMove a MouseLeave. Zde vyhodnotím, zda obsluha chce provést klik a nebo posun panelu.
Kódy níže jsem ořezal tak aby byly co nejjednodušší:
procedure TSimpleScrollPanel.TouchMaskMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
begin
if FMouseDown then
if abs(Y - FMouseY) >= FTouchRange then // pokud má dojít k posunu panelu a ne ke kliku
begin
FBasePosition := FBasePosition - (Y - FMouseY);
FMouseSlided := true; // tato proměnná říká, zda bylo posunuto panelem - pak se neprovede klik
FMouseY := Y;
Update; // aktualizace panelu atd.
end;
end;
procedure TSimpleScrollPanel.TouchMaskMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
FMouseDown := false;
if not FMouseSlided and Self.PointInObjectLocal(X, Y) then
begin
// pokud to padne sem, má se provést klik na tom objektu nad kterým je myš
end;
end;
V TouchMaskMouseUp jsem zkoušel různé způsoby, rušil jsem HitTest na masce a zkoušel simulovat klik, vyčítal děti a zkoušel vyvolat Click událost (bohužel TControl.Click je v protected, takže nelze provést, i když prý to kdysi šlo)...
Prostě, potřebuji nějak znovu vyvolat klik událost v místě kurzoru. Na panelu můžou být různé objekty a proto asi není jiná možnost. Osobně mě překvapuje, že je u FMX tak problematické vyvolat událost kliku v místě kurzoru... Ale třeba hledám moc komplikované řešení a existuje něco jednoduššího?!
Děkuji za případné rady.
A.