Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Dividir formulario proporcionalmente (https://www.clubdelphi.com/foros/showthread.php?t=76688)

Toni 18-11-2011 09:28:17

Dividir formulario proporcionalmente
 
Hola,

Estoy realizando un formulario con varios TChart y algun TPanel y me me gustaria poder dividir el formulario en parte totalmente proporcionales, y que cuando se redimensione el formulario se redimensionen todas las partes del mismo.

Por ejemplo, un formulario que esta divido en 4 partes iguales y en cada parte tenga un TChart. La pregunta es, ¿se puede hacer esto con las propiedades tipicas de Aling? ¿hay que usar algun otro componente?

En otras ocaciones he realizado formularios que se redimensionan con TDBGrid y TPanel, y me ha bastado con los colocar las propiedades Aling correctamente. En este caso no consigo el resultado que deseo de proporcionalidad.

LoPiTaL 18-11-2011 12:48:24

Esto ya se ha tratado más de una vez en el foro. Busca antes de preguntar algo nuevo.
Estoy seguro que alguien te comentará que te leas la guía de estilo.

En cuanto a lo referente a tu pregunta, revísate este enlace:

http://www.clubdelphi.com/foros/showthread.php?t=66263

En concreto necesitarás usar estos dos métodos y poner la propiedad Align a alCustom.

function
CustomAlignInsertBefore( C1, C2: TControl): Boolean; override;
procedure
CustomAlignPosition(Control: TControl; var NewLeft, NewTop, NewWidth, NewHeight: Integer; var AlignRect: TRect; AlignInfo: TAlignInfo); override;

ambos sobreescritos en el formulario.

Un saludo,
LoPiTaL

Toni 18-11-2011 13:09:10

Cita:

Esto ya se ha tratado más de una vez en el foro. Busca antes de preguntar algo nuevo.
Estoy seguro que alguien te comentará que te leas la guía de estilo.
Te aseguro que lo primero que hago siempre es primero buscar en los foros, horas y horas. Pero no siempre es sencillo encontrar lo que buscas.

De todas formas gracias!

ecfisa 18-11-2011 15:38:35

Cita:

Por ejemplo, un formulario que esta divido en 4 partes iguales y en cada parte tenga un TChart. La pregunta es, ¿se puede hacer esto con las propiedades tipicas de Aling? ¿hay que usar algun otro componente?
Hola Toni.

Para este caso en especial, se me ocurrió algo aprovechando el evento OnCanResize del form.

Un ejemplo usando cuatro TPanels:
Código Delphi [-]
procedure TForm1.FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer;
  var Resize: Boolean);
var
  R: TRect;
  Ancho, Alto: Integer;
begin
  Ancho:= GetClientRect.Right div 2;
  Alto:= GetClientRect.Bottom div 2;
  with Panel1 do
  begin
    Height := Alto;
    Width  := Ancho;
  end;

  with Panel2 do
  begin
    Top    := Panel1.Top + Alto;
    Height := Alto;
    Width  := Ancho;
  end;

  with Panel3 do
  begin
    Left   := Ancho;
    Height := Alto;
    Width  := Ancho;
  end;

  with Panel4 do
  begin
   Top     := Panel1.Top + Alto;
   Left    := Ancho;
   Height  := Alto;
   Width   := Ancho;
  end;
end;
Los TChart podrías ubicarlos en cada TPanel con su propiedad Aligng = alClient. Espero te sirva o te dé alguna idea...

Un saludo :)

LoPiTaL 18-11-2011 16:12:47

Cita:

Empezado por Toni (Mensaje 418825)
Te aseguro que lo primero que hago siempre es primero buscar en los foros, horas y horas. Pero no siempre es sencillo encontrar lo que buscas.

Entonces disculpa, no he dicho nada.

Cita:

Empezado por ecfisa
aprovechando el evento OnCanResize del form.

No me parece el método más adecuado (aunque estoy seguro que también funciona), ya que el evento OnCanResize no está pensado para reposicionar objetos, sino para permitir que se redimensione el formulario a un nuevo tamaño o no. Además, no estoy seguro de si al arrancar la aplicación aparecerían correctamente los paneles sin añadir código en el FormCreate, ya que el Width, Height y tal se asignan antes de crear los componentes hijos, y ya una vez creados no se lanzará el OnCanResize debido a que el formulario no volverá a redimensionarse (ya se redimensionó antes).
Me parece el lugar más adecuado el OnCustomAlignInsertBefore y OnCustomAlignPosition, que son los eventos pensados para esto (no sé a partir de qué versión de Delphi están published, pero en todo caso, siempre puedes sobreescribir los métodos que comenté antes).

Un saludo,
LoPiTaL

ecfisa 18-11-2011 17:41:36

Cita:

Empezado por LoPiTaL (Mensaje 418838)
Además, no estoy seguro de si al arrancar la aplicación aparecerían correctamente los paneles sin añadir código en el FormCreate,

