Subversion Repositories spacemission

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 daniel-mar 1
unit DXMapEdit;
2
//(c)2007 Jaro Benes
3
//All Rights Reserved
4
 
5
{
6
Complex application for users of unDelphiX as component editor:
7
 
8
Supported:
9
 a) create image map and store it into rersource.
10
 b) allow do change.
11
 c) controll map by each chip.
12
 
13
}
14
interface
15
{$INCLUDE DelphiXcfg.inc}        
16
uses
17
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
18
  Dialogs, StdCtrls, ExtCtrls, Buttons, {$IFDEF VER4UP}ImgList,{$ENDIF}
19
  Grids, Menus, DXMapEditProperties, Spin,
20
  DXSprite, DXClass, DXDraws{$IfNDef StandardDX}, DirectX{$EndIf}, DIB;
21
 
22
type
23
  {injected class}
24
 
25
  {  TEdit  }
26
 
27
  TEdit = class(StdCtrls.TEdit)
28
  private
29
    function GetAsInteger: Integer;
30
    procedure SetAsInteger(const Value: Integer);
31
  published
32
  public
33
    property AsInteger: Integer read GetAsInteger write SetAsInteger;
34
  end;
35
 
36
  {  TDrawGrid  }
37
 
38
//  TDrawGrid = class(Grids.TDrawGrid)
39
//    procedure CMMouseEnter(var Msg: TMessage); message CM_MouseEnter;
40
//    procedure CMMouseLeave(var Msg: TMessage); message CM_MouseLeave;
41
//  end;
42
 
43
  {  TDelphiXMapEditForm  }
44
 
45
  TDelphiXMapEditForm = class(TForm)
46
    pblBase: TPanel;
47
    LHeight: TLabel;
48
    LMapSizeX: TLabel;
49
    LMapSizeY: TLabel;
50
    EHeight: TEdit;
51
    EWidth: TEdit;
52
    eMapSizeX: TSpinEdit;
53
    eMapSizeY: TSpinEdit;
54
    OKButton: TButton;
55
    CancelButton: TButton;
56
    LWidth: TLabel;
57
    ImageToSet: TComboBox;
58
    LImageToSet: TLabel;
59
    ScrollBox1: TScrollBox;
60
    BtnSetSize: TSpeedButton;
61
    PicturesToChip: TListBox;
62
    LPicturesToChip: TLabel;
63
    MapArea: TDrawGrid;
64
    PopupMenu1: TPopupMenu;
65
    Fillall1: TMenuItem;
66
    PopupMenu2: TPopupMenu;
67
    Clear1: TMenuItem;
68
    LAreaOfChips: TLabel;
69
    ClearOneChip1: TMenuItem;
70
    DelphiXMapEditPropertiesPane: TPanel;
71
    pnlRight: TPanel;
72
    pnlLeft: TPanel;
73
    pnlLabels: TPanel;
74
    Panel1: TPanel;
75
    Splitter1: TSplitter;
76
    procedure OKButtonClick(Sender: TObject);
77
    procedure MapAreaDblClick(Sender: TObject);
78
    procedure ClearOneChip1Click(Sender: TObject);
79
    procedure PopupMenu1Popup(Sender: TObject);
80
    procedure PopupMenu2Popup(Sender: TObject);
81
    procedure Clear1Click(Sender: TObject);
82
    procedure Fillall1Click(Sender: TObject);
83
    procedure MapAreaMouseMove(Sender: TObject; Shift: TShiftState; X,
84
      Y: Integer);
85
    procedure ImageToSetChange(Sender: TObject);
86
    procedure FormDestroy(Sender: TObject);
87
    procedure PicturesToChipDrawItem(Control: TWinControl; Index: Integer;
88
      Rect: TRect; State: TOwnerDrawState);
89
    procedure PicturesToChipMeasureItem(Control: TWinControl; Index: Integer;
90
      var Height: Integer);
91
    procedure FormCreate(Sender: TObject);
92
    procedure MapAreaDrawCell(Sender: TObject; ACol, ARow: Integer;
93
      Rect: TRect; State: TGridDrawState);
94
    procedure MapAreaDragOver(Sender, Source: TObject; X, Y: Integer;
95
      State: TDragState; var Accept: Boolean);
