Jump to content

Gustav Schubert

Members
  • Content Count

    60
  • Joined

  • Last visited

  • Days Won

    1

Gustav Schubert last won the day on December 11 2019

Gustav Schubert had the most liked content!

Community Reputation

15 Good

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    No need to report the right mouse button bug, it exists already. RSP-28235 But I think I have the solution: procedure TListBoxSelector.MouseSelectFinish(const Item: TListBoxItem; const Button: TMouseButton; const Shift: TShiftState); begin if Button <> TMouseButton.mbLeft then begin DoMouseSelectStart(Item, Shift); end; DoMouseSelectFinish(Item, Shift); end;
  2. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    Best practice recommendations: For simple case of ListBox with 4 Items, only one of which should be selectable, do this: a) use OnItemClick, not OnClick b) use TMultiSelectStyle.Default, not TMultiSelectStyle.None (the default) c) do not use the right mouse button to select items d) use TListView if you can My new minimal example - which monitors ItemIndex - shows that the right mouse button can change ItemIndex, so that it becomes out of sync with the selection. unit FrmMain; interface uses System.SysUtils, System.Classes, FMX.Controls.Presentation, FMX.Forms, FMX.Graphics, FMX.ListBox, FMX.StdCtrls, FMX.Objects, FMX.Layouts, FMX.Types, FMX.Controls; type TForm1 = class(TForm) ListBox1: TListBox; Text1: TText; NoneBtn: TSpeedButton; DefaultBtn: TSpeedButton; ExtendedBtn: TSpeedButton; procedure FormCreate(Sender: TObject); procedure ListBox1ItemClick(const Sender: TCustomListBox; const Item: TListBoxItem); procedure NoneBtnClick(Sender: TObject); procedure DefaultBtnClick(Sender: TObject); procedure ExtendedBtnClick(Sender: TObject); private procedure DoOnIdle(Sender: TObject; var Done: Boolean); end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.NoneBtnClick(Sender: TObject); begin ListBox1.MultiSelectStyle := TMultiSelectStyle.None; end; procedure TForm1.DefaultBtnClick(Sender: TObject); begin ListBox1.MultiSelectStyle := TMultiSelectStyle.Default; end; procedure TForm1.ExtendedBtnClick(Sender: TObject); begin ListBox1.MultiSelectStyle := TMultiSelectStyle.Extended; end; procedure TForm1.FormCreate(Sender: TObject); var gn: string; ML: TStrings; begin ReportMemoryLeaksOnShutdown := True; ML := ListBox1.Items; ML.Add('Item 0'); ML.Add('Item 1'); ML.Add('Item 2'); ML.Add('Item 3'); ListBox1.MultiSelectStyle := TMultiSelectStyle.Default; ListBox1.OnItemClick := ListBox1ItemClick; NoneBtn.StaysPressed := True; DefaultBtn.StaysPressed := True; ExtendedBtn.StaysPressed := True; NoneBtn.IsPressed := ListBox1.MultiSelectStyle = TMultiSelectStyle.None; DefaultBtn.IsPressed := ListBox1.MultiSelectStyle = TMultiSelectStyle.Default; ExtendedBtn.IsPressed := ListBox1.MultiSelectStyle = TMultiSelectStyle.Extended; gn := 'MultiSelectEnum'; NoneBtn.GroupName := gn; DefaultBtn.GroupName := gn; ExtendedBtn.GroupName := gn; Application.OnIdle := DoOnIdle; end; procedure TForm1.ListBox1ItemClick(const Sender: TCustomListBox; const Item: TListBoxItem); begin Caption := IntToStr(Item.Index); end; procedure TForm1.DoOnIdle(Sender: TObject; var Done: Boolean); begin Text1.Text := IntToStr(ListBox1.ItemIndex); Done := True; end; end. ( Using a class helper for TListBoxSelector.MouseSelectFinish is not possible. )
  3. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    ClearSelection; Now only one item will be shown as selected at any time, But FCurrent alias ItemIndex can still be changed with right mouse button click on another item, without beeing reflected by the visual selection. Which should be dealt with in MouseSelectFinish? procedure TRggSelectionController.MouseSelectFinish(const Item: TListBoxItem; const Button: TMouseButton; const Shift: TShiftState); begin { added test for button } if Button <> TMouseButton.mbLeft then Exit; inherited; end;
  4. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    Since I have 'played' with TSingleSelectionController a bit, I want to disclose a Feature! With TMultiSelectStye.None (the default for TListBox), it is still possible to select more then one Item, albeit with the illegal help of the right mouse button. This is because the right mouse button will set FCurrent, wich will then derail the proper deselection of the previously selected item - when you left click on another item, which is not the selected and not the current. In other words, the Selected Item and the Current Item may get out of sync when the user is trying something wierd with left and right mouse buttons. Note: On the touch screen, a long tap maps to right mouse button. { Playing with 4 Items: 1) Click Item 1 with left mouse button. Item 1 becomes selected FCurrent := 1 2) Click Item 3 with right mouse button Item 1 still selected Item 3 not selected FCurrent := 3 3) Click Item 2 with left mouse button FCurrent = 3 (still, when DoMouseSelectStart is called) Item 3 will be deselected (but it was not selected, no change) Item 2 becomes selected as well Item 1 still selected FCurrent := 2 ( after click) } procedure TSingleSelectionController.DoMouseSelectStart(const Item: TListBoxItem; const Shift: TShiftState); begin if (FUserSetIndex = -1) and (Item.Index <> FCurrent) then begin { will deselect current } SetSelected(GetCurrentItem, False); // <-- depends on FCurrent being 'correct' if SetCurrent(Item.Index) then Item.SetIsSelectedInternal(True, False); end; end;
  5. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    OK, OnItemClick is much better, got it - only now. Perhaps OnClick should be deprecated? https://stackoverflow.com/questions/48813666/firemonkey-tlistbox-onclick-which-item-is-clicked https://stackoverflow.com/questions/19822639/translating-onclick-to-ontouch-or-something-similiar
  6. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    I can register my own TListBoxSelector derived class and then create a TListBox at runtime, which uses the custom TListBoxSelector, but the classes to inherit from are all private, defined in implementation section of FMX.ListBox.Selection. I did it anyway, just to test out if it works. procedure TRggSelectionController.MouseSelectStart(const Item: TListBoxItem; const Button: TMouseButton; const Shift: TShiftState); begin if Button <> TMouseButton.mbLeft then Exit; // if (FListBox.AniCalculations.TouchTracking <> []) and (Item.Index <> FCurrent) then // DelayedMouseDown(Item, Shift) // else DoMouseSelectStart(Item, Shift); end; { in FormCreate: } TListBoxSelectorFactory.RegisterSelector(TMultiSelectStyle.None, TRggSelectionController); ListBox.Free; ListBox := TListBox.Create(Self); ListBox.Parent := Self; ListBox.Position.Y := 100; ListBox.Position.Y := 200; ListBox.OnClick := ListBoxClick; I am using the Listbox in a desktop application, and when I am navigating the items with the arrow keys, I do not want to do anything immediately. Only when the user clicks, or presses the space character, should an action be triggered. That is why I tried with OnClick instead of OnChange. OnChange is working, but it is called before OnClick, so I cannot just set a flag in OnClick, to be evaluated in OnChange, that does not work. Best workaround still to be determined.
  7. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    Just found out that it is an already Open issue: RSP-19266 You can create a test environment for the issue on the desktop which should be good enough to investigate, by changing one line in the implementation section, in a copy of unit FMX.ListBox. procedure TListBoxSelector.MouseSelectStart(const Item: TListBoxItem; const Button: TMouseButton; const Shift: TShiftState); begin if Button <> TMouseButton.mbLeft then Exit; // if (FListBox.AniCalculations.TouchTracking <> []) and (Item.Index <> FCurrent) then if (Item.Index <> FCurrent) then DelayedMouseDown(Item, Shift) else DoMouseSelectStart(Item, Shift); end;
  8. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    I used PAServer and 64 Bit remote debugging - for the first time - to find out more, with two breakpoints: 1) One breakpoint in OnClick handler. 2) Another breakpoint in TListBoxSelector.SetCurrent. I got different call stacks between Desktop and Tablet. On the tablet computer the OnClick handler is called before the first call to SetCurrent. And this is the very problem! It is of course important that TListBoxSelector.FCurrent be set to the correct value before my OnClick handler is called. /// <summary>Timer used for DelayedMouseDown</summary> FSelectionTimer: TTimer; function TListBoxSelector.SetCurrent(const Index: Integer): Boolean; begin Result := FCurrent <> Index; FCurrent := Index; // <-- ItemIndex end; procedure TListBoxSelector.MouseSelectStart(const Item: TListBoxItem; const Button: TMouseButton; const Shift: TShiftState); begin if Button <> TMouseButton.mbLeft then Exit; if (FListBox.AniCalculations.TouchTracking <> []) and (Item.Index <> FCurrent) then DelayedMouseDown(Item, Shift) // <-- Surface tablet else DoMouseSelectStart(Item, Shift); // <-- Desktop end; procedure TListBoxSelector.DelayedMouseDown(const ItemDown: TListBoxItem; const Shift: TShiftState); begin if FSelectionTimer = nil then FSelectionTimer := TSelectionTimer.CreateTimer(Self); TSelectionTimer(FSelectionTimer).Reload(ItemDown, Shift); end; Now I am confident that some of you will be able to reproduce.
  9. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    Update - the problem is reproducible on my Surface tablet with scaling 2.0, but not - as I have just learned - on my Retina iMac with the same scaling, in the bootcamp partition. Surprise.
  10. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    No solution so far, just the test project which will show the issue. Whether OnClick 'works' depends on where you test. On my Surface tablet it it does not work. ItemIndex will be the previously clicked item, not the item you just clicked on. And the first time you click, the handler will not be called at all. Latest: I verified that OnChange works as expected, and I looked up the specific model info of the problem device: procedure TFormMain.ListBoxChange(Sender: TObject); begin { works as expected } // HandleClick(Listbox.ItemIndex); end; procedure TFormMain.ListBoxClick(Sender: TObject); begin { does not work on Surface Pro (5. Gen), Modell 1796 m3 } HandleClick(Listbox.ItemIndex); end; procedure TFormMain.HandleClick(ii: Integer); begin if ii > -1 then begin Inc(Counter); Caption := ListBox.Items[ii] + ' - ' + IntToStr(Counter); end; end;
  11. Gustav Schubert

    TListBox OnClick not working just on some machines ?

    unit FrmMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Layouts, FMX.ListBox, FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base, FMX.ListView; type TFormMain = class(TForm) ListBox: TListBox; ListView: TListView; procedure FormCreate(Sender: TObject); procedure ListBoxClick(Sender: TObject); procedure ListBoxKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); procedure ListViewItemClick(const Sender: TObject; const AItem: TListViewItem); procedure FormDestroy(Sender: TObject); private Counter: Integer; ML: TStrings; end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); var i: Integer; li: TListViewItem; begin ReportMemoryLeaksOnShutdown := True; ML := TStringList.Create; ML.Add('Item 0'); ML.Add('Item 1'); ML.Add('Item 2'); ML.Add('Item 3'); Listbox.Items := ML; ListView.ItemAppearanceName := 'ListItem'; ListView.ItemAppearance.ItemHeight := 24; ListView.ItemAppearanceObjects.ItemObjects.Accessory.Visible := False; ListView.ItemAppearanceObjects.ItemObjects.Text.Font.Family := 'Consolas'; ListView.ItemAppearanceObjects.ItemObjects.Text.Font.Size := 16; ListView.ItemAppearanceObjects.ItemObjects.Text.TextColor := TAlphaColors.Dodgerblue; ListView.ItemAppearanceObjects.HeaderObjects.Text.Visible := False; ListView.ItemAppearanceObjects.FooterObjects.Text.Visible := False; ListView.OnItemClick := ListViewItemClick; for i := 0 to ML.Count-1 do begin li := ListView.Items.Add; li.Text := ML[i]; end; end; procedure TFormMain.FormDestroy(Sender: TObject); begin ML.Free; end; procedure TFormMain.ListViewItemClick(const Sender: TObject; const AItem: TListViewItem); var ii: Integer; begin ii := AItem.Index; if ii > -1 then begin Inc(Counter); Caption := ML[ii] + ' - ' + IntToStr(Counter); end; end; procedure TFormMain.ListBoxClick(Sender: TObject); var ii: Integer; begin if ListBox.Selected = nil then begin Inc(Counter); Exit; end; ii := ListBox.ItemIndex; if ii > -1 then begin Inc(Counter); Caption := ML[ii] + ' - ' + IntToStr(Counter); end; end; procedure TFormMain.ListBoxKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); begin if KeyChar = ' ' then ListBoxClick(nil); end; end.
  12. I have a strange problem with FMX TListbox and the OnClick handler, but apparrently only on my Surface tablet. Cannot reproduce on another machine. Initially I thought it was a strange HDPI related issue, now I think it may be 'just' a driver issue. The first comment contains the test program. It would be interesting if someone can reproduce. Details in comments below. I'm sorry if this turns out to be noise. Symptoms: If I click on a ListBox item then ItemIndex in ListboxClick is wrong, it contains the index of the previously clicked item.
  13. Works for me! Except for two minor observations: a) in Winapi.D2DMissing there are references to some enum values (const) which are not available in my Rio installation, but those can be looked up on the Internet. const D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR = 0; //D2D1_INTERPOLATION_MODE_DEFINITION_NEAREST_NEIGHBOR; ... b) GrayScale can be set only once, thereafter it fails with EOSError, Code 87, Wrong Parameter?
  14. Gustav Schubert

    About missing property TComboBox.Text

    It can be confusing, so I double-checked: ComboBox.Clear does not trigger OnChange ComboBox.Items.Clear will trigger OnChange (with Selected = nil) It is after calling ComboBox.Clear that you can observe the first-attempt-anomaly. Assigning to Items will involve Items.Clear, and the Selected = nil problem, which the feature request is aiming to deal with in a better way. The fact that OnChange is not called after Combo.Clear may be a problem for the logic of your program. But that does not invalidate the feature request. The attached form contains the updated test code. FrmMain.zip
  15. Gustav Schubert

    About missing property TComboBox.Text

    The Problem (ComboBox.Selected = nil in OnChange) does not happen the first time you swap the content of Items. It is happening from the second time onwards. Can be shown easily with another test button that calls ComboBox1.Clear. This will reset the test cycle. TComboBoxHelper works as expected and is 3rd best option for me. Second best option in my ranking is to inherit from TComboBox, preferred because I do create all components at runtime. Best option so far and by far is of course to add the property directly. No one came out with the idea for 8 years or so. And then it took me two days (too long) after running into the problem, before I refactored and used my own combobox - a little success story. So this is why I made an exception to the rule and went on record with a feature request for something otherwise very simple. We are now up to two votes. A big number for me, a small step for Delphi. Thanks to Emba for opening the 'new feature' request. Let's see how it goes. 👈
×