Hola.

Si, hay que darle valores iniciales a los paneles ya sea por código o situándolos visualmente. Pero como aclaré en mi mensaje "Para este caso en especial,...", el código no tiene pretenciones de ser una solución global sino una respuesta a un planteo concreto.
Es decir, funciona para cuatro panels que dividen el form exactamente en cuatro partes iguales distribuidas en forma de mosaico y se redimensionan acorde al tamaño del form. Que fué lo que interpreté que buscaba Toni.

Un saludo.

Edito: Para no dejarle a Toni una respuesta incompleta, el órden visual del ejemplo es:

Panel1 - Panel3
Panel2 - Panel4

O desde código:
Código Delphi [-]
...
begin
  Panel1.Top:= 1;
  Panel1.Left:= 1;
  Panel2.Top:= Panel1.Height;
  Panel2.Left:= 1;
  Panel3.Top:=  1;
  Panel3.Left:= Panel1.Width;
  Panel4.Top:= Panel1.Height; 
  Panel4.Left:= Panel1.Width;
end;

ecfisa 18-11-2011 19:56:55

Hola LoPiTaL.

Estuve probando otra vez con el método CustomAlignPosition (ya que antes no encontré como lograrlo :( ) y como muchas veces pasa, lo que no salía antes salió después... :)

Para 4 Panels(propiedad Align = alCustom) en mosaico, redimensionables:
Código Delphi [-]
procedure TForm1.CustomAlignPosition(Control: TControl; var NewLeft, NewTop, NewWidth, NewHeight: Integer; var AlignRect: TRect;
  AlignInfo: TAlignInfo);
begin
  inherited;
  NewWidth  := GetClientRect.Right div 2;
  NewHeight := GetClientRect.Bottom div 2;
  if Control = Panel1 then
  begin
    NewLeft := 1;
    NewTop  := 1;
  end;
  if Control = Panel2 then
  begin
    NewLeft := Panel1.Width;
    NewTop  := 1;
  end;
  if Control = Panel3 then
  begin
    NewLeft := 1;
    NewTop  := Panel1.Height;
  end;
  if Control = Panel4 then
  begin
    NewLeft := Panel1.Width;
    NewTop  := Panel1.Height;
  end;
end;

Saludos.

Toni 18-11-2011 20:40:43

OK, muchas gracias a los dos. Las dos soluciones funcionan perfectamente.

LoPiTaL 18-11-2011 20:49:50

Cita:

Estuve probando otra vez con el método CustomAlignPosition
jajaj! Te dejé con la intriga ehh?? :D

Sólo apuntar un detalle más a tu solución (que funciona perfectamente):
Así hay que vigilar el orden de creación de los componentes. Ya que por lo general se crean en este orden Panel1, Panel2, Panel3, Panel4, entonces el método directamente es correcto.
PERO si quisieses poner el Panel2 primero (por el motivo que sea), entonces necesitarías sobreescribir el otro método, OnCustomAlignInsertBefore, para poder indicar, cuando salga la pareja PanelX - Panel2, que quieres que alinee primero el panel2, ya que si no, las instrucciones:

Código Delphi [-]
    NewLeft := Panel2.Width;  //Sustituido Panel1 por Panel2
    NewTop  := Panel2.Height;

no funcionarán, ya que cuando alinea Panel1, Panel2 todavía no tiene el Width y Height que tocan.

Y respondiendo a la pregunta que os estáis haciendo: sí, me ha tocado pelearme muuuuuuuuuchhooooo con estos dos métodos... :p:p

Un saludo,
LoPiTaL

ecfisa 18-11-2011 21:01:54

Cita:

Empezado por LoPiTaL (Mensaje 418856)
Y respondiendo a la pregunta que os estáis haciendo: sí, me ha tocado pelearme muuuuuuuuuchhooooo con estos dos métodos... :p:p

Es que generalmente es proporcional: tanto más uno se rompe el coco con un problema, tanto más aprende la mejor forma de solucionarlo... ;)

Un saludo. :)

Toni 18-11-2011 21:17:49

Pues la complicacion no acaba ahi.....este formulario no solo se divide en 4, sino que tiene un TabControl con varios Tabs y estos Tabs se dividen en cuatro (no todos). Pero bueno es mas de lo mismo.

Lo que si que quiero es implementar que al redimensionar el formulario lo haga de forma proporcional, para que las graficas que hay en cada division no se vean feas y mal formadas. A trabajar un poco mas....y el problema es que contra reloj.

Gracias por la ayuda!

Chris 18-11-2011 22:34:14

No sé desde que versión de Delphi está disponible, pero hay un exelente control para este menester. El TGridPanel. Si tienes alguna de las más recientes versiones de Delphi puedes probarlo a ver si lo tienes.

Saludos,
Chris


La franja horaria es GMT +2. Ahora son las 14:05:23.

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