unit Gallery;
interface
uses
Windows, Messages, SysUtils, Types, Classes, Graphics, Generics.Defaults,
Generics.Collections, ASObjects, UITypes, Forms, Controls, ImageViewer,
ASKernel, ClientDefs, ASTableEditor, MainForm, SndPlayer, TextEditor, ASNum,
ASExpression, Menus;
type
TGallery = class
strict private class var
FKernel: TASKernel;
FImgFrame: TImageViewerGUI;
class procedure CreatePixmapFrame(AObject: TAlgosimPixmap;
const ATitle: string; ANewWindow: Boolean); static;
class procedure CreateSoundFrame(AObject: TAlgosimSound;
const ATitle: string; ANewWindow: Boolean); static;
class procedure CreateTableFrame(AObject: TAlgosimTable;
const ATitle: string; ANewWindow: Boolean); static;
class procedure CreateTextFrame(AObject: TAlgosimObject;
const ATitle: string; ANewWindow: Boolean); static;
public
class property Kernel: TASKernel read FKernel write FKernel;
class function IsGalleryObject(AObject: TAlgosimObject): Boolean; static;
class procedure CreateFrame(AObject: TAlgosimObject;
const ATitle: string = ''; ANewWindow: Boolean = False); static;
class procedure ShowControl(AControl: TControl); static;
class procedure Vacuum; static;
end;
type
TASOForm = class(TForm)
protected
FKernel: TASKernel;
procedure DoClose(var Action: TCloseAction); override;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
public
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
end;
TSoundPlayerForm = class(TASOForm)
protected
procedure DoClose(var Action: TCloseAction); override;
public
SoundPlayer: TSoundPlayer;
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
end;
TTableForm = class(TASOForm)
private
FHasShown: Boolean;
protected
procedure DoShow; override;
public
TableEditor: TASTableEditor;
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
destructor Destroy; override;
end;
TTextASOForm = class(TASOForm)
strict private
FObject: TAlgosimObject;
FContextMenu: TPopupMenu;
FViewType: Integer;
procedure SetObject(AObject: TAlgosimObject);
procedure UpdateView(AViewType: Integer = 1);
procedure SetForm(Sender: TObject);
procedure ContextMenuPopup(Sender: TObject);
protected
procedure WMWindowPosChanged(var Message: TWMWindowPosChanged);
message WM_WINDOWPOSCHANGED;
procedure DoClose(var Action: TCloseAction); override;
public
Console: TTextEditor;
property &Object: TAlgosimObject write SetObject;
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
destructor Destroy; override;
end;
TPixmapForm = class(TASOForm)
public
ImageViewerGUI: TImageViewerGUI;
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
end;
implementation
uses
Math, ASColors, FormFader, WinMgrForm;
function _scale(X: Integer): Integer;
begin
Result := MulDiv(X, Screen.PixelsPerInch, 96);
end;
procedure TASOForm.CMTextChanged(var Message: TMessage);
begin
inherited;
TWndMgr.CaptionChanged(Self);
end;
constructor TASOForm.CreateNew(AOwner: TComponent; Dummy: Integer);
begin
inherited;
BorderStyle := bsSizeToolWin;
TFormFader.Create(Self);
TWindowWatcher.Create(Self);
end;
procedure TASOForm.DoClose(var Action: TCloseAction);
begin
inherited;
Action := caFree;
end;
constructor TSoundPlayerForm.CreateNew(AOwner: TComponent; Dummy: Integer);
begin
inherited;
Caption := 'Audio Player';
ClientHeight := TSoundPlayer.PreferredHeight;
ClientWidth := 10 * TSoundPlayer.PreferredHeight;
SoundPlayer := TSoundPlayer.Create(Self);
SoundPlayer.Parent := Self;
SoundPlayer.Align := alClient;
end;
procedure TSoundPlayerForm.DoClose(var Action: TCloseAction);
begin
inherited;
if Assigned(SoundPlayer) then
SoundPlayer.Stop;
end;
procedure TTextASOForm.ContextMenuPopup(Sender: TObject);
var
i: Integer;
begin
for i := 0 to FContextMenu.Items.Count - 1 do
FContextMenu.Items[i].Checked := FContextMenu.Items[i].Tag = FViewType;
end;
constructor TTextASOForm.CreateNew(AOwner: TComponent; Dummy: Integer);
var
mi: TMenuItem;
begin
inherited;
Caption := 'Object';
Console := TTextEditor.Create(Self);
Console.Parent := Self;
Console.Align := alClient;
Console.BorderType := btNone;
Console.UseRuxThemes := True;
Console.RulerVisible := False;
Console.LineSpacing := 0;
Console.ErrorMessageOnReadOnlyError := False;
if Assigned(AlgosimMainForm) and Assigned(AlgosimMainForm.teConsole) then
begin
Console.Font.Assign(AlgosimMainForm.teConsole.Font);
Console.BackgroundColor := AlgosimMainForm.teConsole.BackgroundColor;
Console.ForegroundColor := AlgosimMainForm.teConsole.ForegroundColor;
end;
FContextMenu := TPopupMenu.Create(Self);
FContextMenu.OnPopup := ContextMenuPopup;
mi := TMenuItem.Create(FContextMenu);
mi.Caption := 'Pretty form';
mi.RadioItem := True;
mi.Tag := 1;
mi.OnClick := SetForm;
FContextMenu.Items.Add(mi);
mi := TMenuItem.Create(FContextMenu);
mi.Caption := 'Single line';
mi.RadioItem := True;
mi.Tag := 2;
mi.OnClick := SetForm;
FContextMenu.Items.Add(mi);
mi := TMenuItem.Create(FContextMenu);
mi.Caption := 'Truncated single line';
mi.RadioItem := True;
mi.Tag := 3;
mi.OnClick := SetForm;
FContextMenu.Items.Add(mi);
mi := TMenuItem.Create(FContextMenu);
mi.Caption := 'Input form';
mi.RadioItem := True;
mi.Tag := 4;
mi.OnClick := SetForm;
FContextMenu.Items.Add(mi);
mi := TMenuItem.Create(FContextMenu);
mi.Caption := 'Unformatted';
mi.RadioItem := True;
mi.Tag := 5;
mi.OnClick := SetForm;
FContextMenu.Items.Add(mi);
Console.PopupMenu := FContextMenu;
end;
destructor TTextASOForm.Destroy;
begin
FreeAndNil(FObject);
inherited;
end;
procedure TTextASOForm.DoClose(var Action: TCloseAction);
begin
inherited;
if Assigned(Console) and Console.BalloonVisible then
begin
Console.HideBalloon;
Action := caNone;
end
end;
procedure TTextASOForm.SetForm(Sender: TObject);
begin
if Sender is TMenuItem then
UpdateView(TMenuItem(Sender).Tag);
end;
procedure TTextASOForm.SetObject(AObject: TAlgosimObject);
begin
FreeAndNil(FObject);
FObject := AObject.Clone;
UpdateView;
end;
function ColorText(const AColor: TRGB): string;
var
rgb: TRGB;
hsv: THSV;
name: string;
begin
rgb := TRGB(AColor);
hsv := THSV(AColor);
Result := Format(
'RGB HSV'#13#10 +
'%.3f %d°'#13#10 +
'%.3f %.3f'#13#10 +
'%.3f %.3f'#13#10 +
''#13#10 +
'%s',
[
rgb.Red, Round(hsv.Hue),
rgb.Green, hsv.Saturation,
rgb.Blue, hsv.Value,
ColorToHex(rgb)
],
TFormatSettings.Invariant);
if TryGetColorName(rgb, name) then
Result := Result + #13#10#13#10 + name;
end;
procedure TTextASOForm.UpdateView(AViewType: Integer);
var
S: string;
FO: TFormatOptions;
begin
if FObject = nil then
Exit;
if Console = nil then
Exit;
if Assigned(FKernel) then
FO := FKernel.FormatOptions
else
FO := DefaultFormatOptions;
if FObject is TCustomFunctionObj then
S := TCustomFunctionObj(FObject).ExprAsStr(False)
else if (FObject is TAlgosimColor) and (AViewType = 1) then
S := ColorText(FObject.ToColor)
else
case AViewType of
1:
S := FObject.GetAsMultilineText(FO);
2:
S := FObject.GetAsSingleLineText(FO);
3:
S := FObject.ToPreviewString;
4:
S := FObject.ToInputString;
5:
S := FObject.ToString;
else
S := '';
end;
Console.PlainText := S;
if (FObject is TAlgosimColor) and (AViewType = 1) then
begin
Console.EditMode := emText;
Console.RemoveClass('Color box');
Console.AddClass(MakeClass('Color box', Console.Font.Size, [], FObject.ToColor));
Console.AddLine;
Console.AddLine('██████████████', 'Color box');
Console.AddLine('██████████████', 'Color box');
end;
Console.EditMode := emReadOnly;
Console.TextFile.GotoSOF;
ClientHeight := EnsureRange
(
Console.TotalVerticalExtent + 2*GetSystemMetricsForWindow(SM_CYHSCROLL, Handle),
100,
600
);
ClientWidth := EnsureRange
(
Console.TotalHorizontalExtent + 3*GetSystemMetricsForWindow(SM_CXVSCROLL, Handle),
200,
800
);
FViewType := AViewType;
end;
procedure TTextASOForm.WMWindowPosChanged(var Message: TWMWindowPosChanged);
begin
inherited;
if Assigned(Console) then
Console.MoveBalloonPostScroll;
end;
constructor TPixmapForm.CreateNew(AOwner: TComponent; Dummy: Integer);
begin
inherited;
BorderStyle := bsSizeable;
Caption := 'Pixmap';
Color := clWhite;
Width := _scale(800);
Height := _scale(600);
ImageViewerGUI := TImageViewerGUI.Create(Self);
ImageViewerGUI.Parent := Self;
ImageViewerGUI.Align := alClient;
ScaleForPPI(Screen.PixelsPerInch);
end;
constructor TTableForm.CreateNew(AOwner: TComponent; Dummy: Integer);
begin
inherited;
Caption := 'Table';
TableEditor := TASTableEditor.Create(Self);
TableEditor.Parent := Self;
TableEditor.Align := alClient;
TableEditor.Color := clWindow;
end;
destructor TTableForm.Destroy;
begin
FreeAndNil(TableEditor);
inherited;
end;
procedure TTableForm.DoShow;
begin
inherited;
if not FHasShown and Assigned(TableEditor.Table) then
begin
ClientWidth := Math.Min(TableEditor.GetTotalHorizontalExtent + 100, Screen.WorkAreaWidth);
ClientHeight := Math.Min(TableEditor.GetTotalVerticalExtent + 100, Screen.WorkAreaHeight);
ClientWidth := Math.Min(TableEditor.GetTotalHorizontalExtent, Screen.WorkAreaWidth);
ClientHeight := Math.Min(TableEditor.GetTotalVerticalExtent, Screen.WorkAreaHeight);
if Width > Screen.WorkAreaWidth then
Width := Screen.WorkAreaWidth;
if Height > Screen.WorkAreaHeight then
Height := Screen.WorkAreaHeight;
FHasShown := True;
end;
end;
class procedure TGallery.CreateFrame(AObject: TAlgosimObject;
const ATitle: string; ANewWindow: Boolean);
begin
AssertMainThread;
if AObject is TAlgosimPixmap then
CreatePixmapFrame(TAlgosimPixmap(AObject), ATitle, ANewWindow)
else if AObject is TAlgosimSound then
CreateSoundFrame(TAlgosimSound(AObject), ATitle, ANewWindow)
else if AObject is TAlgosimTable then
CreateTableFrame(TAlgosimTable(AObject), ATitle, ANewWindow)
else
CreateTextFrame(AObject, ATitle, ANewWindow);
end;
class procedure TGallery.CreatePixmapFrame(AObject: TAlgosimPixmap;
const ATitle: string; ANewWindow: Boolean);
var
bm: TBitmap;
Frm: TPixmapForm;
begin
bm := AObject.Value.CreateGDIBitmap;
try
if ANewWindow then
begin
Frm := TPixmapForm.CreateNew(AlgosimMainForm);
if not ATitle.IsEmpty then
Frm.Caption := ATitle;
Frm.ImageViewerGUI.ImageViewer.Bitmap := bm;
Frm.ImageViewerGUI.ImageViewer.Caption := ATitle;
Frm.Show;
end
else
begin
if AlgosimMainForm.GUIMode = guiConsole then
AlgosimMainForm.GUIMode := guiMixed;
if FImgFrame = nil then
begin
FImgFrame := TImageViewerGUI.Create(AlgosimMainForm);
FImgFrame.Parent := AlgosimMainForm.GalleryPanel;
FImgFrame.Align := alClient
end;
ShowControl(FImgFrame);
FImgFrame.ImageViewer.Bitmap := bm;
end;
finally
bm.Free;
end;
end;
class procedure TGallery.CreateSoundFrame(AObject: TAlgosimSound;
const ATitle: string; ANewWindow: Boolean);
var
Frm: TSoundPlayerForm;
begin
Frm := TSoundPlayerForm.CreateNew(AlgosimMainForm);
if not ATitle.IsEmpty then
Frm.Caption := ATitle;
Frm.SoundPlayer.Sound := AObject.Value;
Frm.Show;
end;
class procedure TGallery.CreateTableFrame(AObject: TAlgosimTable;
const ATitle: string; ANewWindow: Boolean);
var
Frm: TTableForm;
begin
Frm := TTableForm.CreateNew(AlgosimMainForm);
if not ATitle.IsEmpty then
Frm.Caption := ATitle;
Frm.TableEditor.Table := AObject.Value;
Frm.Show;
end;
class procedure TGallery.CreateTextFrame(AObject: TAlgosimObject;
const ATitle: string; ANewWindow: Boolean);
var
Frm: TTextASOForm;
begin
if AObject = nil then
Exit;
Frm := TTextASOForm.CreateNew(AlgosimMainForm);
if not ATitle.IsEmpty then
Frm.Caption := ATitle;
Frm.&Object := AObject;
Frm.Show;
end;
class function TGallery.IsGalleryObject(AObject: TAlgosimObject): Boolean;
begin
Result := (AObject is TAlgosimPixmap) or (AObject is TAlgosimSound);
end;
class procedure TGallery.ShowControl(AControl: TControl);
begin
for var i := 0 to AlgosimMainForm.GalleryPanel.ControlCount - 1 do
AlgosimMainForm.GalleryPanel.Controls[i].Visible :=
AlgosimMainForm.GalleryPanel.Controls[i] = AControl;
end;
class procedure TGallery.Vacuum;
begin
for var i := AlgosimMainForm.GalleryPanel.ControlCount - 1 downto 0 do
if AlgosimMainForm.GalleryPanel.Controls[i].ClassName.ToLower.Contains('temporary') then
AlgosimMainForm.GalleryPanel.Controls[i].Free;
end;
end.