123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 |
- //
- // The graphics engine GLScene
- //
- unit FmGuiLayoutEditor;
- interface
- {$I Stage.Defines.inc}
- uses
- Winapi.Windows,
- Winapi.ShellApi,
- System.SysUtils,
- System.Variants,
- System.Classes,
- Vcl.Graphics,
- Vcl.Controls,
- Vcl.Forms,
- Vcl.Dialogs,
- Vcl.Buttons,
- Vcl.ExtDlgs,
- Vcl.StdCtrls,
- Vcl.ExtCtrls,
- Vcl.Samples.Spin,
- Vcl.Grids,
-
- GLS.BaseClasses,
- GLS.ImageUtils,
- GLS.Gui,
- Stage.Strings;
- type
- TGLLayoutEditorForm = class(TForm)
- Panel1: TPanel;
- Panel2: TPanel;
- items_list: TListBox;
- x_label: TLabel;
- y_label: TLabel;
- open_image_button: TBitBtn;
- open_button: TBitBtn;
- save_button: TBitBtn;
- OpenDialog1: TOpenDialog;
- SaveDialog1: TSaveDialog;
- delete_item_button: TBitBtn;
- add_button: TBitBtn;
- Label1: TLabel;
- Label2: TLabel;
- left_edit: TSpinEdit;
- top_edit: TSpinEdit;
- Label3: TLabel;
- Label4: TLabel;
- height_edit: TSpinEdit;
- width_edit: TSpinEdit;
- Label5: TLabel;
- name_edit: TEdit;
- elements_grid: TStringGrid;
- Panel3: TPanel;
- BitBtn4: TBitBtn;
- BitBtn5: TBitBtn;
- ScrollBox1: TScrollBox;
- Image2: TImage;
- PaintBox1: TPaintBox;
- Image1: TImage;
- BitBtn6: TBitBtn;
- BitBtn1: TBitBtn;
- GLGuiLayout1: TGLGuiLayout;
- procedure open_image_buttonClick(Sender: TObject);
- procedure open_buttonClick(Sender: TObject);
- procedure save_buttonClick(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
- procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure add_buttonClick(Sender: TObject);
- procedure delete_item_buttonClick(Sender: TObject);
- procedure items_listClick(Sender: TObject);
- procedure name_editExit(Sender: TObject);
- procedure name_editKeyPress(Sender: TObject; var Key: Char);
- procedure elements_gridClick(Sender: TObject);
- procedure left_editChange(Sender: TObject);
- procedure top_editChange(Sender: TObject);
- procedure width_editChange(Sender: TObject);
- procedure height_editChange(Sender: TObject);
- procedure BitBtn4Click(Sender: TObject);
- procedure BitBtn6Click(Sender: TObject);
- procedure elements_gridDblClick(Sender: TObject);
- private
-
- procedure SyncImages;
- procedure DrawCurrentElement;
- procedure RefreshComponentBox;
- function GetEnabledSpins: Boolean;
- procedure SetEnabledSpins(Value: Boolean);
- public
- procedure Execute(AGUILayout: TGLGuiLayout);
- property EnabledSpins: Boolean read GetEnabledSpins write SetEnabledSpins;
- end;
- function GUILayoutEditorForm: TGLLayoutEditorForm;
- procedure ReleaseGUILayoutEditorForm;
- //-------------------------------------------------
- implementation
- //-------------------------------------------------
- {$R *.dfm}
- uses
- Stage.Utils;
- var
- vGUILayoutEditorForm: TGLLayoutEditorForm;
- rect_point1, rect_point2: TPoint;
- zoom: integer = 1;
- sorted_elements: array[0..9] of TGLGuiElement;
- function GUILayoutEditorForm: TGLLayoutEditorForm;
- begin
- if not Assigned(vGUILayoutEditorForm) then
- vGUILayoutEditorForm := TGLLayoutEditorForm.Create(nil);
- Result := vGUILayoutEditorForm;
- end;
- procedure ReleaseGUILayoutEditorForm;
- begin
- if Assigned(vGUILayoutEditorForm) then
- begin
- vGUILayoutEditorForm.Free;
- vGUILayoutEditorForm := nil;
- end;
- end;
- function SnapPoint(X, Y: integer): TPoint;
- begin
- Result.X := (X div zoom) * zoom;
- Result.Y := (Y div zoom) * zoom;
- end;
- procedure TGLLayoutEditorForm.SetEnabledSpins(Value: Boolean);
- begin
- left_edit.Enabled := Value;
- top_edit.Enabled := Value;
- height_edit.Enabled := Value;
- width_edit.Enabled := Value;
- end;
- procedure TGLLayoutEditorForm.SyncImages;
- begin
- Image2.Width := Image1.Width;
- Image2.Height := Image1.Height;
- Image2.Picture.Bitmap.Width := Image1.Width;
- Image2.Picture.Bitmap.Height := Image1.Height;
- PaintBox1.Width := Image1.Width;
- PaintBox1.Height := Image1.Height;
- ScrollBox1.HorzScrollBar.Range := Image1.Width;
- ScrollBox1.VertScrollBar.Range := Image1.Height;
- PaintBox1.Canvas.CopyRect(PaintBox1.Canvas.ClipRect,
- Image1.Canvas, Image1.Canvas.ClipRect);
- end;
- procedure TGLLayoutEditorForm.DrawCurrentElement;
- begin
- with elements_grid do
- if (items_list.ItemIndex > -1) and (sorted_elements[Col + 3 * Row] <> nil)
- then
- with sorted_elements[Col + 3 * Row], Image2.Canvas do
- begin
- FillRect(ClipRect);
- Rectangle(Rect(zoom * Round(TopLeft.X), zoom * Round(TopLeft.Y),
- zoom * Round(BottomRight.X), zoom * Round(BottomRight.Y)));
- end;
- end;
- procedure TGLLayoutEditorForm.open_image_buttonClick(Sender: TObject);
- var
- LFileName: string;
- begin
- LFileName := '';
- if OpenPictureDialog(LFileName) then
- try
- Image1.Stretch := false;
- Image1.AutoSize := true;
- Image1.Picture.LoadFromFile(LFileName);
- Image1.AutoSize := false;
- Image1.Stretch := true;
- Image2.Canvas.Pen.Width := 1;
- SyncImages;
- zoom := 1;
- except
- Application.MessageBox('Unable to load picture!', 'Error', MB_ICONERROR);
- end;
- end;
- procedure TGLLayoutEditorForm.RefreshComponentBox;
- var
- i: integer;
- begin
- items_list.Clear;
- for i := 0 to GLGuiLayout1.GuiComponents.Count - 1 do
- items_list.Items.Add(GLGuiLayout1.GuiComponents[i].Name);
- items_list.ItemIndex := 0;
- items_listClick(nil);
- end;
- procedure TGLLayoutEditorForm.open_buttonClick(Sender: TObject);
- begin
- case Application.MessageBox('Save layout?',
- 'Question', MB_ICONQUESTION + MB_YESNOCANCEL) of
- mrYes: save_buttonClick(nil);
- mrCancel: Exit;
- end;
- if OpenDialog1.Execute then
- try
- GLGuiLayout1.Clear;
- GLGuiLayout1.LoadFromFile(OpenDialog1.FileName);
- RefreshComponentBox;
- except
- Application.MessageBox('Unable to load layout!', 'Error', MB_ICONERROR);
- end;
- end;
- procedure TGLLayoutEditorForm.save_buttonClick(Sender: TObject);
- begin
- if SaveDialog1.FileName = '' then
- if SaveDialog1.Execute then
- GLGuiLayout1.SaveToFile(SaveDialog1.FileName)
- else
- else
- GLGuiLayout1.SaveToFile(SaveDialog1.FileName);
- end;
- procedure TGLLayoutEditorForm.FormCreate(Sender: TObject);
- begin
- rect_point1.X := -1;
- Image2.Canvas.FillRect(Image2.Canvas.ClipRect);
- Image2.Canvas.Pen.Color := clAqua;
- end;
- function TGLLayoutEditorForm.GetEnabledSpins: Boolean;
- begin
- Result := left_edit.Enabled;
- end;
- procedure TGLLayoutEditorForm.Image1MouseMove(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
- begin
- x_label.Caption := 'X: ' + IntToStr(X div zoom);
- y_label.Caption := 'Y: ' + IntToStr(Y div zoom);
- if not (ssRight in Shift) then
- Exit;
- if (X < 0) or (Y < 0) or (X > Image2.Width) or (Y > Image2.Height) then
- Exit;
- if rect_point1.X < 0 then
- rect_point1 := SnapPoint(X, Y)
- else
- with Image2.Canvas do
- begin
- FillRect(ClipRect);
- rect_point2 := SnapPoint(X, Y);
- Rectangle(rect_point1.x, rect_point1.y, X, Y);
- end;
- if items_list.ItemIndex = -1 then
- Exit;
- if rect_point1.X < rect_point2.X then
- left_edit.Value := rect_point1.X div zoom
- else
- left_edit.Value := rect_point2.X div zoom;
- if rect_point1.Y > rect_point2.Y then
- top_edit.Value := rect_point2.Y div zoom
- else
- top_edit.Value := rect_point1.Y div zoom;
- width_edit.Value := Abs(rect_point2.X - rect_point1.X) div zoom;
- height_edit.Value := Abs(rect_point2.Y - rect_point1.Y) div zoom;
- end;
- procedure TGLLayoutEditorForm.Image1MouseDown(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if not (ssRight in Shift) then
- Exit;
- with Image2.Canvas do
- begin
- FillRect(ClipRect);
- rect_point1 := SnapPoint(X, Y);
- rect_point2 := rect_point1;
- end;
- end;
- procedure TGLLayoutEditorForm.Image1MouseUp(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if not (ssRight in Shift) then
- Exit;
- rect_point1.X := -1;
- end;
- procedure TGLLayoutEditorForm.add_buttonClick(Sender: TObject);
- var
- i: integer;
- begin
- with TGLGuiComponent(GLGuiLayout1.GuiComponents.Add) do
- begin
- Name := InputBox('Question', 'Name of new region:', '');
- if Name = '' then
- begin
- Free;
- Exit;
- end;
- items_list.Items.Add(Name);
- items_list.ItemIndex := items_list.Count - 1;
- for i := 0 to 9 do
- begin
- sorted_elements[i] := TGLGuiElement(Elements.Add);
- sorted_elements[i].Align := TGUIAlignments(i);
- end;
- name_edit.Text := Name;
- end;
- end;
- procedure TGLLayoutEditorForm.delete_item_buttonClick(Sender: TObject);
- begin
- if items_list.ItemIndex = -1 then
- Exit;
- GLGuiLayout1.GuiComponents.Delete(items_list.ItemIndex);
- items_list.DeleteSelected;
- if items_list.ItemIndex > -1 then
- name_edit.Text := GLGuiLayout1.GuiComponents[items_list.ItemIndex].Name
- else
- name_edit.Text := '';
- end;
- procedure TGLLayoutEditorForm.items_listClick(Sender: TObject);
- var
- i, p: integer;
- begin
- if items_list.ItemIndex = -1 then
- Exit;
- name_edit.Text := GLGuiLayout1.GuiComponents[
- items_list.ItemIndex].Name;
- elements_grid.Row := 0;
- elements_grid.Col := 0;
- for i := 0 to Length(sorted_elements) - 1 do
- begin
- sorted_elements[i] := nil;
- if I < 9 then
- elements_grid.Cells[i mod 3, i div 3] := #32;
- end;
- with GLGuiLayout1.GuiComponents[items_list.ItemIndex] do
- for i := 0 to Elements.Count - 1 do
- begin
- p := Integer(Elements[i].Align);
- sorted_elements[p] := Elements[i];
- elements_grid.Cells[p mod 3, p div 3] := '+';
- end;
- elements_gridClick(nil);
- end;
- procedure TGLLayoutEditorForm.name_editExit(Sender: TObject);
- begin
- if items_list.ItemIndex > -1 then
- begin
- GLGuiLayout1.GuiComponents[items_list.
- ItemIndex].Name := name_edit.Text;
- items_list.Items[items_list.ItemIndex] := name_edit.Text;
- items_listClick(nil);
- end;
- end;
- procedure TGLLayoutEditorForm.name_editKeyPress(Sender: TObject; var Key: Char);
- begin
- if Key = #13 then
- name_editExit(nil);
- end;
- procedure TGLLayoutEditorForm.elements_gridClick(Sender: TObject);
- begin
- with elements_grid do
- if (items_list.ItemIndex > -1) and (sorted_elements[Col + 3 * Row] <> nil)
- then
- with sorted_elements[Col + 3 * Row] do
- begin
- EnabledSpins := True;
- left_edit.Value := Round(TopLeft.X);
- top_edit.Value := Round(TopLeft.Y);
- width_edit.Value := Round(BottomRight.X - TopLeft.X);
- height_edit.Value := Round(BottomRight.Y - TopLeft.Y);
- DrawCurrentElement;
- end
- else
- begin
- EnabledSpins := False;
- Image2.Canvas.FillRect(Image2.Canvas.ClipRect);
- end;
- end;
- procedure TGLLayoutEditorForm.elements_gridDblClick(Sender: TObject);
- var
- I: Integer;
- E: TGLGuiElement;
- begin
- if items_list.ItemIndex > -1 then
- with elements_grid do
- begin
- if Assigned(sorted_elements[Col + 3 * Row]) then
- begin
- I := GLGuiLayout1.GuiComponents[items_list.ItemIndex].Elements.IndexOf(sorted_elements[Col + 3 * Row]);
- GLGuiLayout1.GuiComponents[items_list.ItemIndex].Elements.Delete(I);
- sorted_elements[Col + 3 * Row] := nil;
- Cells[Col, Row] := #32;
- elements_gridClick(nil);
- end
- else begin
- E := TGLGuiElement(GLGuiLayout1.GuiComponents[items_list.ItemIndex].Elements.Add);
- E.Align := TGUIAlignments(Col + 3 * Row);
- sorted_elements[Col + 3 * Row] := E;
- Cells[Col, Row] := '+';
- elements_gridClick(nil);
- end;
- end;
- end;
- procedure TGLLayoutEditorForm.left_editChange(Sender: TObject);
- begin
- if (items_list.ItemIndex = -1) or not EnabledSpins then
- Exit;
- if left_edit.Value + width_edit.Value > Image2.Width div zoom then
- left_edit.Value := (Image2.Width div zoom) - width_edit.Value;
- if left_edit.Value < 0 then
- left_edit.Value := 0;
- with elements_grid do
- sorted_elements[Col + 3 * Row].TopLeft.X := left_edit.Value;
- DrawCurrentElement;
- end;
- procedure TGLLayoutEditorForm.top_editChange(Sender: TObject);
- begin
- if (items_list.ItemIndex = -1) or not EnabledSpins then
- Exit;
- if top_edit.Value + height_edit.Value > Image2.Height div zoom then
- top_edit.Value := (Image2.Height div zoom) - height_edit.Value;
- if top_edit.Value < 0 then
- top_edit.Value := 0;
- with elements_grid do
- sorted_elements[Col + 3 * Row].TopLeft.Y := top_edit.Value;
- DrawCurrentElement;
- end;
- procedure TGLLayoutEditorForm.width_editChange(Sender: TObject);
- begin
- if (items_list.ItemIndex = -1) or not EnabledSpins then
- Exit;
- with elements_grid do
- sorted_elements[Col + 3 * Row].BottomRight.X := left_edit.Value +
- width_edit.Value;
- if left_edit.Value + width_edit.Value > Image2.Width div zoom then
- width_edit.Value := (Image2.Width div zoom) - left_edit.Value;
- if width_edit.Value < 0 then
- width_edit.Value := 0;
- DrawCurrentElement;
- end;
- procedure TGLLayoutEditorForm.height_editChange(Sender: TObject);
- begin
- if (items_list.ItemIndex = -1) or not EnabledSpins then
- Exit;
- with elements_grid do
- sorted_elements[Col + 3 * Row].BottomRight.Y := top_edit.Value +
- height_edit.Value;
- if top_edit.Value + height_edit.Value > Image2.Height div zoom then
- height_edit.Value := (Image2.Height div zoom) - top_edit.Value;
- if height_edit.Value < 0 then
- height_edit.Value := 0;
- DrawCurrentElement;
- end;
- procedure TGLLayoutEditorForm.BitBtn4Click(Sender: TObject);
- begin
- if zoom + TBitBtn(Sender).Tag < 1 then
- Exit;
- Image1.Width := (Image1.Width div zoom) * (zoom + TBitBtn(Sender).Tag);
- Image1.Height := (Image1.Height div zoom) * (zoom + TBitBtn(Sender).Tag);
- SyncImages;
- zoom := zoom + TBitBtn(Sender).Tag;
- Image2.Canvas.Pen.Width := zoom;
- elements_gridClick(nil);
- end;
- procedure TGLLayoutEditorForm.BitBtn6Click(Sender: TObject);
- {$IFDEF LINUX}
- var
- lProcess: TProcess;
- {$ENDIF}
- begin
- {$IFDEF MSWINDOWS}
- ShellExecuteW(0, 'open', 'mspaint', '', '', SW_SHOW)
- {$ENDIF}
- {$IFDEF LINUX}
- lProcess := TProcess.Create(nil);
- lProcess.CommandLine := 'gimp';
- try
- lProcess.Execute;
- finally
- lProcess.Destroy;
- end;
- {$ENDIF}
- end;
- procedure TGLLayoutEditorForm.Execute(AGUILayout: TGLGuiLayout);
- begin
- GLGuiLayout1.Assign(AGUILayout);
- Image1.Stretch := false;
- Image1.AutoSize := true;
- Image1.Picture.Assign(AGUILayout.Material.GetActualPrimaryTexture.Image.GetBitmap32.Create32BitsBitmap);
- Image1.AutoSize := false;
- Image1.Stretch := true;
- Image2.Canvas.Pen.Width := 1;
- SyncImages;
- zoom := 1;
- RefreshComponentBox;
- if ShowModal = mrOk then
- AGUILayout.Assign(GLGuiLayout1);
- end;
- //-------------------------------------
- initialization
- //-------------------------------------
- finalization
- ReleaseGUILayoutEditorForm;
- end.
|