Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Always show options dropdown in TValueListEditor

I'm trying to improve a GUI by reducing the amount of clicks needed to perform some actions. However, one VCL component that's bothering me is a TValueListEditor which contains a list of keys and values, all controlled by dropdowns. Selecting an options always requires three clicks, when only two are needed:

Bad

At this point in time, the topmost row has focus, and the value can be changed by using the dropdown (two clicks). However, when the user wants to edit a different key, he first has to change focus to that key before he can use the dropdown (three clicks).

Is there any way to show the dropdown arrow on all rows to prevent that extra click?

Here's a mockup example of what I want to achieve:

Good

like image 269
Orwell Avatar asked Oct 21 '12 10:10

Orwell


People also ask

How to show all the options from a dropdown list in JavaScript?

To show all the options from a dropdown list, use the options property. The property allows you to get all the options with length property. You can try to run the following code to get all the options from a drop-down list.

Is there a way to select all data sources in dropdown menu?

Unless 'All' is an option in the data sources that populate your dropdowns, you will have to do it a different way. I just did something similar last week in an app I am working on. What I did was to add a checkbox under my dropdown with the option to select 'All'.

How do I show customized information in a drop down list?

For example, let’s say your Drop Down cell is Cell A9 and you want to give “customized” information in Cell A10. You can insert a Macro or Formula (depending on the number of options in your Drop Down tab) in Cell A10 to check A9 content and then show the right information in Cell A10.

What are the disadvantages of drop down list validation in Excel?

The biggest drawback of this technique is that the cell to the right of the validation list cell must be blank, and also be about 18 pixels wide. If your drop-down validation lists are in an Excel Table, then you will have to insert a blank column.


1 Answers

uses
  Vcl.Themes;

type
  TValueListEditor = class(Vcl.ValEdit.TValueListEditor)
  private
    procedure DrawDropDownButton(ACol, ARow: Integer; ARect: TRect;
      AState: TGridDrawState);
    function MouseOverButton(X: Integer): Boolean;
  protected
    procedure DrawCell(ACol, ARow: Integer; ARect: TRect;
      AState: TGridDrawState); override;
    procedure DrawCellHighlight(const ARect: TRect; AState: TGridDrawState;
      ACol, ARow: Integer); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
      Y: Integer); override;
  end;

{ TValueListEditor }

type
  TInplaceEditListAccess = class(Vcl.Grids.TInplaceEditList);

procedure TValueListEditor.DrawCell(ACol, ARow: Integer; ARect: TRect;
  AState: TGridDrawState);
begin
  inherited DrawCell(ACol, ARow, ARect, AState);
  DrawDropDownButton(ACol, ARow, ARect, AState);
end;

procedure TValueListEditor.DrawCellHighlight(const ARect: TRect;
  AState: TGridDrawState; ACol, ARow: Integer);
var
  R: TRect;
begin
  R := ARect;
  if ItemProps[ARow - FixedRows].HasPickList then
    Dec(R.Right, EditList.ButtonWidth);
  inherited DrawCellHighLight(R, AState, ACol, ARow);
  DrawDropDownButton(ACol, ARow, ARect, AState);
end;

procedure TValueListEditor.DrawDropDownButton(ACol, ARow: Integer;
  ARect: TRect; AState: TGridDrawState);
var
  Details: TThemedElementDetails;
begin
  if (ACol = 1) and (ARow >= FixedRows) and not (gdFocused in AState) and
    ItemProps[ARow - FixedRows].HasPickList then
  begin
    ARect.Left := ARect.Right - EditList.ButtonWidth;
    Details := StyleServices.GetElementDetails(tgDropDownButtonNormal);
    StyleServices.DrawElement(Canvas.Handle, Details, ARect);
  end;
end;

procedure TValueListEditor.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var
  ACol: Integer;
  ARow: Integer;
begin
  inherited MouseDown(Button, Shift, X, Y);
  MouseToCell(X, Y, ACol, ARow);
  if (Button = mbLeft) and (ARow > FixedRows) and
    ItemProps[ARow - FixedRows].HasPickList and
    not EditList.ListVisible and MouseOverButton(X) then
  begin
    EditorMode := True;
    TInplaceEditListAccess(EditList).DropDown;
  end;
end;

function TValueListEditor.MouseOverButton(X: Integer): Boolean;
begin
  Result := (UseRightToLeftAlignment and (X < EditList.ButtonWidth)) or
    (not UseRightToLeftAlignment and (X > ClientWidth - EditList.ButtonWidth));
end;

enter image description here

like image 63
NGLN Avatar answered Sep 21 '22 01:09

NGLN