Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Bloquear reordenamiento de ciertos items en componente TButtonGroup (https://www.clubdelphi.com/foros/showthread.php?t=88951)

osmeg 01-09-2015 17:03:11

Bloquear reordenamiento de ciertos items en componente TButtonGroup
 
Buenos días amigos de ClubDelphi,

Hoy les traigo una inquietud, quizá alguien me pueda colaborar. Estoy utilizando el componente TButtonGroup y a este componente le agregó varios items (de tipo TGrpButtonItem) dinámicamente. Algunos de los items del componente los considero "especiales" y al ser considerados como tal quiero que cuando el usuario intente involucrarlos en el proceso de reordenamiento el programa lo impida y deje el orden de los items tal cual se encontraba inicialmente.

En pocas palabras, cuando el usuario intente reordenar alguno de estos items especiales, el evento OnReorderButton no se ejecutará. Sólo será ejecutado para los items que no se consideran especiales.

¿Existe alguna manera de implementar este comportamiento con este componente?

Gracias por su atención.

AgustinOrtu 01-09-2015 18:10:53

Hola osmeg

Proba de la siguiente manera:

Código Delphi [-]
procedure TForm1.ButtonGroup1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if ButtonGroup1.IndexOfButtonAt(X, Y) in [0, 1] then
    ButtonGroup1.ButtonOptions := ButtonGroup1.ButtonOptions - [gboAllowReorder]
  else
    ButtonGroup1.ButtonOptions := ButtonGroup1.ButtonOptions + [gboAllowReorder]
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ButtonGroup1.Items.Add.Caption := 'Primero';
  ButtonGroup1.Items.Add.Caption := 'Segundo';
  ButtonGroup1.Items.Add.Caption := 'Tercero';
  ButtonGroup1.ButtonOptions := ButtonGroup1.ButtonOptions + [gboAllowReorder];
end;

De esa manera no podrias reordenar el "primero" ni el "segundo"

Una extension de lo anterior que se asemeja mas a lo que buscas (creo)

Código Delphi [-]
function IsSpecialButton(AButton: TGrpButtonItem): Boolean;
begin
  // tu codigo
  Result := True;
end;

procedure TForm1.ButtonGroup1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  LIndex: Integer;
  LButton: TGrpButtonItem;
begin
  LIndex := ButtonGroup1.IndexOfButtonAt(X, Y);
  LButton := ButtonGroup1.Items[LIndex];
  if LButton = NIL then
    Exit;

  if IsSpecialButton(LButton) then
    ButtonGroup1.ButtonOptions := ButtonGroup1.ButtonOptions - [gboAllowReorder]
  else
    ButtonGroup1.ButtonOptions := ButtonGroup1.ButtonOptions + [gboAllowReorder]
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ButtonGroup1.Items.Add.Caption := 'Primero';
  ButtonGroup1.Items.Add.Caption := 'Segundo';
  ButtonGroup1.Items.Add.Caption := 'Tercero';
  ButtonGroup1.ButtonOptions := ButtonGroup1.ButtonOptions + [gboAllowReorder];
end;

osmeg 01-09-2015 21:35:55

Hola AgustinOrtu. Gracias por tu aporte.

Con la implementación indicada se soluciona parcialmente el problema. Ahora faltaría buscar la forma de restringir el reordenamiento si un item "no especial" se superpone sobre uno "especial". Este caso no se tiene en cuenta con el evento OnMouseDown dado. ¿Será posible utilizar el evento OnReorderButton para evitar este comportamiento?

Gracias por su atención y colaboración.

AgustinOrtu 01-09-2015 22:21:24

Habria que ver, el OnReorderButton se dispara despues de alterar el orden


Código Delphi [-]
procedure TButtonGroup.DoReorderButton(const OldIndex, NewIndex: Integer);
var
  OldIndexID: Integer;
begin
  FIgnoreUpdate := True;
  try
    if FItemIndex <> -1 then
      OldIndexID := Items[FItemIndex].ID
    else
      OldIndexID := -1;
    FButtonItems.Items[OldIndex].Index := NewIndex;
    if OldIndexID <> -1 then
      FItemIndex := Items.FindItemID(OldIndexID).Index;
  finally
    FIgnoreUpdate := False;
  end;
  if HandleAllocated then
    RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW);
  if Assigned(FOnReorderButton) then
    FOnReorderButton(Self, OldIndex, NewIndex);
end;

AgustinOrtu 01-09-2015 22:33:09

La unica forma que se me ocurrio es esta :)

Código Delphi [-]
procedure TForm1.ButtonGroup1ReorderButton(Sender: TObject; OldIndex,
  NewIndex: Integer);
var
  Old, New: TGrpButtonItem;
begin
  if NewIndex = 1 then
  begin
    ButtonGroup1.Items.BeginUpdate;
    try
      Old := ButtonGroup1.Items[OldIndex];
      New := ButtonGroup1.Items[NewIndex];
      Old.Index := NewIndex;
      New.Index := OldIndex;
    finally
      ButtonGroup1.Items.EndUpdate;
    end;
  end;
end;

Aunque desconozco que pasaria con muchos botones. Basicamente se esta pintando el control dos veces

Sino lo suyo es heredar de TButtonGroup y reescribir DoReorderButton

osmeg 02-09-2015 18:42:37

Hola AgustinOrtu,

Gracias por tu aporte. Revisaré la alternativa que me das y te comento.


La franja horaria es GMT +2. Ahora son las 07:15:05.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi