Autor Téma: Kapacitní dotykový displej se chová podivně u tlačítka TSpeedButton  (Přečteno 1344 krát)

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 234
  • Karma: 0
Vážená komunito,

asi opět narážím na vlastní neznalost, ale již nevím co dělat. Mám vlastní FMX komponentu - tlačítko. V jednoduchém FMX projektu vše funguje jak má, respektive pokud klikám pomocí myši, nebo aplikaci zkouším na dotykovém odporovém displeji. Jak u Windows 7, 8 i 10.

Problém nastává pouze u kapacitního displeje. Patrně je zde problém v tom, že displej podporuje multitouch a moje tlačítko si to neumí přebrat. A kde je problém? Tlačítko se má při kliknutí rozsvítit po celou dobu stisku. Jenže u tohoto kapacitního displeje se rozsvítí jen někdy. Jednou při druhém kliku, jindy při šestém. Nezáleží na síle ani délce kliku.

Vzhledem k tomu, že je to moje komponenta, rozhodl jsem se provést test s TSpeedButton komponentou. A chová se to úplně stejně. Defaultně SpeedButton po označení (výběru) svítí. Při kliku se má ještě více prosvítit. To ale nastává jen občas. Opět nezáleží na délce kliku.

U obou komponent jsem si logoval klik událost a ta vždy reaguje správně. Tj. i když se tlačítko nerozsvítí, tak click událost přijde.

Setkal se s tím někdo?

Platforma: Windows 7, 8, 10
Vývojové prostředí: Delphi Berlin

Děkuji.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2732
  • Karma: 105
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
A jak se chová udalost OnTap ?

Nebo si muzes zkusit pomoci nejak jako pri kliknuti OnClick

Kód: Delphi [Vybrat]
  1. procedure TForm18.Button1Click(Sender: TObject);
  2. var
  3.   button: TButton;
  4. begin
  5.   button := Sender AS TButton;
  6.   button.StaysPressed := True;
  7.   button.IsPressed := True;
  8.  
  9.   TThread.CreateAnonymousThread(
  10.     procedure
  11.     begin
  12.       Sleep(500);
  13.       TThread.Synchronize(nil,
  14.         procedure
  15.         begin
  16.            button.IsPressed := False;
  17.         end);
  18.      end
  19.    ).Start;
  20. end;
  21.  
Embarcadero MVP - Czech republic

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 234
  • Karma: 0
OnTap událost přijde vždy u dotykového displeje, tj. i když se tlačítko rozsvítí i nerozsvítí. Stejně jako OnClick událost.

Pokud je tlačítko skupinové, tak vše funguje jak má. Jakmile je ale samostatné a nezůstává stisknuté po uvolnění stisku, tak zlobí grafika.

Rád bych přišel na to, proč se tak děje. Jistě bych vymyslel nějaký kód co by to dokázal vizuálně vyřešit, ale to není ono.

