Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-11-2008
pablopessoa pablopessoa is offline
Miembro
 
Registrado: May 2008
Ubicación: Argentina
Posts: 162
Poder: 10
pablopessoa Va por buen camino
crear efecto "deshacer" en editor grafico

hola! sigo haciendo mi editor grafico y me gustaria hacer un efecto tipo "deshacer" o "control + z" y que esto borre lo ultimo que se haya hecho.
se que deberia guardar siempre lo ultimo que se hizo para poder eliminarlo, pero no se como se podria hacer, podran iluminarme un poco?
Muchas Gracias!!
Responder Con Cita
  #2  
Antiguo 25-11-2008
[coso] coso is offline
Miembro Premium
 
Registrado: May 2008
Ubicación: Girona
Posts: 1.677
Poder: 0
coso Va por buen camino
Hola, podrias usar varios metodos:
- ir guardando todos los comandos ejecutados en una lista, y al pulsar deshacer, ir ejecutandolos todos desde el principio hasta el que desees (que tendria que ser el anterior)
- ir guardando las pantallas, y reponerlas al aplicar el deshacer
- ir guardando los 'anticomandos' (si un comando es linea de A a B, este seria linea de B a A con el color de fondo)

Te dejo un ejemplo de el segundo metodo, a ver si te sirve :