96
    procedure BtnSetSizeClick(Sender: TObject);
97
    procedure MapAreaDragDrop(Sender, Source: TObject; X, Y: Integer);
98
    procedure MapAreaMouseDown(Sender: TObject; Button: TMouseButton;
99
      Shift: TShiftState; X, Y: Integer);
100
  private
101
    { Private declarations }
102
    DIB: TDIB;
103
    maparea_X, maparea_Y: Integer;
104
    pct: TDXPictureClip;
105
    FocusPopUpPositionCol, FocusPopUpPositionRow: Integer;
106
    DragPositionCol, DragPositionRow: Integer;
107
    DelphiXMapEditPropertiesForm: TDelphiXMapEditPropertiesForm;
108
    procedure MapTypeDefaultValuesByObject(out MapType: TMapType);
109
  public
110
    DXBackgroundSprite: TBackgroundSprite;
111
    DXImageList: TCustomDXImageList; //instance only
112
    function LoadSplittedImage(ClearContentOfMapArea: Boolean{$IFDEF VER4UP} = False{$ENDIF}): Boolean;
113
    procedure ResizeMapArea;
114
  end;
115
 
116
var
117
  DelphiXMapEditForm: TDelphiXMapEditForm;
118
 
119
implementation
120
 
121
{$R *.dfm}
122
 
123
{ TEdit }
124
 
125
function TEdit.GetAsInteger: Integer;
126
begin
127
  try
128
    Result := StrToInt(Self.Text);
129
  except
130
    Result := 0;
131
  end;
132
end;
133
 
134
procedure TEdit.SetAsInteger(const Value: Integer);
135
begin
136
  Self.Text := IntToStr(Value)
137
end;
138
 
139
{ TDrawGrid  }
140
 
141
//procedure TDrawGrid.CMMouseEnter(var Msg: TMessage);
142
//begin
143
//
144
//end;
145
//
146
//procedure TDrawGrid.CMMouseLeave(var Msg: TMessage);
147
//begin
148
//end;
149
 
150
//------------------------------------------------------------------------------
151
 
152
{TDelphiXMapEditForm}
153
 
154
procedure TDelphiXMapEditForm.MapAreaDragDrop(Sender, Source: TObject; X,
155
  Y: Integer);
156
var
157
  DropPositionCol, DropPositionRow: Integer;
158
begin
159
  MapArea.MouseToCell(X, Y, DropPositionCol, DropPositionRow); // convert mouse coord.
160
  if Source is TListBox then begin
161
    if Sender is TDrawGrid then
162
      with Sender as TDrawGrid do begin
163
        with DXBackgroundSprite do
164
          Chips[DropPositionCol, DropPositionRow] := (Source as TListBox).ItemIndex;
165
        Invalidate;
166
      end;
167
  end
168
  else
169
    if Source is TDrawGrid then begin
170
      if Sender is TDrawGrid then
171
        if (DropPositionCol <> DragPositionCol) or (DropPositionRow <> DragPositionRow) then
172
          with Sender as TDrawGrid do begin
173
            with DXBackgroundSprite do
174
              Map[DropPositionCol, DropPositionRow] := Map[DragPositionCol, DragPositionRow];
175
            Invalidate;
176
          end;
177
    end;
178
end;
179
 
180
procedure TDelphiXMapEditForm.MapAreaDragOver(Sender, Source: TObject; X,
181
  Y: Integer; State: TDragState; var Accept: Boolean);
182
var
183
  CurrentCol, CurrentRow: Integer;
184
begin
185
  MapArea.MouseToCell(X, Y, CurrentCol, CurrentRow); // convert mouse coord.
186
  Accept := ((Source = PicturesToChip) or (Source = Sender))
187
  { Accept dragged stuff only when the mouse is now over an acceptable region }
188
  and (CurrentCol >= 0) and (CurrentRow >= 0);
189
  if Source = Sender then
190
    MapArea.SetFocus;
191
end;
192
 
193
procedure TDelphiXMapEditForm.MapAreaDrawCell(Sender: TObject; ACol,
194
  ARow: Integer; Rect: TRect; State: TGridDrawState);