Napsal jsem i výrobci kapacitního displeje, jak zrušit gesta. Bohužel jejich aplikace mě nepustí do nastavení.
« Poslední změna: 15-05-2020, 14:25:45 od age.new »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3075
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Defaultně SpeedButton po označení (výběru) svítí. Při kliku se má ještě více prosvítit. To ale nastává jen občas. Opět nezáleží na délce kliku.
Ne, ze bych neco v Delphi delal s dotykovou obrazovkou (jen v C# ve WinForms), ale jak muze dojit na touch screenu k oznaceni (vyberu) tlacitka? Na hover ani focus se tam nehraje a prvni akci je click pri doteku na tlacitko. Ta tlacitka ve WinForms delal kolega a ja uz si to nepamatuju, jak to bylo udelany a ten projekt u sebe vubec nemam, takze se nepodivam, ale co me ted napadat, tak bych se zasade ridil OnMouseDown/OnMouseUp a nejak se zkusil vyporadat s dblclickem. Jak se presne chova OnTap v Delphi nevim.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2732
  • Karma: 105
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Defaultně SpeedButton po označení (výběru) svítí. Při kliku se má ještě více prosvítit. To ale nastává jen občas. Opět nezáleží na délce kliku.
Ne, ze bych neco v Delphi delal s dotykovou obrazovkou (jen v C# ve WinForms), ale jak muze dojit na touch screenu k oznaceni (vyberu) tlacitka? Na hover ani focus se tam nehraje a prvni akci je click pri doteku na tlacitko. Ta tlacitka ve WinForms delal kolega a ja uz si to nepamatuju, jak to bylo udelany a ten projekt u sebe vubec nemam, takze se nepodivam, ale co me ted napadat, tak bych se zasade ridil OnMouseDown/OnMouseUp a nejak se zkusil vyporadat s dblclickem. Jak se presne chova OnTap v Delphi nevim.

No některá zařízení s kapacitním displejem umožnují detekovat sílu stisku, ale pochybuji, že umí Windows. Nebo délku stisku, což je častejší a obecně používanější a FMX to myslím tak bere - resp. chování některých komponent (interně se hodně používají časovače) to velmi napovídá , takže klidně může lehký stisk označit a delší stisk stisknout.
Jelikož poslední dobou hodně s FMX pracuji, tak musím říct že mne některé věci překvapují a v některých oblastech hodně tomu přicházím na chut.

Takže myšlenka, že první akce je click nemusí být vůbec správná.

Každopadně OnTap - Occurs when a user taps the control using a finger or a similar device (not a mouse) a je vyvolán ještě před click a ve FMX je celkem dost použivána, hlavně na mobilních zařízeních.


Embarcadero MVP - Czech republic

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3075
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
No některá zařízení s kapacitním displejem umožnují detekovat sílu stisku, ale pochybuji, že umí Windows.
No nazdar... Doufam, ze to nikoho nenapadne pouzit v mobilech nebo autoradiich - uz dneska je to UI navrzene pro detske prstiky a nektere veci se s tim skoro nedaji udelat :-(

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2732
  • Karma: 105
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
No některá zařízení s kapacitním displejem umožnují detekovat sílu stisku, ale pochybuji, že umí Windows.
No nazdar... Doufam, ze to nikoho nenapadne pouzit v mobilech nebo autoradiich - uz dneska je to UI navrzene pro detske prstiky a nektere veci se s tim skoro nedaji udelat :-(

On to umi iPhone 6s a novější (tj. 5 let zpátky), takže to není žádná raketová technologie :-)
Embarcadero MVP - Czech republic

Offline raul

  • Hrdina
  • ****
  • Příspěvků: 365
  • Karma: 15
    • Verze Delphi: FPC :D
Delali jsme aplikaci v Cordove (ex Phonegap) tzn js a html zkompilovane do aplikace. Na samsung tabletech ale nebylo mozne rozbehat eventy klikani apod. Nekteri lide nebyli schopni kliknout, nekteri v pohode. Kolega nakonec udelal nejakej tester, kterej vypisoval log vsech eventu a byl to vicemene jen bordel, ktery nebyl ani podobny jinym zarizenim. Nekdo na to dokonce psal patch, ktery ale opet fungoval nejak. Nakonec jsme to vyresili koupenim lenova, ktere tim netrpelo vubec. Mozna je tohle problem uplne jiny, ale mozna by to mohlo souviset. Zkusil bych tedy i jine zarizeni a posleze prozkoumaval hloubeji. (Btw efekt stisku tlacitka se objevil i na tom samsungu vzdy, jen to proste obcas dostalo event tap, click, a mix dalsich.)
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3075
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
On to umi iPhone 6s a novější (tj. 5 let zpátky), takže to není žádná raketová technologie :-)
Tak iPhone bych nechtel ani zadarmo, leda bych se ho obratem ruky zbavil :-) Ale on s tim snad koketoval jeden cas i Android. Ale udajne lonsky model iPhonu uz to zase nema/nepouziva a misto toho reaguje na delku doteku. Jedina funkce, kde by mi to prislo prirozene, je nekde v malovani stetcem, ze by to reagovalo na tlak a prizpusobovalo mu sirku cary, ale jinak mi to prijde jako dost velka ptakovina.

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 234
  • Karma: 0
Tak po důkladnějším logování jsem přišel na toto:

- když zmáčknu krátce, tak přijdou všechny události click, down, up
- když zmáčknu dlouze, tak události click, down, up přijdou až poté, co sundám prst

v obou výše uvedených případech se tlačítko nerozsvítí, i když kódem to projde.

- když zmáčknu dlouze a zároveň trochu prstem hnu (o pár pixelů), tak se tlačítko rozsvítí. Přijde totiž událost click, down a až prst uvolním, tak poté přijde událost up.

a zde jedna perlička. Při pokusech s rychlým stiskem a potažením prstu po tlačítku se cca 1x z deseti případů podaří tlačítko nechat rozsvícené i po uvolnění prstu. Přijdou jen události click a down. Událost up nenastane.

... příčina je patrně v tom, jak kapacitní displej posílá události např. kvůli gestům. U odporového displeje bez gest vše funguje jak má.

Možná mám nějakou hloupost v kódu při obsluze dědičnosti. Komponentu tlačítka jsem přepsal, vyházel co šlo a vznikla z toho velmi jednoduchá komponenta. Přijde Vám, že je něco špatně s obsluhou up / down stavů?

Kód: Delphi [Vybrat]
  1. unit ImageButton;
  2.  
  3. interface
  4.  
  5. uses
  6.   FMX.Objects, FMX.Controls, FMX.Types, FMX.Layouts, FMX.Effects, System.UITypes, System.SysUtils, System.Classes;
  7.  
  8. type
  9.   TUpDownState = (udsUP, udsDOWN);
  10.   TEnableState = (esENABLED, esDISABLED);
  11.  
  12.   TImageButton = class(TLayout)
  13.   private
  14.     FUpDownState: TUpDownState;
  15.     FEnableState: TEnableState;
  16.     FAllowAllUp: boolean;
  17.     FGroupIndex: integer;
  18.  
  19.     FEnabledUpImage: TImage;
  20.     FEnabledDownImage: TImage;
  21.     FDisabledUpImage: TImage;
  22.     FDisabledDownImage: TImage;
  23.  
  24.     FEnabledUpText: TText;
  25.     FEnabledDownText: TText;
  26.     FDisabledUpText: TText;
  27.     FDisabledDownText: TText;
  28.  
  29.     FShowEnabledUpImage: boolean;
  30.     FShowEnabledDownImage: boolean;
  31.     FShowEnabledUpText: boolean;
  32.     FShowEnabledDownText: boolean;
  33.  
  34.     FShowDisabledUpImage: boolean;
  35.     FShowDisabledDownImage: boolean;
  36.     FShowDisabledUpText: boolean;
  37.     FShowDisabledDownText: boolean;
  38.  
  39.     IsClicked: boolean;
  40.  
  41.     procedure ChangeUpDownState(const Value: TUpDownState); overload;
  42.     procedure ChangeEnableState(const Value: TEnableState); overload;
  43.     procedure SetAllowAllUp(const Value: boolean);
  44.     procedure SetGroupIndex(const Value: integer);
  45.  
  46.     procedure ChangeShowEnabledUpImage(const Value: boolean);
  47.     procedure ChangeShowEnabledDownImage(const Value: boolean);
  48.     procedure ChangeShowEnabledUpText(const Value: boolean);
  49.     procedure ChangeShowEnabledDownText(const Value: boolean);
  50.  
  51.     procedure ChangeShowDisabledUpImage(const Value: boolean);
  52.     procedure ChangeShowDisabledDownImage(const Value: boolean);
  53.     procedure ChangeShowDisabledUpText(const Value: boolean);
  54.     procedure ChangeShowDisabledDownText(const Value: boolean);
  55.  
  56.     procedure Update;
  57.   public
  58.     constructor Create(AOwner: TComponent); override;
  59.     destructor  Destroy; override;
  60.  
  61.     procedure Click; override;
  62.     procedure ChangeUpDownState; overload;
  63.     procedure ChangeEnableState; overload;
  64.   protected
  65.     procedure SetName(const Value: TComponentName); override;
  66.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
  67.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
  68.     procedure DoMouseLeave; override;
  69.   published
  70.     property UpDownState: TUpDownState read FUpDownState write ChangeUpDownState;
  71.     property EnableState: TEnableState read FEnableState write ChangeEnableState;
  72.     property AllowAllUp: boolean read FAllowAllUp write SetAllowAllUp;
  73.     property GroupIndex: integer read FGroupIndex write SetGroupIndex;
  74.  
  75.     property EnabledUpImage: TImage read FEnabledUpImage;
  76.     property EnabledDownImage: TImage read FEnabledDownImage;
  77.     property EnabledUpText: TText read FEnabledUpText;
  78.     property EnabledDownText: TText read FEnabledDownText;
  79.  
  80.     property DisabledUpImage: TImage read FDisabledUpImage;
  81.     property DisabledDownImage: TImage read FDisabledDownImage;
  82.     property DisabledUpText: TText read FDisabledUpText;
  83.     property DisabledDownText: TText read FDisabledDownText;
  84.  
  85.     property ShowEnabledUpImage: boolean read FShowEnabledUpImage write ChangeShowEnabledUpImage;
  86.     property ShowEnabledDownImage: boolean read FShowEnabledDownImage write ChangeShowEnabledDownImage;
  87.     property ShowEnabledUpText: boolean read FShowEnabledUpText write ChangeShowEnabledUpText;
  88.     property ShowEnabledDownText: boolean read FShowEnabledDownText write ChangeShowEnabledDownText;
  89.  
  90.     property ShowDisabledUpImage: boolean read FShowDisabledUpImage write ChangeShowDisabledUpImage;
  91.     property ShowDisabledDownImage: boolean read FShowDisabledDownImage write ChangeShowDisabledDownImage;
  92.     property ShowDisabledUpText: boolean read FShowDisabledUpText write ChangeShowDisabledUpText;
  93.     property ShowDisabledDownText: boolean read FShowDisabledDownText write ChangeShowDisabledDownText;
  94.   end;
  95.  
  96. procedure Register;
  97.  
  98. implementation
  99.  
  100. procedure Register;
  101. begin
  102.   RegisterComponents('My FMX Components', [TImageButton]);
  103. end;
  104.  
  105. constructor TImageButton.Create(AOwner: TComponent);
  106. begin
  107.   inherited Create(AOwner);
  108.  
  109.   // default
  110.   HitTest      := true;
  111.   FUpDownState := udsUP;
  112.   fEnableState := esENABLED;
  113.   FAllowAllUp  := false;
  114.   FGroupIndex  := 0;
  115.   IsClicked    := false;
  116.  
  117.   FEnabledUpImage         := TImage.Create(Self);
  118.   FEnabledUpImage.Parent  := Self;
  119.   FEnabledUpImage.Name    := Self.Name + '_EnabledUpImage';
  120.   FEnabledUpImage.Align   := TAlignLayout.Center;
  121.   FEnabledUpImage.HitTest := false;
  122.   FEnabledUpImage.Locked  := true;
  123.   FEnabledUpImage.Stored  := false;
  124.   FEnabledUpImage.SetSubComponent(true);
  125.  
  126.   FEnabledDownImage         := TImage.Create(Self);
  127.   FEnabledDownImage.Parent  := Self;
  128.   FEnabledDownImage.Name    := Self.Name + '_EnabledDownImage';
  129.   FEnabledDownImage.Align   := TAlignLayout.Center;
  130.   FEnabledDownImage.HitTest := false;
  131.   FEnabledDownImage.Locked  := true;
  132.   FEnabledDownImage.Stored  := false;
  133.   FEnabledDownImage.SetSubComponent(true);
  134.  
  135.   FEnabledUpText         := TText.Create(Self);
  136.   FEnabledUpText.Parent  := Self;
  137.   FEnabledUpText.Name    := Self.Name + '_EnabledUpText';
  138.   FEnabledUpText.HitTest := false;
  139.   FEnabledUpText.Locked  := true;
  140.   FEnabledUpText.Stored  := false;
  141.   FEnabledUpText.SetSubComponent(true);
  142.  
  143.   FEnabledDownText         := TText.Create(Self);
  144.   FEnabledDownText.Parent  := Self;
  145.   FEnabledDownText.Name    := Self.Name + '_EnabledDownText';
  146.   FEnabledDownText.HitTest := false;
  147.   FEnabledDownText.Locked  := true;
  148.   FEnabledDownText.Stored  := false;
  149.   FEnabledDownText.SetSubComponent(true);
  150.  
  151.   FDisabledUpImage         := TImage.Create(Self);
  152.   FDisabledUpImage.Parent  := Self;
  153.   FDisabledUpImage.Name    := Self.Name + '_DisabledUpImage';
  154.   FDisabledUpImage.Align   := TAlignLayout.Center;
  155.   FDisabledUpImage.HitTest := false;
  156.   FDisabledUpImage.Locked  := true;
  157.   FDisabledUpImage.Stored  := false;
  158.   FDisabledUpImage.SetSubComponent(true);
  159.  
  160.   FDisabledDownImage         := TImage.Create(Self);
  161.   FDisabledDownImage.Parent  := Self;
  162.   FDisabledDownImage.Name    := Self.Name + '_DisabledDownImage';
  163.   FDisabledDownImage.Align   := TAlignLayout.Center;
  164.   FDisabledDownImage.HitTest := false;
  165.   FDisabledDownImage.Locked  := true;
  166.   FDisabledDownImage.Stored  := false;
  167.   FDisabledDownImage.SetSubComponent(true);
  168.  
  169.   FDisabledUpText         := TText.Create(Self);
  170.   FDisabledUpText.Parent  := Self;
  171.   FDisabledUpText.Name    := Self.Name + '_DisabledUpText';
  172.   FDisabledUpText.HitTest := false;
  173.   FDisabledUpText.Locked  := true;
  174.   FDisabledUpText.Visible := false;
  175.   FDisabledUpText.Stored  := false;
  176.   FDisabledUpText.SetSubComponent(true);
  177.  
  178.   FDisabledDownText         := TText.Create(Self);
  179.   FDisabledDownText.Parent  := Self;
  180.   FDisabledDownText.Name    := Self.Name + '_DisabledDownText';
  181.   FDisabledDownText.HitTest := false;
  182.   FDisabledDownText.Locked  := true;
  183.   FDisabledDownText.Visible := false;
  184.   FDisabledDownText.Stored  := false;
  185.   FDisabledDownText.SetSubComponent(true);
  186.  
  187.   FShowEnabledUpImage   := true;
  188.   FShowEnabledDownImage := true;
  189.   FShowEnabledUpText    := false;
  190.   FShowEnabledDownText  := false;
  191.  
  192.   FShowDisabledUpImage   := true;
  193.   FShowDisabledDownImage := true;
  194.   FShowDisabledUpText    := false;
  195.   FShowDisabledDownText  := false;
  196. end;
  197.  
  198. destructor TImageButton.Destroy;
  199. begin
  200.   if Assigned(FEnabledUpImage)   then FEnabledUpImage.Free;
  201.   if Assigned(FEnabledDownImage) then FEnabledDownImage.Free;
  202.   if Assigned(FEnabledUpText)    then FEnabledUpText.Free;
  203.   if Assigned(FEnabledDownText)  then FEnabledDownText.Free;
  204.  
  205.   if Assigned(FDisabledUpImage)   then FDisabledUpImage.Free;
  206.   if Assigned(FDisabledDownImage) then FDisabledDownImage.Free;
  207.   if Assigned(FDisabledUpText)    then FDisabledUpText.Free;
  208.   if Assigned(FDisabledDownText)  then FDisabledDownText.Free;
  209.  
  210.   inherited;
  211. end;
  212.  
  213. procedure TImageButton.SetName(const Value: TComponentName);
  214. begin
  215.   inherited SetName(Value);
  216.  
  217.   FEnabledUpImage.Name   := Value + '_EnabledUpImage';
  218.   FEnabledDownImage.Name := Value + '_EnabledDownImage';
  219.   FEnabledUpText.Name    := Value + '_EnabledUpText';
  220.   FEnabledDownText.Name  := Value + '_EnabledDownText';
  221.  
  222.   FDisabledUpImage.Name   := Value + '_DisabledUpImage';
  223.   FDisabledDownImage.Name := Value + '_DisabledDownImage';
  224.   FDisabledUpText.Name    := Value + '_DisabledUpText';
  225.   FDisabledDownText.Name  := Value + '_DisabledDownText';
  226. end;
  227.  
  228. procedure TImageButton.Click;
  229. begin
  230.   if IsClicked then inherited;
  231.   IsClicked := false;
  232. end;
  233.  
  234. procedure TImageButton.ChangeUpDownState;
  235. begin
  236.   case FUpDownState of
  237.     udsUP:   ChangeUpDownState(udsDOWN);
  238.     udsDOWN: ChangeUpDownState(udsUP);
  239.   end;
  240. end;
  241.  
  242. procedure TImageButton.ChangeEnableState;
  243. begin
  244.   case FEnableState of
  245.     esENABLED:  ChangeEnableState(esDISABLED);
  246.     esDISABLED: ChangeEnableState(esENABLED);
  247.   end;
  248. end;
  249.  
  250. procedure TImageButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  251. begin
  252.   if Button <> TMouseButton.mbLeft then exit;
  253.   if FEnableState = esDISABLED then exit;
  254.   if (FGroupIndex <> 0) and (FUpDownState = udsDOWN) and not FAllowAllUp then exit;
  255.  
  256.   IsClicked := true;
  257.   ChangeUpDownState;
  258.   Click;
  259.  
  260.   inherited;
  261. end;
  262.  
  263. procedure TImageButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  264. begin
  265.   if (FGroupIndex = 0) and (FUpDownState = udsDOWN) then ChangeUpDownState;
  266.  
  267.   inherited;
  268. end;
  269.  
  270. procedure TImageButton.DoMouseLeave;
  271. begin
  272.   if (FGroupIndex = 0) and (FUpDownState = udsDOWN) then ChangeUpDownState;
  273.  
  274.   inherited;
  275. end;
  276.  
  277. procedure TImageButton.ChangeUpDownState(const Value: TUpDownState);
  278. var
  279.   i: integer;
  280.   b: boolean;
  281. begin
  282.   if FUpDownState = Value then exit;
  283.  
  284.   // pokud jsem jediný down tak nelze jít na up
  285.   if (FGroupIndex <> 0) and not FAllowAllUp and (Value = udsUP) then
  286.   begin
  287.     b := true;
  288.     for i := 0 to Parent.ChildrenCount - 1 do
  289.       if Parent.Children[i] is TImageButton then
  290.         if TImageButton(Parent.Children[i]) <> Self then
  291.           if TImageButton(Parent.Children[i]).GroupIndex = FGroupIndex then
  292.             if TImageButton(Parent.Children[i]).UpDownState = udsDOWN then
  293.             begin
  294.               b := false;
  295.               break;
  296.             end;
  297.     if b then exit;
  298.   end;
  299.  
  300.   FUpDownState := Value;
  301.  
  302.   // změna stavu u zbylých tlačítek v groupě
  303.   if (FGroupIndex <> 0) and (FUpDownState = udsDOWN) then
  304.     for i := 0 to Parent.ChildrenCount - 1 do
  305.       if Parent.Children[i] is TImageButton then
  306.         if TImageButton(Parent.Children[i]) <> Self then
  307.           if TImageButton(Parent.Children[i]).GroupIndex = FGroupIndex then
  308.             if TImageButton(Parent.Children[i]).UpDownState = udsDOWN then
  309.               TImageButton(Parent.Children[i]).ChangeUpDownState;
  310.  
  311.   Update;
  312. end;
  313.  
  314. procedure TImageButton.ChangeEnableState(const Value: TEnableState);
  315. begin
  316.   if FEnableState = Value then exit;
  317.  
  318.   FEnableState := Value;
  319.  
  320.   Update;
  321. end;
  322.  
  323. procedure TImageButton.SetAllowAllUp(const Value: boolean);
  324. var
  325.   i: integer;
  326. begin
  327.   if FAllowAllUp = Value then exit;
  328.   FAllowAllUp := Value;
  329.  
  330.   // změna AllowAllUp u všech tlačíte v groupě
  331.   if FGroupIndex <> 0 then
  332.     for i := 0 to Parent.ChildrenCount - 1 do
  333.       if Parent.Children[i] is TImageButton then
  334.         if TImageButton(Parent.Children[i]) <> Self then
  335.           TImageButton(Parent.Children[i]).SetAllowAllUp(FAllowAllUp);
  336.  
  337.   Update;
  338. end;
  339.  
  340. procedure TImageButton.SetGroupIndex(const Value: integer);
  341. var
  342.   i: integer;
  343. begin
  344.   if FGroupIndex = Value then exit;
  345.   FGroupIndex := Value;
  346.  
  347.   // změna AllowAllUp u všech tlačíte v groupě
  348.   if FGroupIndex <> 0 then
  349.     for i := 0 to Parent.ChildrenCount - 1 do
  350.       if Parent.Children[i] is TImageButton then
  351.         if TImageButton(Parent.Children[i]) <> Self then
  352.           TImageButton(Parent.Children[i]).SetAllowAllUp(FAllowAllUp);
  353.  
  354.   Update;
  355. end;
  356.  
  357. procedure TImageButton.ChangeShowEnabledUpImage(const Value: boolean);
  358. begin
  359.   if FShowEnabledUpImage = Value then exit;
  360.   FShowEnabledUpImage := Value;
  361.  
  362.   Update;
  363. end;
  364.  
  365. procedure TImageButton.ChangeShowEnabledDownImage(const Value: boolean);
  366. begin
  367.   if FShowEnabledDownImage = Value then exit;
  368.   FShowEnabledDownImage := Value;
  369.  
  370.   Update;
  371. end;
  372.  
  373. procedure TImageButton.ChangeShowEnabledUpText(const Value: boolean);
  374. begin
  375.   if FShowEnabledUpText = Value then exit;
  376.   FShowEnabledUpText := Value;
  377.  
  378.   Update;
  379. end;
  380.  
  381. procedure TImageButton.ChangeShowEnabledDownText(const Value: boolean);
  382. begin
  383.   if FShowEnabledDownText = Value then exit;
  384.   FShowEnabledDownText := Value;
  385.  
  386.   Update;
  387. end;
  388.  
  389. procedure TImageButton.ChangeShowDisabledUpImage(const Value: boolean);
  390. begin
  391.   if FShowDisabledUpImage = Value then exit;
  392.   FShowDisabledUpImage := Value;
  393.  
  394.   Update;
  395. end;
  396.  
  397. procedure TImageButton.ChangeShowDisabledDownImage(const Value: boolean);
  398. begin
  399.   if FShowDisabledDownImage = Value then exit;
  400.   FShowDisabledDownImage := Value;
  401.  
  402.   Update;
  403. end;
  404.  
  405. procedure TImageButton.ChangeShowDisabledUpText(const Value: boolean);
  406. begin
  407.   if FShowDisabledUpText = Value then exit;
  408.   FShowDisabledUpText := Value;
  409.  
  410.   Update;
  411. end;
  412.  
  413. procedure TImageButton.ChangeShowDisabledDownText(const Value: boolean);
  414. begin
  415.   if FShowDisabledDownText = Value then exit;
  416.   FShowDisabledDownText := Value;
  417.  
  418.   Update;
  419. end;
  420.  
  421. procedure TImageButton.Update;
  422. begin
  423.   case FEnableState of
  424.     esENABLED:
  425.       case FUpDownState of
  426.         udsUP: begin
  427.           FDisabledUpImage.Visible   := false;
  428.           FDisabledDownImage.Visible := false;
  429.           FDisabledUpText.Visible    := false;
  430.           FDisabledDownText.Visible  := false;
  431.  
  432.           FEnabledUpImage.Visible   := FShowEnabledUpImage;
  433.           FEnabledDownImage.Visible := false;
  434.           FEnabledUpText.Visible    := FShowEnabledUpText;
  435.           FEnabledDownText.Visible  := false;
  436.  
  437.           FEnabledUpImage.BringToFront;
  438.           FEnabledUpText.BringToFront;
  439.         end;
  440.         udsDOWN: begin
  441.           FDisabledUpImage.Visible   := false;
  442.           FDisabledDownImage.Visible := false;
  443.           FDisabledUpText.Visible    := false;
  444.           FDisabledDownText.Visible  := false;
  445.  
  446.           FEnabledUpImage.Visible   := false;
  447.           FEnabledDownImage.Visible := FShowEnabledDownImage;
  448.           FEnabledUpText.Visible    := false;
  449.           FEnabledDownText.Visible  := FShowEnabledDownText;
  450.  
  451.           FEnabledDownImage.BringToFront;
  452.           FEnabledDownText.BringToFront;
  453.         end;
  454.       end;
  455.     esDISABLED:
  456.       case FUpDownState of
  457.         udsUP: begin
  458.           FEnabledUpImage.Visible   := false;
  459.           FEnabledDownImage.Visible := false;
  460.           FEnabledUpText.Visible    := false;
  461.           FEnabledDownText.Visible  := false;
  462.  
  463.           FDisabledUpImage.Visible   := FShowDisabledUpImage;
  464.           FDisabledDownImage.Visible := false;
  465.           FDisabledUpText.Visible    := FShowDisabledUpText;
  466.           FDisabledDownText.Visible  := false;
  467.  
  468.           FDisabledUpImage.BringToFront;
  469.           FDisabledUpText.BringToFront;
  470.         end;
  471.         udsDOWN: begin
  472.           FEnabledUpImage.Visible   := false;
  473.           FEnabledDownImage.Visible := false;
  474.           FEnabledUpText.Visible    := false;
  475.           FEnabledDownText.Visible  := false;
  476.  
  477.           FDisabledUpImage.Visible   := false;
  478.           FDisabledDownImage.Visible := FShowDisabledDownImage;
  479.           FDisabledUpText.Visible    := false;
  480.           FDisabledDownText.Visible  := FShowDisabledDownText;
  481.  
  482.           FDisabledDownImage.BringToFront;
  483.           FDisabledDownText.BringToFront;
  484.         end;
  485.       end;
  486.   end;
  487.  
  488.   inherited;
  489. end;
  490.  
  491. end.
  492.  

Jedná se o TLayout, který má 4 TImage jako subkomponenty pro stavy 1) enabled up 2) enabled down 3) disabled up 4) disabled down. Jednodušeji kód už snad ani nejde napsat.