Código Delphi [-]
unit back;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Guarda;
    procedure Button1Click(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
    index : integer;
    deshacer : array [0..200] of TBitmap;

  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Guarda;
var
     i : integer;
begin
     label1.Caption := inttostr(index);

     if index = 200 - 1 then  // si hay mas de 200, 'movemos' todos para el principio, perdiendo la primera pantalla guardada
     for i := 1 to 200 - 2 do
     bitblt(deshacer[i-1].Canvas.Handle,0,0,deshacer[i-1].Width,deshacer[i-1].Height,deshacer[i].Canvas.Handle,0,0,SRCCOPY);

     bitblt(deshacer[index].Canvas.Handle,0,0,Width,Height,Canvas.Handle,0,0,SRCCOPY);

     if index < 200 - 1 then Inc(index);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
     i : integer;
begin
     Color := $220000;
     Label1.Font.Color := clWhite;
     Label1.Caption := '0';
     for i := 0 to 200 - 1 do
     begin
          deshacer[i] := TBitmap.Create;
          deshacer[i].Width  := ClientWidth;
          deshacer[i].Height := ClientHeight;
     end;

     index := 0;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
     i : integer;
begin
     for i := 200-1 downto 0 do
     deshacer[i].Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
     if index = 0 then exit;

     dec(index);

     bitblt(Canvas.Handle,0,0,ClientWidth,ClientHeight,deshacer[index].Canvas.Handle,0,0,SRCCOPY);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
     op : integer = 10;
     xo : integer = 0;
     yo : integer = 0;
begin
     Canvas.Pen.Color := random($FFFFFF);
     Canvas.MoveTo(xo,yo);
     Canvas.LineTo(x,y);

     op := op + 1;

     xo := X;
     yo := Y;

     if op > 10 then begin Guarda; op := 0; end;
end;

end.

es bastante tosco (no cambies el tamaño de la ventana, pues puede dar error, gasta mucha memoria y repinta otras ventanas). Espero que te sirva de idea
Archivos Adjuntos
Tipo de Archivo: zip deshacer.zip (159,4 KB, 13 visitas)

Última edición por coso fecha: 25-11-2008 a las 00:05:50.
Responder Con Cita
  #3  
Antiguo 25-11-2008
pablopessoa pablopessoa is offline
Miembro
 
Registrado: May 2008
Ubicación: Argentina
Posts: 162
Poder: 10
pablopessoa Va por buen camino
hola! pedazo de respuesta!! ,uchas gracias!!
el cliente no puede cambiar el tamaño de la ventana, lo tengo fijo, pero si pasa que el tamaño de la ventana se ajusta a la resolucion de pantalla, pero al sacar el tamaño con el metodo ClientWidth; supongo que no afectaria.
Muchas gracias lo voy a probar a ver si me sale bien :P
un saludo!!!
Responder Con Cita
  #4  
Antiguo 26-11-2008
pablopessoa pablopessoa is offline
Miembro
 
Registrado: May 2008
Ubicación: Argentina
Posts: 162
Poder: 10
pablopessoa Va por buen camino
hola coso, lamentablemente tengo que confesarte que no logro adaptar tu solucion a mi aplicacion, lo que pasa es que hay algunas diferencias que no se manejar, por ejemplo : yo trabajo sobre un timage no sobre el formulario en si, yo tengo la posibilidad de hacer circulos, cuadrados, lineas , etc por lo que yo tengo que guardar una ves que se termino de dibujar la figura ( OnMouseUp).
Sigo paso a paso la ejecucion y corre el proceso guardar todo bien, pero me parece que el canvas.handle del timage no guarda lo mismo que el canvas.handle del Form, y cuando apreto "deshacer" no me cambia el bitmap.
Si tenes ganas, te dejo el codigo que hice para que veas si la cagada me la mande yo (lo cual es un 200% probable jajaj ).
Pero de todas maneras te agradezco el tiempo y la respuesta que me diste

Última edición por pablopessoa fecha: 30-11-2008 a las 18:59:09.
Responder Con Cita
  #5  
Antiguo 26-11-2008
[coso] coso is offline
Miembro Premium
 
Registrado: May 2008
Ubicación: Girona
Posts: 1.677
Poder: 0
coso Va por buen camino
Cita:
pero me parece que el canvas.handle del timage no guarda lo mismo que el canvas.handle del Form
cierto, tendrias que usar el handle de TImage.Picture.Bitmap.Canvas. A la que tenga un momento miro el codigo

Última edición por coso fecha: 26-11-2008 a las 15:36:56.
Responder Con Cita
  #6  
Antiguo 26-11-2008
[coso] coso is offline
Miembro Premium
 
Registrado: May 2008
Ubicación: Girona
Posts: 1.677
Poder: 0
coso Va por buen camino
Por otra banda, no te iria mejor para esto un TPaintBox? (paleta System)
Responder Con Cita
  #7  
Antiguo 26-11-2008
[coso] coso is offline
Miembro Premium
 
Registrado: May 2008
Ubicación: Girona
Posts: 1.677
Poder: 0
coso Va por buen camino
hola de nuevo, te dejo el mismo codigo que puse adaptado a Timage : eso si, no estoy seguro que sea del todo correcto, tendrias que probar el saveto y el loadfrom para saber si realmente funciona, pues no se bien bien que relacion hay entre las clases timage, la tpicture y la tbitmap correspondiente.

Código Delphi [-]
procedure TForm1.Guarda;
var
     i : integer;
begin
     label1.Caption := inttostr(index);

     if index = 200 - 1 then  // si hay mas de 200, 'movemos' todos para el principio, perdiendo la primera pantalla guardada
     for i := 1 to 200 - 2 do
     bitblt(deshacer[i-1].Canvas.Handle,0,0,deshacer[i-1].Width,deshacer[i-1].Height,deshacer[i].Canvas.Handle,0,0,SRCCOPY);

     bitblt(deshacer[index].Canvas.Handle,0,0,Width,Height,Image1.Picture.Bitmap.Canvas.Handle,0,0,SRCCOPY);

     if index < 200 - 1 then Inc(index);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
     i : integer;
begin
     doublebuffered := true;
     Color := $220000;
     Label1.Font.Color := clWhite;
     Label1.Caption := '0';
     for i := 0 to 200 - 1 do
     begin
          deshacer[i] := TBitmap.Create;
          deshacer[i].Width  := ClientWidth;
          deshacer[i].Height := ClientHeight;
     end;

     index := 0;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
     i : integer;
begin
     for i := 200-1 downto 0 do
     deshacer[i].Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
     if index = 0 then exit;

     dec(index);

     bitblt(Image1.Canvas.Handle,0,0,ClientWidth,ClientHeight,deshacer[index].Canvas.Handle,0,0,SRCCOPY);
     Refresh;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
     op : integer = 10;
     xo : integer = 0;
     yo : integer = 0;
begin
     Image1.Canvas.Pen.Color := random($FFFFFF);
     Image1.Canvas.MoveTo(xo,yo);
     Image1.Canvas.LineTo(x,y);

     op := op + 1;

     xo := X;
     yo := Y;

     if op > 10 then begin Guarda; op := 0; end;
end;
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Como crear un efecto "Hollywood" como el de Photoshop kapullok_2006 Gráficos 0 22-11-2007 12:43:08
Como hacer para que Vista no reporte "No se pudo comprobar el editor" Firma digital fcios Windows 2 16-06-2007 05:52:49
Necesito llamar a métodos de clases "hija" desde su clase "padre" Flecha OOP 17 20-04-2007 01:03:53
Un editor COOL. Al recibir el foco se "ilumina" y viceversa... pascalutn2003 Varios 32 18-12-2006 04:01:31
Múltiples "Deshacer" en un editor de textos soul6301 Varios 1 05-06-2004 22:38:37


La franja horaria es GMT +2. Ahora son las 04:22:09.


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