195
var
196
  TmpRect: TRect;
197
  A: array[1..255] of Char;
198
begin
199
  with MapArea.Canvas do begin
200
    FillRect(Rect);
201
    if pct.IsEmpty then Exit;
202
    with DXBackgroundSprite do begin
203
      DIB.SetSize(pct.Width, pct.Height, 24);
204
      pct.Draw(DIB.Canvas, 0, 0, Chips[ACol, ARow]);
205
      if gdFocused in State then begin
206
        DIB.DoDarkness(80);
207
      end
208
      else begin
209
        if CollisionMap[ACol, ARow] then
210
          DIB.Darker(50)
211
      end;
212
      if Map[ACol, ARow].MirrorFlip <> [] then DIB.Mirror(rmfMirror in Map[ACol, ARow].MirrorFlip, rmfFlip in Map[ACol, ARow].MirrorFlip);
213
      Draw(Rect.Left, Rect.Top, DIB);
214
    end;
215
    if gdFocused in State then
216
    begin
217
      if goDrawFocusSelected in MapArea.Options then
218
        Pen.Color := clHighlight
219
      else
220
        Pen.Color := MapArea.Color;
221
      Brush.Style := bsClear;
222
{$IFDEF VER5UP}
223
      Rectangle(Rect); InFlateRect(Rect, -1, -1); Rectangle(Rect);
224
{$ELSE}
225
      Rectangle(Rect.Left, Rect.Top, Rect.Right, Rect.Bottom); InFlateRect(Rect, -1, -1);Rectangle(Rect.Left, Rect.Top, Rect.Right, Rect.Bottom);
226
{$ENDIF}
227
    end;
228
    with DXBackgroundSprite do begin
229
      Font.Name := 'Arial';
230
      Font.Size := 9;
231
      Font.Color := clHighlightText;
232
      Brush.Style := bsClear;
233
      TmpRect := Rect;
234
      TmpRect.Bottom := TmpRect.Bottom - ((TmpRect.Bottom - TmpRect.Top) div 2);
235
      if CollisionMap[ACol, ARow] then
236
        DrawText(MapArea.Canvas.Handle, StrPCopy(@A, 'brick'), -1, TmpRect, dt_SingleLine or dt_Center or dt_VCenter);
237
      TmpRect := Rect;
238
      TmpRect.Top := TmpRect.Bottom - ((TmpRect.Bottom - TmpRect.Top) div 2);
239
      case Map[ACol, ARow].Rendered of
240
        rtDraw: DrawText(MapArea.Canvas.Handle, StrPCopy(@A, 'D:' + IntToStr(Map[ACol, ARow].Alpha)), -1, TmpRect, dt_SingleLine or dt_Center or dt_VCenter);
241
        rtBlend: DrawText(MapArea.Canvas.Handle, StrPCopy(@A, 'B:' + IntToStr(Map[ACol, ARow].Alpha)), -1, TmpRect, dt_SingleLine or dt_Center or dt_VCenter);
242
        rtAdd: DrawText(MapArea.Canvas.Handle, StrPCopy(@A, 'A:' + IntToStr(Map[ACol, ARow].Alpha)), -1, TmpRect, dt_SingleLine or dt_Center or dt_VCenter);
243
        rtSub: DrawText(MapArea.Canvas.Handle, StrPCopy(@A, 'S:' + IntToStr(Map[ACol, ARow].Alpha)), -1, TmpRect, dt_SingleLine or dt_Center or dt_VCenter);
244
      end
245
    end;
246
  end;
247
end;
248
 
249
procedure TDelphiXMapEditForm.FormCreate(Sender: TObject);
250
begin
251
  DelphiXMapEditPropertiesForm := TDelphiXMapEditPropertiesForm.Create(Self);
252
  DelphiXMapEditPropertiesForm.Parent := DelphiXMapEditPropertiesPane;
253
  DelphiXMapEditPropertiesForm.ParentWindow := Self.DelphiXMapEditPropertiesPane.Handle;
254
  DelphiXMapEditPropertiesForm.Top := 0;
255
  DelphiXMapEditPropertiesForm.Left := 0;