Co mě ale trochu mate je použití inherited u Click, MouseDown a MouseUp. Nemůže se to zároveň nějak blokovat v případě, že přijdou události click, down a up naráz?

Děkuji.

 

Offline raul

  • Hrdina
  • ****
  • Příspěvků: 365
  • Karma: 15
    • Verze Delphi: FPC :D
To co popisujes je dost podobne vyse zminenemu prikladu s js a samsungem. Co je to za tablet ? Dela to i jinde ?
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 234
  • Karma: 0
Je to průmyslový dotykový panel na principu kapacitní vrstvy. Od jiného výrobce máme podobný s odporovou vrstvou a ten to nedělá.

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 234
  • Karma: 0
Nejde nějak v Delphi nastavit, aby dotyk prstem bral jako kliknutí myši? Bohužel se u multi-touch displeje chová klik prstem jinak než klik myší. Potřeboval bych nějak nastavit, aby byl dotyk prstem stejný jako obyčejná myš... :(

Pokud si chcete sami otestovat:

1) umístěte na FMX formulář TSpeedButton tlačítko a TMemo
2) na eventy tlačítka pro Click, MouseDown, MouseUp dejte logování do TMemo
3) spusťte aplikaci a klikejte na tlačítko nejdříve myší a poté na dotykové obrazovce - eventy budou přicházet jinak.

Např. u dotykové obrazovky, když kliknete na tlačítko, tak nepřijde žádný event! Nerozumím tomu, proč klik prstem nevyvolá down event. Základní funkčnost je nefunkční. Třeba se to dá nějak vypnout / zapnout / změnit?

Pokud má někdo nějaký nápad, rád jej vyzkouším.

Děkuji.
 

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2732
  • Karma: 105
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině

Pokud má někdo nějaký nápad, rád jej vyzkouším.


A co ten OnTap?
Embarcadero MVP - Czech republic

Offline age.new

  • Plnoletý
  • ***
  • Příspěvků: 234
  • Karma: 0
OnTap trpí stejnými problémy:

1) když se provede prstem klik a hned uvolní, tak přijde před Down eventem
2) když se provede prstem klik a neuvolní, tak OnTap event nepřijde nikdy, ani po pohybu prstem nebo uvolnění

Asi to už někdo řešil zde: https://stackoverflow.com/questions/50465050/start-touch-and-finish-touch-event-delphi