Hi,
finally I've got a working example, that does what I want. It gave me a hard time, since I'm quite new to FPC/Lazarus, so there have been other issues that adressed other topics.
Nevertheless:
Here's what I have now. This works quite fine for me, though I guess an experience programmer would solve it differntly.
What do I have:
- I can draw my rects on the "canvas". The original image is not changed, as it is demanded.
- I store the rects in a TObjectList. So I can select/move/delete them (not implemented yet).
I'd like to thank you all for your suggestions and help. Thank you!
unit MainForm;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
ExtCtrls, ExtDlgs, BGRAGraphicControl, BGRABitmap, contnrs;
type
{ ThwndMain }
ThwndMain = class(TForm)
DrawingArea: TBGRAGraphicControl;
openImageDlg: TOpenPictureDialog;
panelList: TListView;
tb2ImageList: TImageList;
LeftPanel: TPanel;
DrawingScrollbox: TScrollBox;
tbImageList: TImageList;
ToolBar1: TToolBar;
tbbNew: TToolButton;
tbbOpen: TToolButton;
tbbSave: TToolButton;
tbbSep1: TToolButton;
tbbLoadImage: TToolButton;
tbbSep2: TToolButton;
tbbExport: TToolButton;
panelBar: TToolBar;
ToolButton1: TToolButton;
tbbHelp: TToolButton;
tbbMoveUp: TToolButton;
tbbMoveDown: TToolButton;
tbbDelete: TToolButton;
tbbSep3: TToolButton;
tbbAddSound: TToolButton;
tbbRemoveSound: TToolButton;
procedure DrawingAreaMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure DrawingAreaMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: integer);
procedure DrawingAreaMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure DrawingAreaPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure tbbLoadImageClick(Sender: TObject);
procedure DrawAction(x: integer; y: integer);
procedure DrawAllRects();
private
{ private declarations }
public
{ public declarations }
end;
TmyRect = class(TObject)
rect: TRect;
constructor Create(x, y, x2, y2: integer);
function getCoords(): string;
end;
var
hwndMain: ThwndMain;
recA, recB: TRect;
orig, recim: TBGRABitmap;
mouseEv: boolean;
startX, startY, nowX, nowY: integer;
rectList: TObjectList;
currentRect: TmyRect;
implementation
{$R *.lfm}
constructor TmyRect.Create(x, y, x2, y2: integer);
begin
self.rect.Left := X;
self.rect.Top := Y;
self.rect.Right := X2;
self.rect.Bottom := Y2;
end;
function TmyRect.getCoords(): string;
begin
getCoords := IntToStr(self.rect.Left) + ' : ' + IntToStr(self.rect.Top) +
' | ' + IntToStr(self.rect.Right) + ' : ' + IntToStr(self.rect.Bottom);
end;
{ ThwndMain }
procedure ThwndMain.FormCreate(Sender: TObject);
begin
rectList := TObjectList.Create(True);
currentRect := TmyRect.Create(0, 0, 0, 0);
DrawingArea.Canvas.Pen.Color := clRed;
DrawingArea.Canvas.Pen.Width := 3;
DrawingArea.Canvas.Pen.Style := psDash;
DrawingArea.Canvas.Brush.Style := bsClear;
DrawingArea.Enabled := False;
orig := TBGRABitmap.Create();
recim := TBGRABitmap.Create();
mouseEv := False;
startX := 0;
startY := 0;
nowX := 0;
nowY := 0;
end;
procedure ThwndMain.tbbLoadImageClick(Sender: TObject);
begin
openImageDlg.FileName := '';
recB := rect(0, 0, 0, 0);
if openImageDlg.Execute then
begin
if fileExists(openImageDlg.FileName) then
begin
{ TODO : Try:Except: for Loading Images! }
rectList.Clear();
orig.LoadFromFile(openImageDlg.FileName);
recim.LoadFromFile(openImageDlg.Filename);
DrawingArea.Width := orig.Width;
DrawingArea.Height := orig.Height;
with recim do
begin
with bitmap do
begin
Canvas.Pen.Color := clRed;
Canvas.Pen.Width := 3;
Canvas.Pen.Style := psDash;
Canvas.Brush.Style := bsClear;
end;
end;
orig.Draw(DrawingArea.Canvas, 0, 0, True);
DrawingArea.Enabled := True;
end;
end;
end;
procedure ThwndMain.DrawingAreaMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
begin
if Button = mbLeft then
begin
mouseEv := True;
startX := X;
startY := Y;
currentRect.rect.Left := X;
currentRect.rect.Top := Y;
currentRect.rect.Right := X;
currentRect.rect.Bottom := Y;
end;
end;
procedure ThwndMain.DrawingAreaMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: integer);
begin
if mouseEV then;
begin
DrawAction(X, Y);
end;
end;
procedure ThwndMain.DrawingAreaMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
var
msg: string;
begin
if (mouseEV) and (Button = mbLeft) then
begin
DrawAction(X, Y);
currentRect.rect.Right := X;
currentRect.rect.Bottom := Y;
rectList.Add(TmyRect.Create(currentRect.rect.Left, currentRect.rect.Top,
currentRect.rect.Right, currentRect.rect.Bottom));
mouseEv := False;
currentRect.rect.Left := 0;
currentRect.rect.Top := 0;
currentRect.rect.Right := 0;
currentRect.rect.Bottom := 0;
//DrawingArea.Refresh;
end;
end;
procedure ThwndMain.DrawingAreaPaint(Sender: TObject);
begin
// This is the OLD way, I skipped this,
// since the other way fits my thinking better:
// DrawingArea.Canvas.Draw(0,0,recim.Bitmap);
recim.Draw(DrawingArea.Canvas, 0, 0, True);
end;
procedure ThwndMain.FormDestroy(Sender: TObject);
begin
recim.Free();
rectList.Free();
end;
procedure ThwndMain.DrawAction(x: integer; y: integer);
begin
if mouseEv then
begin
DrawAllRects();
DrawingArea.Canvas.Draw(0, 0, recim.Bitmap);
DrawingArea.Canvas.Rectangle(startX, startY, x, y);
end;
end;
procedure ThwndMain.DrawAllRects();
var
i: integer;
x, y, x2, y2: integer;
begin
for i := 0 to rectList.Count - 1 do
begin
x := TmyRect(rectList.Items[i]).rect.Left;
y := TmyRect(rectList.Items[i]).rect.Top;
x2 := TmyRect(rectList.Items[i]).rect.Right;
y2 := TmyRect(rectList.Items[i]).rect.Bottom;
recim.canvas.Rectangle(x, y, x2, y2);
end;
end;
end.