256
  DelphiXMapEditPropertiesForm.BorderStyle := bsNone;
257
  DelphiXMapEditPropertiesForm.Align := alClient;
258
  {nothing selected}
259
  FocusPopUpPositionCol := -1;
260
  FocusPopUpPositionRow := -1;
261
  DIB := TDIB.Create;
262
  pct := TDXPictureClip.Create(nil);
263
{$IFDEF VER4UP}
264
  MapArea.DoubleBuffered := True;
265
{$ENDIF}
266
end;
267
 
268
procedure TDelphiXMapEditForm.PicturesToChipMeasureItem(Control: TWinControl;
269
  Index: Integer; var Height: Integer);
270
begin
271
  Height := pct.Height;
272
end;
273
 
274
procedure TDelphiXMapEditForm.ResizeMapArea;
275
{$IFNDEF VER4UP}
276
type
277
  TOldMap = array[0..0, 0..0] of TMapType;
278
  POldMap = ^TOldMap;
279
{$ENDIF}
280
var
281
{$IFDEF VER4UP}
282
  oldmap: array of array of TMapType;
283
{$ELSE}
284
  oldmap: POldMap;
285
{$ENDIF}
286
  i, j, oldw, oldh: Integer;
287
  MapType: TMapType;
288
begin
289
  {older size, save old layout}
290
  oldw := DXBackgroundSprite.MapWidth;
291
  oldh := DXBackgroundSprite.MapHeight;
292
{$IFDEF VER4UP}
293
  SetLength(oldmap, oldw, oldh);
294
{$ELSE}
295
  GetMem(oldmap, oldw * oldh * SizeOf(TMapType));
296
  try
297
{$ENDIF}
298
    {old the content of map}
299
    if not DXBackgroundSprite.IsMapEmpty then
300
      for i := 0 to oldw - 1 do
301
        for j := 0 to oldh - 1 do
302
          oldmap{$IFNDEF VER4UP}^{$ENDIF} [i, j] := DXBackgroundSprite.Map[i, j];
303
    {size realocation}
304
    with DXBackgroundSprite do begin
305
      SetMapSize(eMapSizeX.Value, eMapSizeY.Value);
306
      {prevent resize of cleared by the content object}
307
      MapTypeDefaultValuesByObject(MapType);
308
      for i := 0 to eMapSizeX.Value - 1 do
309
        for j := 0 to eMapSizeY.Value - 1 do begin
310
          Chips[i, j] := 0;
311
          CollisionMap[i, j] := False;
312
          Map[i, j] := MapType;
313
        end;
314
    end;
315
    {back context}
316
    for i := 0 to oldw - 1 do
317
      for j := 0 to oldh - 1 do
318
        DXBackgroundSprite.Map[i, j] := oldmap{$IFNDEF VER4UP}^{$ENDIF} [i, j];
319
{$IFNDEF VER4UP}
320
  finally
321
    FreeMem(oldmap)
322
  end;
323
{$ENDIF}
324
  MapArea.ColCount := eMapSizeX.Value;
325
  MapArea.RowCount := eMapSizeY.Value;
326
  MapArea.Width := eMapSizeX.Value * (EWidth.AsInteger + 1);
327
  MapArea.Height := eMapSizeY.Value * (EHeight.AsInteger + 1);
328
  MapArea.Invalidate;
329
end;
330
 
331
procedure TDelphiXMapEditForm.MapTypeDefaultValuesByObject(out MapType: TMapType);
332
begin
333
  FillChar(MapType, SizeOf(MapType), 0);
334
  { default values from owner's object }
335
  MapType.CollisionChip := DXBackgroundSprite.Collisioned;
336
  MapType.Overlap := 0;
337
  MapType.AnimLooped:= DXBackgroundSprite.AnimLooped;
338
  MapType.AnimStart := DXBackgroundSprite.AnimStart;
339
  MapType.AnimCount := DXBackgroundSprite.AnimCount;
340
  MapType.AnimSpeed := DXBackgroundSprite.AnimSpeed;
341
  MapType.Alpha := DXBackgroundSprite.Alpha;
342
  MapType.Rendered := DXBackgroundSprite.BlendMode;
343
  MapType.AnimPos := DXBackgroundSprite.AnimPos;
344
  MapType.Angle := DXBackgroundSprite.Angle;
345
  MapType.MirrorFlip := DXBackgroundSprite.MirrorFlip;
346
  MapType.TextureFilter := DXBackgroundSprite.TextureFilter;
347
  MapType.CenterX := DXBackgroundSprite.CenterX;
348
  MapType.CenterY := DXBackgroundSprite.CenterY;
349
end;
350
 
351
procedure TDelphiXMapEditForm.BtnSetSizeClick(Sender: TObject);
352
begin
353
  ResizeMapArea
354
end;
355
 
356
procedure TDelphiXMapEditForm.PicturesToChipDrawItem(Control: TWinControl;
357
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
358
var
359
  R: TRect;
360
  I: Integer;
361
begin
362
  with PicturesToChip.Canvas do begin
363
    if not (odSelected in State) then
364
      if Odd(Index) then Brush.Color := {$IFDEF VER6UP}clMoneyGreen{$ELSE}clGreen{$ENDIF}
365
      else Brush.Color := clWhite;
366
    FillRect(Rect);
367
    pct.Draw(PicturesToChip.Canvas, Rect.Left, Rect.Top, Index);
368
    Brush.Style := bsClear;
369
    R := Rect;
370
    R.Left := Rect.Left + pct.Width + 2;
371
    I := Rect.Top + (Rect.Bottom - Rect.Top - PicturesToChip.Canvas.TextHeight(PicturesToChip.Items[index])) div 2;
372
    TextOut(Rect.Left + pct.Width + 2, I, PicturesToChip.Items[index]);
373
  end;
374
end;
375
 
376
procedure TDelphiXMapEditForm.FormDestroy(Sender: TObject);
377
begin
378
  DIB.Free;
379
  pct.Free;
380
end;
381
 
382
function TDelphiXMapEditForm.LoadSplittedImage(ClearContentOfMapArea: Boolean): Boolean;
383
var
384
  I, V: Integer;
385
begin
386
  if (ImageToSet.ItemIndex <> -1) and Assigned(DXImageList) then begin
387
    DXImageList.Items[ImageToSet.ItemIndex].Restore;
388
    pct.Picture := DXImageList.Items[ImageToSet.ItemIndex].Picture;
389
    pct.Width := DXImageList.Items[ImageToSet.ItemIndex].PatternWidth;
390
    pct.Height := DXImageList.Items[ImageToSet.ItemIndex].PatternHeight;
391
    EWidth.AsInteger := pct.Width;
392
    EHeight.AsInteger := pct.Height;
393
    PicturesToChip.Clear;
394
    V := DXImageList.Items[ImageToSet.ItemIndex].PatternCount;
395
    for I := 0 to V - 1 do begin
396
      PicturesToChip.Items.Add(Format(ImageToSet.Text + ' [%d]', [I]));
397
    end;
398
    PicturesToChip.ItemHeight := DXImageList.Items[ImageToSet.ItemIndex].PatternHeight;
399
    {seznam je videt a take MapArea}
400
    PicturesToChip.Visible := True;
401
    {pri zmene obrazku vymazat content!}
402
    if ClearContentOfMapArea then
403
      Clear1.Click;
404
    MapArea.Visible := True;
405
    MapArea.Invalidate;
406
    Result := True;
407
  end
408
  else
409
    Result := False;
410
end;
411
 
412
procedure TDelphiXMapEditForm.ImageToSetChange(Sender: TObject);
413
begin
414
  if ImageToSet.ItemIndex <> -1 then
415
  begin
416
    LoadSplittedImage(True);
417
  end;
418
end;
419
 
420
procedure TDelphiXMapEditForm.MapAreaMouseDown(Sender: TObject;
421
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
422
begin
423
  { Convert mouse coordinates X, Y to to StringGrid related col and row numbers }
424
  MapArea.MouseToCell(X, Y, DragPositionCol, DragPositionRow);
425
  { Allow dragging only if an acceptable cell was clicked (cell beyond the fixed column and row) }
426
  if (Button = mbLeft) and (DragPositionCol >= 0) and (DragPositionRow >= 0) then
427
  begin
428
    { Begin dragging after mouse has moved 4 pixels }
429
    MapArea.BeginDrag(False{$IFDEF VER4UP}, 2{$ENDIF});
430
  end;
431
end;
432
 
433
procedure TDelphiXMapEditForm.MapAreaMouseMove(Sender: TObject;
434
  Shift: TShiftState; X, Y: Integer);
435
var
436
  FocusPositionCol, FocusPositionRow: Integer;
437
begin
438
  maparea_X := X; maparea_Y := Y;
439
  MapArea.MouseToCell(X, Y, FocusPositionCol, FocusPositionRow);
440
  if not MapArea.Focused then
441
    MapArea.SetFocus;
442
  MapArea.Row := FocusPositionRow;
443
  MapArea.Col := FocusPositionCol;
444
end;
445
 
446
procedure TDelphiXMapEditForm.Fillall1Click(Sender: TObject);
447
var
448
  i, j: Integer;
449
begin
450
  if PicturesToChip.ItemIndex <> -1 then
451
  begin
452
    with DXBackgroundSprite do
453
      for i := 0 to MapArea.ColCount - 1 do
454
        for j := 0 to MapArea.RowCount - 1 do
455
          Chips[i, j] := PicturesToChip.ItemIndex;
456
    MapArea.Invalidate;
457
  end;
458
end;
459
 
460
procedure TDelphiXMapEditForm.Clear1Click(Sender: TObject);
461
var
462
  i, j: Integer;
463
  MapType: TMapType;
464
begin
465
  MapTypeDefaultValuesByObject(MapType);
466
  with DXBackgroundSprite do
467
    for i := 0 to MapArea.ColCount - 1 do
468
      for j := 0 to MapArea.RowCount - 1 do
469
      begin
470
        Chips[i, j] := 0;
471
        CollisionMap[i, j] := False;
472
        Map[i, j] := MapType;
473
      end;
474
  MapArea.Invalidate;
475
end;
476
 
477
procedure TDelphiXMapEditForm.PopupMenu2Popup(Sender: TObject);
478
var
479
  Shift: TShiftState;
480
begin
481
  Shift := [];
482
  MouseMove(Shift, maparea_X, maparea_Y);
483
  MapArea.MouseToCell(maparea_X, maparea_Y, FocusPopUpPositionCol, FocusPopUpPositionRow);
484
end;
485
 
486
procedure TDelphiXMapEditForm.PopupMenu1Popup(Sender: TObject);
487
begin
488
  Fillall1.Enabled := PicturesToChip.ItemIndex <> -1;
489
end;
490
 
491
procedure TDelphiXMapEditForm.ClearOneChip1Click(Sender: TObject);
492
var
493
  MapType: TMapType;
494
begin
495
  MapTypeDefaultValuesByObject(MapType);
496
  with DXBackgroundSprite do
497
  begin
498
    Map[MapArea.Col, MapArea.Row] := MapType;
499
  end;
500
  MapArea.Invalidate;
501
end;
502
 
503
procedure TDelphiXMapEditForm.MapAreaDblClick(Sender: TObject);
504
begin
505
  {Reset the flag}
506
  DelphiXMapEditPropertiesForm.Tag := 0;
507
  DelphiXMapEditPropertiesForm.Panel2.Color := {$IFDEF VER6UP}clSkyBlue{$ELSE}clBlue{$ENDIF};
508
  if not DelphiXMapEditPropertiesForm.Showing then
509
    DelphiXMapEditPropertiesForm.Show;
510
  Application.ProcessMessages;
511
  DelphiXMapEditPropertiesForm.Col := MapArea.Col;
512
  DelphiXMapEditPropertiesForm.Row := MapArea.Row;
513
  DelphiXMapEditPropertiesForm.LoadCellToForm(DXBackgroundSprite.Map[MapArea.Col, MapArea.Row], MapArea.Col, MapArea.Row);
514
end;
515
 
516
procedure TDelphiXMapEditForm.OKButtonClick(Sender: TObject);
517
begin
518
  if DelphiXMapEditPropertiesForm.Tag = 1 then
519
    DelphiXMapEditPropertiesForm.btnOK.Click;
520
end;
521
 
522
end.