123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692 |
- //
- // The graphics engine GXScene https://github.com/glscene
- //
- unit GXS.Console;
- (*
- The console is a popdown window that appears on a game for text output/input.
- What is different compared to the original component?
- 1) Can be added to any object, not just the root one
- 2) Has a *wide* range of built-in commands
- 3) TgxConsoleCommand.UnknownCommand added
- it is set to True, if no internal command recognized
- 4) Internal console help added
- 5) By default does not remove quotes ("), but this option can be
- turned on (property RemoveQuotes)
- 6) Command list added. All user commands are saved there
- 7) All previously typed commands can be accessed in a usual way (arrow up/down)
- 8) Commands can be auto-completed by pressing TConsoleControls.AutoCompleteCommand key,
- or setting AutoCompleteCommandsOnKeyPress, AutoCompleteCommandsOnEnter to True
- Dbl-pressing the key, defined in the TConsoleControls.AutoCompleteCommand
- property, gives you a list of all possible internal-external commands that
- start with your letters
- 9) Batch command execution support added
- 10) Short help is shown when user calls the global 'help' function
- Long help is shown elsewhere
- 11) Show command help by "/?", "-?", "--?" etc
- 12) Assign() added for every class
- TODO:
- [new command] Redirection with the | operator, like in any othe console (optional)
- [new command] File browser stuff... (this one's optional ;)
- Blinking cursor, "Delete" key support
- Allow long lines to continue on the next line
- May be SceneViewer should be a TControl to support the FullScreenViewer...
- *)
- interface
- {$I Stage.Defines.inc}
- uses
- Winapi.Windows,
- System.Classes,
- System.SysUtils,
- System.TypInfo,
- System.UITypes,
- System.UIConsts,
- FMX.Graphics,
- Stage.VectorTypes,
- GXS.PersistentClasses,
- Stage.Strings,
- Stage.Utils,
- GXS.Coordinates,
- GXS.Scene,
- GXS.Objects,
- GXS.HUDObjects,
- GXS.SceneViewer,
- GXS.BitmapFont,
- GXS.Context,
- GXS.Texture,
- GXS.Material,
- GXS.ImageUtils;
- const
- CONSOLE_MAX_COMMANDS = 120;
- type
- EGLConsoleException = class(Exception);
- TgxConsoleOption = (coAutoCompleteCommandsOnKeyPress,
- //commands are auto-completed as user types them
- coAutoCompleteCommandsOnEnter, //commands are auto-completed when user presses the "Enter" key
- coShowConsoleHelpIfUnknownCommand, //take a wild guess ;)
- coRemoveQuotes); //remove quotes when a command line is parsed
- TgxConsoleOptions = set of TgxConsoleOption;
- TgxCustomConsole = class;
- TgxConsoleCommandList = class;
- TgxConsoleCommand = class;
- (* Stores info on a command. A command is a parsed input line.
- Should be transformed into a class, I think...*)
- TgxUserInputCommand = record
- CommandCount: Integer;
- Strings: array of string;
- UnknownCommand: Boolean;
- //if user identifies a command, he must set this to "True"
- end;
- // Event called when used presses the "Enter"
- TgxlConsoleEvent = procedure(const ConsoleCommand: TgxConsoleCommand;
- const Console: TgxCustomConsole;
- var Command: TgxUserInputCommand) of object;
- TgxConsoleMatchList = set of 0..CONSOLE_MAX_COMMANDS {Byte};
- // A class that checks for duplicates.
- TgxConsoleStringList = class(TStringList)
- private
- FConsole: TgxCustomConsole;
- protected
- procedure Changed; override;
- function GetOwner: TPersistent; override;
- public
- function CommandExists(const Command: string): Boolean;
- constructor Create(const Owner: TgxCustomConsole);
- end;
- // A wrapper for a console command.
- TgxConsoleCommand = class(TCollectionItem)
- private
- FVisible: Boolean;
- FEnabled: Boolean;
- FSilentDisabled: Boolean;
- FCommandList: TgxConsoleCommandList;
- FCommandName: string;
- FShortHelp: string;
- FLongHelp: TStringList;
- FOnCommand: TgxlConsoleEvent;
- FOnHelp: TNotifyEvent;
- procedure SetCommandName(const Value: string);
- protected
- procedure ShowInvalidUseOfCommandError; virtual;
- procedure ShowInvalidNumberOfArgumentsError(const ShowHelpAfter: Boolean =
- True); virtual;
- procedure DoOnCommand(var UserInputCommand: TgxUserInputCommand); virtual;
- function GetDisplayName: string; override;
- public
- //procedures
- procedure ShowHelp; virtual;
- procedure ShowShortHelp; virtual;
- procedure Assign(Source: TPersistent); override;
- constructor Create(Collection: TCollection); override;
- destructor Destroy; override;
- published
- //properties
- property CommandName: string read FCommandName write SetCommandName;
- property ShortHelp: string read FShortHelp write FShortHelp;
- property LongHelp: TStringList read FLongHelp;
- property OnCommand: TgxlConsoleEvent read FOnCommand write FOnCommand;
- property OnHelp: TNotifyEvent read FOnHelp write FOnHelp;
- // Disabled commands won't execute
- property Enabled: Boolean read FEnabled write FEnabled default True;
- (* If command is disabled and user calls it, no error report will be
- generated if SilentDisabled is enabled *)
- property SilentDisabled: Boolean read FSilentDisabled write FSilentDisabled
- default False;
- (* Hidden commands won't show when user requests command list
- or uses auto-complete *)
- property Visible: Boolean read FVisible write FVisible default True;
- end;
- TgxConsoleCommandList = class(TCollection)
- private
- FConsole: TgxCustomConsole;
- function GetItems(const Index: Integer): TgxConsoleCommand;
- protected
- function GetOwner: TPersistent; override;
- public
- procedure SortCommands(const Ascending: Boolean = True);
- function CommandExists(const Command: string): Boolean;
- function GetCommandIndex(const Command: string): Integer;
- // General list stuff.
- function LastConsoleCommand: TgxConsoleCommand;
- function Add: TgxConsoleCommand; overload;
- // Standard stuff.
- constructor Create(const AOwner: TgxCustomConsole);
- destructor Destroy; override;
- property Items[const Index: Integer]: TgxConsoleCommand read GetItems;
- default;
- end;
- TgxConsoleControls = class(TPersistent)
- private
- FOwner: TPersistent;
- FNavigatePageUp: Byte;
- FAutoCompleteCommand: Byte;
- FPreviousCommand: Byte;
- FNextCommand: Byte;
- FNavigateUp: Byte;
- FNavigatePageDown: Byte;
- FNavigateDown: Byte;
- FDblClickDelay: Integer;
- protected
- function GetOwner: TPersistent; override;
- public
- constructor Create(AOwner: TPersistent);
- procedure Assign(Source: TPersistent); override;
- published
- property NavigateUp: Byte read FNavigateUp write FNavigateUp default
- VK_HOME;
- property NavigateDown: Byte read FNavigateDown write FNavigateDown default
- VK_END;
- property NavigatePageUp: Byte read FNavigatePageUp write FNavigatePageUp
- default VK_PRIOR;
- property NavigatePageDown: Byte read FNavigatePageDown write
- FNavigatePageDown default VK_NEXT;
- property NextCommand: Byte read FNextCommand write FNextCommand default
- VK_DOWN;
- property PreviousCommand: Byte read FPreviousCommand write FPreviousCommand
- default VK_UP;
- property AutoCompleteCommand: Byte read FAutoCompleteCommand write
- FAutoCompleteCommand default VK_CONTROL;
- property DblClickDelay: Integer read FDblClickDelay write FDblClickDelay
- default 300;
- end;
- // TgxCustomConsole
- TgxCustomConsole = class(TgxBaseSceneObject)
- private
- FHudSprite: TgxHudSprite;
- FHudText: TgxHudText;
- FSceneViewer: TgxSceneViewer;
- FInputLine: string;
- FStartLine: Integer;
- FCurrentCommand: Integer;
- FPreviousTickCount: Integer;
- FSize: Single;
- FColsoleLog: TStringList;
- FCommands: TgxConsoleCommandList;
- FAdditionalCommands: TgxConsoleStringList;
- FTypedCommands: TStringList;
- FControls: TgxConsoleControls;
- FOnCommandIssued: TgxlConsoleEvent;
- FOptions: TgxConsoleOptions;
- FHint: string;
- procedure SetSize(const Value: Single);
- procedure SetSceneViewer(const Value: TgxSceneViewer);
- function GetFont: TgxCustomBitmapFont;
- procedure SetFont(const Value: TgxCustomBitmapFont);
- protected
- procedure DoOnCommandIssued(var UserInputCommand: TgxUserInputCommand);
- virtual;
- procedure SetFontColor(const Color: TColor); virtual;
- function GetFontColor: TColor; virtual;
- procedure SetHUDSpriteColor(const Color: TColor); virtual;
- function GetHUDSpriteColor: TColor; virtual;
- function NumLines: Integer; virtual;
- procedure ShowConsoleHelp; virtual;
- procedure HandleUnknownCommand(const Command: string); virtual;
- // Auto Complete Command
- procedure AutoCompleteCommand; overload; virtual;
- procedure AutoCompleteCommand(var MatchCount: Integer; var
- AdditionalCommandsMatchList: TgxConsoleMatchList; var CommandsMatchList:
- TgxConsoleMatchList); overload;
- // Command interpreters
- procedure CommandIssued(var UserInputCommand: TgxUserInputCommand); virtual;
- procedure FixCommand(var UserInputCommand: TgxUserInputCommand); virtual;
- function ParseString(str, caract: string): TgxUserInputCommand; virtual;
- procedure ProcessInput; virtual;
- // Refreshes the Hud (clip lines outside the visible console).
- procedure RefreshHud; virtual;
- // Register built-in commands (onCreate)
- procedure RegisterBuiltInCommands; virtual;
- // Internal command handlers:
- procedure ProcessInternalCommandHelp(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandClearScreen(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandConsoleHide(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandConsoleColor(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandConsoleRename(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandConsoleClearTypedCommands(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var
- Command: TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandSystemTime(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandSystemDate(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandViewerFPS(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandViewerResetPerformanceMonitor(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var
- Command: TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandViewerVSync(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- procedure ProcessInternalCommandViewerAntiAliasing(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand); virtual;
- // Internal command help handlers:
- procedure GetHelpInternalCommandRename(Sender: TObject); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation);
- override;
- procedure SetName(const Value: TComponentName); override;
- public
- // Methods: User *must* call these methods in his code.
- procedure ProcessKeyPress(const c: Char); virtual;
- procedure ProcessKeyDown(const key: word); virtual;
- // Navigation through code from outside
- procedure NavigateUp;
- procedure NavigateDown;
- procedure NavigatePageUp;
- procedure NavigatePageDown;
- (* Refreshes the size of the hud to reflect changes on the viewer.
- Should be called whenever the viewer's size changes. *)
- procedure RefreshHudSize; virtual;
- // Adds a line (which is not treated as a command).
- procedure AddLine(const str: string);
- // TypedCommands are cleared and current command index is reset.
- procedure ClearTypedCommands;
- procedure ExecuteCommand(const Command: string);
- procedure ExecuteCommands(const Commands: TStrings);
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- // Changes the console font color.
- property FontColor: TColor read GetFontColor write SetFontColor stored
- False;
- property HUDSpriteColor: TColor read GetHUDSpriteColor write
- SetHUDSpriteColor stored False;
- // Where user enters his commands.
- property InputLine: string read FInputLine write FInputLine;
- // List of commands that user typed.
- property TypedCommands: TStringList read FTypedCommands;
- // Commands have events that are called when user types a sertauin command
- property Commands: TgxConsoleCommandList read FCommands;
- (* Aditional commands can be registered to participate in command auto-completion.
- They can be interpreted in the global OnCommandIssued event handler. *)
- property AdditionalCommands: TgxConsoleStringList read FAdditionalCommands;
- // User controls.
- property Controls: TgxConsoleControls read FControls;
- // list of commands that user typed and console's responces.
- property ColsoleLog: TStringList read FColsoleLog;
- // Allows to change consol's height from 0 to 1.
- property Size: Single read FSize write SetSize;
- // Visual stuff.
- property SceneViewer: TgxSceneViewer read FSceneViewer write SetSceneViewer;
- property HudSprite: TgxHudSprite read FHudSprite;
- property HudText: TgxHudText read FHudText;
- property Font: TgxCustomBitmapFont read GetFont write SetFont stored False;
- property Options: TgxConsoleOptions read FOptions write FOptions;
- (* Main event of the console. Happens whenever the enter key is pressed.
- First the input line is compared to all registered commands, then everything
- is parsed into a TgxUserInputCommand record and sent to the event.
- Empty lines are not ignored (i.e. they also trigger events)*)
- property OnCommandIssued: TgxlConsoleEvent read FOnCommandIssued write
- FOnCommandIssued;
- // Standard stuff
- property Hint: string read FHint write FHint;
- property Visible default False;
- end;
- TgxConsole = class(TgxCustomConsole)
- published
- property FontColor;
- property HUDSpriteColor;
- property InputLine;
- property TypedCommands;
- property Commands;
- property AdditionalCommands;
- property Controls;
- property ColsoleLog;
- property SceneViewer;
- property HudSprite;
- property HudText;
- property Font;
- property Options;
- property OnCommandIssued;
- property Hint;
- property Tag;
- property ObjectsSorting;
- property Visible;
- property OnProgress;
- end;
- //-------------------------------------------
- implementation
- //-------------------------------------------
- const
- STR_NO_DUPLICATE_NAMES_ALLOWED = 'Duplicate names not allowed!';
- STR_UNRECOGNIZED_PARAMETER = 'Unrecognized parameter: ';
- conDefaultFontCharHeight = 15;
- conDefaultConsoleWidth = 400;
- conDefaultConsoleHeight = 100;
- //-------------------------------------------
- // TgxCustomConsole
- //-------------------------------------------
- procedure TgxCustomConsole.ProcessInternalCommandClearScreen(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- begin
- Console.FInputLine := '';
- Console.ColsoleLog.Clear;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandConsoleHide(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- begin
- Console.Visible := False;
- AddLine(' - Console hidden');
- end;
- procedure TgxCustomConsole.ProcessInternalCommandConsoleColor(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- var
- NewColor: TColor;
- begin
- with Console, ConsoleCommand do
- begin
- if Command.CommandCount = 1 then
- AddLine(' - Current console font color is ' +
- ColorToString(FHudText.ModulateColor.AsWinColor))
- else if Command.CommandCount = 2 then
- begin
- if TryStringToColorAdvanced(Command.Strings[1], NewColor) then
- begin
- //color changed successfully
- SetFontColor(NewColor);
- AddLine(' - Current console font changed to ' +
- ColorToString(NewColor));
- end
- else
- begin
- //color unidentified!
- AddLine(' - Color unidentified!');
- end;
- end
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandConsoleRename(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- var
- CommandIndex: Integer;
- begin
- if (Command.CommandCount <> 3) then
- ConsoleCommand.ShowInvalidNumberOfArgumentsError
- else
- begin
- CommandIndex :=
- ConsoleCommand.FCommandList.GetCommandIndex(Command.Strings[1]);
- if CommandIndex = -1 then
- begin
- AddLine(' - Could not rename command +"' + Command.Strings[1] + '" to "'
- +
- Command.Strings[2] + '": such command was not found!');
- ConsoleCommand.ShowHelp;
- end
- else if ConsoleCommand.FCommandList.CommandExists(Command.Strings[2]) or
- Console.FAdditionalCommands.CommandExists(Command.Strings[2]) then
- begin
- AddLine(' - Could not rename command +"' + Command.Strings[1] + '" to "'
- +
- Command.Strings[2] + '": command "' + Command.Strings[2] +
- '" already exists!');
- ConsoleCommand.ShowHelp;
- end
- else
- begin
- ConsoleCommand.FCommandName := Command.Strings[2];
- AddLine(' - Command "' + Command.Strings[1] + '" successfully renamed to "'
- +
- Command.Strings[2] + '"!');
- end;
- end;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandConsoleClearTypedCommands(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- begin
- if (Command.CommandCount = 1) then
- Console.ClearTypedCommands
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandSystemDate(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- begin
- if (Command.CommandCount = 1) then
- AddLine(' - Current system date is: ' + DateToStr(now))
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandHelp(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- var
- MainCommand: string;
- I: Integer;
- begin
- if Command.CommandCount = 1 then
- Console.ShowConsoleHelp
- else if (Command.CommandCount = 2) then
- begin
- MainCommand := LowerCase(Command.Strings[1]);
- if FCommands.Count <> 0 then
- for I := 0 to FCommands.Count - 1 do
- if MainCommand = LowerCase(FCommands[I].FCommandName) then
- begin
- FCommands[I].ShowHelp;
- Exit;
- end;
- if FAdditionalCommands.Count <> 0 then
- for I := 0 to FAdditionalCommands.Count - 1 do
- if MainCommand = LowerCase(FAdditionalCommands[I]) then
- begin
- AddLine(' - Command "' + Command.Strings[1] +
- '" exists, but help is unavaible,');
- AddLine(' - because it is an external command');
- Exit;
- end;
- HandleUnknownCommand(Command.Strings[1]);
- end
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandSystemTime(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- begin
- if Command.CommandCount = 1 then
- AddLine(' - Current system time is: ' + TimeToStr(now))
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end;
- procedure TgxCustomConsole.GetHelpInternalCommandRename(Sender: TObject);
- begin
- with TgxConsoleCommand(Sender) do
- begin
- Addline(' - The "' + FCommandName + '" command can rename any command');
- AddLine(' - Usage:');
- AddLine(' - ' + FCommandName + ' [old_command_name] [new_command_name]');
- end;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandViewerFPS(const ConsoleCommand:
- TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- begin
- if Command.CommandCount = 1 then
- begin
- if Console.FSceneViewer <> nil then
- AddLine(' - Current SceneViewer has ' +
- Console.FSceneViewer.FramesPerSecondText)
- else
- AddLine(' - ' + strErrorEx + strSceneViewerNotDefined);
- end
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end;
- procedure
- TgxCustomConsole.ProcessInternalCommandViewerResetPerformanceMonitor(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- begin
- if Command.CommandCount = 1 then
- begin
- if Console.FSceneViewer <> nil then
- begin
- Console.FSceneViewer.ResetPerformanceMonitor;
- AddLine(' - ResetPerformanceMonitor for Current SceneViewer completed');
- end
- else
- AddLine(' - ' + strErrorEx + strSceneViewerNotDefined);
- end
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end;
- procedure TgxCustomConsole.ProcessInternalCommandViewerVSync(const
- ConsoleCommand: TgxConsoleCommand; const Console: TgxCustomConsole; var Command:
- TgxUserInputCommand);
- const
- ON_OFF: array[Boolean] of string = ('Off', 'On');
- begin
- if Console.FSceneViewer <> nil then
- begin
- if Command.CommandCount = 1 then
- begin
- AddLine(' - Current SceneViewer VSync is ' +
- ON_OFF[Console.FSceneViewer.VSync = vsmSync]);
- end
- else if (Command.CommandCount = 2) then
- begin
- if Command.Strings[1] = ON_OFF[False] then
- Console.FSceneViewer.VSync := vsmNoSync
- else if Command.Strings[1] = ON_OFF[True] then
- Console.FSceneViewer.VSync := vsmSync
- else
- begin
- AddLine(' - ' + STR_UNRECOGNIZED_PARAMETER + Command.Strings[1]);
- Exit;
- end;
- AddLine(' - Current SceneViewer VSync was changed to ' +
- ON_OFF[Console.FSceneViewer.VSync = vsmSync]);
- end
- else
- HandleUnknownCommand(Command.Strings[1]);
- end
- else
- AddLine(' - ' + strErrorEx + strSceneViewerNotDefined);
- end;
- procedure TgxCustomConsole.ProcessInternalCommandViewerAntiAliasing(
- const ConsoleCommand: TgxConsoleCommand;
- const Console: TgxCustomConsole; var Command: TgxUserInputCommand);
- var
- Temp: Integer;
- begin
- if Console.FSceneViewer <> nil then
- begin
- if Command.CommandCount = 1 then
- AddLine(' - Current SceneViewer AntiAliasing = ' +
- GetEnumName(TypeInfo(TgxAntiAliasing),
- Ord(Console.FSceneViewer.Buffer.AntiAliasing)))
- else if (Command.CommandCount = 2) then
- begin
- Temp := GetEnumValue(TypeInfo(TgxAntiAliasing), Command.Strings[1]);
- if Temp = -1 then
- begin
- AddLine(' - ' + STR_UNRECOGNIZED_PARAMETER + Command.Strings[1]);
- end
- else
- begin
- Console.FSceneViewer.Buffer.AntiAliasing := TgxAntiAliasing(Temp);
- AddLine(' - Current SceneViewer AntiAliasing was changed to ' +
- GetEnumName(TypeInfo(TgxAntiAliasing),
- Ord(Console.FSceneViewer.Buffer.AntiAliasing)))
- end;
- end
- else
- ConsoleCommand.ShowInvalidNumberOfArgumentsError;
- end
- else
- AddLine(' - ' + strErrorEx + strSceneViewerNotDefined);
- end;
- function TgxCustomConsole.ParseString(str, caract: string): TgxUserInputCommand;
- var
- p1: Integer;
- begin
- Result.CommandCount := 0;
- while True do
- begin
- p1 := pos(caract, str);
- if (p1 = 0) or (p1 = -1) then
- break;
- SetLength(Result.Strings, Result.CommandCount + 1);
- Result.Strings[Result.CommandCount] := copy(str, 1, p1 - 1);
- str := copy(str, p1 + 1, Length(str));
- Result.CommandCount := Result.CommandCount + 1;
- end;
- if Length(str) > 0 then
- begin
- setlength(Result.Strings, Result.CommandCount + 1);
- Result.Strings[Result.CommandCount] := str;
- Result.CommandCount := Result.CommandCount + 1;
- end;
- end;
- procedure TgxCustomConsole.FixCommand(var UserInputCommand:
- TgxUserInputCommand);
- var
- nCount, I: Integer;
- openq: Boolean;
- begin
- for I := 0 to UserInputCommand.CommandCount - 1 do
- UserInputCommand.Strings[I] := trim(UserInputCommand.Strings[I]);
- nCount := 0;
- I := 0;
- openq := False;
- while nCount < UserInputCommand.CommandCount do
- begin
- if UserInputCommand.Strings[I] = '' then
- begin
- if UserInputCommand.Strings[nCount] <> '' then
- UserInputCommand.Strings[I] := UserInputCommand.Strings[nCount];
- end
- else if openq then
- UserInputCommand.Strings[I] := UserInputCommand.Strings[I] + ' ' +
- UserInputCommand.Strings[nCount];
- if (Length(UserInputCommand.Strings[I]) > 0) then
- begin
- if coRemoveQuotes in FOptions then
- begin
- if (UserInputCommand.Strings[I][1] = '"') and
- (UserInputCommand.Strings[I][Length(UserInputCommand.Strings[I])] =
- '"') then
- UserInputCommand.Strings[I] := copy(UserInputCommand.Strings[I], 2,
- Length(UserInputCommand.Strings[I]) - 2);
- if (UserInputCommand.Strings[I][1] = '"') and not openq then
- begin
- openq := True;
- UserInputCommand.Strings[I] := copy(UserInputCommand.Strings[I], 2,
- Length(UserInputCommand.Strings[I]));
- end;
- if (UserInputCommand.Strings[I][Length(UserInputCommand.Strings[I])] =
- '"') and openq then
- begin
- openq := False;
- UserInputCommand.Strings[I] := copy(UserInputCommand.Strings[I], 1,
- Length(UserInputCommand.Strings[I]) - 1);
- end;
- end;
- if not openq then
- Inc(I);
- end;
- Inc(nCount);
- end;
- if I < UserInputCommand.CommandCount then
- begin
- setLength(UserInputCommand.Strings, I);
- UserInputCommand.CommandCount := I;
- end;
- end;
- constructor TgxCustomConsole.Create(AOwner: TComponent);
- begin
- inherited;
- FColsoleLog := TStringList.Create;
- FTypedCommands := TStringList.Create;
- FCommands := TgxConsoleCommandList.Create(Self);
- FAdditionalCommands := TgxConsoleStringList.Create(Self);
- FControls := TgxConsoleControls.Create(Self);
- FHudSprite := TgxHudSprite.Create(Self);
- MakeSubComponent(FHudSprite, True);
- AddChild(FHudSprite);
- FHudSprite.FreeNotification(Self);
- with FHudSprite.Material do
- begin
- BlendingMode := bmTransparency;
- FrontProperties.Diffuse.Alpha := 0.5;
- Texture.TextureMode := tmModulate;
- Texture.Enabled := True;
- end;
- FHudText := TgxHudText.Create(Self);
- MakeSubComponent(FHudText, True);
- AddChild(FHUDText);
- FHudText.FreeNotification(Self);
- FHudText.Position.Y := 2;
- FHudText.Position.X := 3;
- FSize := 0.35;
- RegisterBuiltIncommands;
- SetVisible(False);
- SetHUDSpriteColor(TColorRec.White);
- SetFontColor(TColorRec.Blue);
- end;
- destructor TgxCustomConsole.Destroy;
- begin
- Controls.Destroy;
- FCommands.Destroy;
- FAdditionalCommands.Destroy;
- FTypedCommands.Destroy;
- FColsoleLog.Destroy;
- FreeAndNil(FHudSprite);
- FreeAndNil(FHudText);
- inherited;
- end;
- procedure TgxCustomConsole.ProcessKeyPress(const c: Char);
- begin
- if not Visible then
- Exit;
- if c = #8 then //glKey_BACK
- FInputLine := copy(FInputLine, 1, Length(FInputLine) - 1)
- else if c = #13 then //glKey_RETURN
- begin
- if coAutoCompleteCommandsOnEnter in FOptions then
- AutoCompleteCommand;
- //remmember the current entered command
- if (FInputLine <> '') and (FInputLine <> #13) then
- begin
- if FTypedCommands.Count = 0 then
- FCurrentCommand := FTypedCommands.Add(FInputLine) + 1
- else
- begin
- if FTypedCommands[FTypedCommands.Count - 1] <> FInputLine then
- FCurrentCommand := FTypedCommands.Add(FInputLine) + 1;
- end;
- end;
- ProcessInput;
- end
- else
- FInputLine := FinputLine + c;
- if coAutoCompleteCommandsOnKeyPress in FOptions then
- AutoCompleteCommand;
- RefreshHud;
- end;
- procedure TgxCustomConsole.ProcessKeyDown(const key: word);
- var
- MatchCount: Integer;
- AdditionalCommandsMatchList: TgxConsoleMatchList;
- CommandsMatchList: TgxConsoleMatchList;
- CurrentTickCount: Integer;
- I: Integer;
- begin
- if not Visible then
- Exit;
- if (key = FControls.NextCommand) then
- if FCurrentCommand <> FTypedCommands.Count then
- begin
- if FCurrentCommand <> FTypedCommands.Count - 1 then
- Inc(FCurrentCommand);
- FinputLine := FTypedCommands[FCurrentCommand];
- end;
- if (key = FControls.PreviousCommand) then
- if FTypedCommands.Count <> 0 then
- begin
- if FCurrentCommand <> 0 then
- Dec(FCurrentCommand);
- FinputLine := FTypedCommands[FCurrentCommand];
- end;
- if (key = FControls.AutoCompleteCommand) then
- begin
- CurrentTickCount := TThread.GetTickCount;
- AutoCompleteCommand(MatchCount, AdditionalCommandsMatchList,
- CommandsMatchList);
- if MatchCount = 0 then
- Beep;
- if CurrentTickCount - FPreviousTickCount < Controls.FDblClickDelay then
- if MatchCount > 1 then
- begin
- if CommandsMatchList <> [] then
- begin
- AddLine(' - Registered commands:');
- for I := 0 to CONSOLE_MAX_COMMANDS do
- if I in CommandsMatchList then
- AddLine(' - ' + FCommands[I].FCommandName);
- end;
- if AdditionalCommandsMatchList <> [] then
- begin
- AddLine(' - Additional registered commands:');
- for I := 0 to CONSOLE_MAX_COMMANDS do
- if I in AdditionalCommandsMatchList then
- AddLine(' - ' + FAdditionalCommands[I]);
- end;
- end;
- FPreviousTickCount := CurrentTickCount;
- end;
- if (key = FControls.NavigateUp) then
- Dec(FStartLine);
- if (key = FControls.NavigateDown) then
- Inc(FStartLine);
- if (key = FControls.NavigatePageUp) then
- Dec(FStartLine, NumLines);
- if key = FControls.NavigatePageDown then
- Inc(FStartLine, NumLines);
- RefreshHud;
- end;
- procedure TgxCustomConsole.RefreshHud;
- var
- outStr: string;
- endLine, I: Integer;
- begin
- //beware! This stuf is messy
- if FStartLine > FColsoleLog.Count - numlines then
- FStartLine := FColsoleLog.Count - numlines;
- if FStartLine < 0 then
- FStartLine := 0;
- endLine := FStartLine + numlines - 1;
- if FColsoleLog.Count < numLines then
- outStr := FColsoleLog.Text
- else
- begin
- for I := FStartLine to endLine do
- outStr := outStr + FColsoleLog[I] + #13;
- end;
- FHudText.Text := outStr + '> ' + FInputLine;
- end;
- function TgxCustomConsole.NumLines: Integer;
- begin
- if GetFont = nil then
- Result := Trunc(FHudSprite.Height / conDefaultFontCharHeight - 1.7)
- else
- Result := Trunc(FHudSprite.Height / GetFont.CharHeight - 1.7);
- end;
- procedure TgxCustomConsole.ProcessInput;
- var
- info: TgxUserInputCommand;
- begin
- //Add the current line
- AddLine(FInputLine);
- //Get everything between spaces
- info := ParseString(FInputLine, ' ');
- info.UnknownCommand := True;
- //Remove empty strings and " sequences
- FixCommand(info);
- //Execute the command
- CommandIssued(info);
- //Clear the current line
- FinputLine := '';
- end;
- procedure TgxCustomConsole.ExecuteCommands(const Commands: TStrings);
- var
- I: Integer;
- begin
- if Commands.Count = 0 then
- Exit;
- for I := 0 to Commands.Count - 1 do
- ExecuteCommand(Commands[I]);
- end;
- procedure TgxCustomConsole.ExecuteCommand(const Command: string);
- begin
- FInputLine := Command;
- ProcessInput;
- end;
- procedure TgxCustomConsole.AddLine(const str: string);
- begin
- FColsoleLog.Text := FColsoleLog.Text + str + #10;
- FStartLine := FColsoleLog.Count - numLines;
- RefreshHud;
- end;
- procedure TgxCustomConsole.CommandIssued(var UserInputCommand:
- TgxUserInputCommand);
- var
- MainCommand: string;
- I: Integer;
- begin
- if UserInputCommand.CommandCount = 0 then
- Exit;
- MainCommand := LowerCase(UserInputCommand.Strings[0]);
- if FCommands.Count <> 0 then
- for I := 0 to FCommands.Count - 1 do
- if MainCommand = LowerCase(FCommands[I].FCommandName) then
- begin
- //show help
- if UserInputCommand.CommandCount > 1 then
- begin
- //I hope I didn't forget anything ;)
- if (UserInputCommand.Strings[1] = '/?') or
- (UserInputCommand.Strings[1] = '\?') or
- (UserInputCommand.Strings[1] = '-?') or
- (UserInputCommand.Strings[1] = '--?') or
- (UserInputCommand.Strings[1] = '/help') or
- (UserInputCommand.Strings[1] = '\help') or
- (UserInputCommand.Strings[1] = '-help') or
- (UserInputCommand.Strings[1] = '--help') then
- FCommands[I].ShowHelp
- else
- //or execute the asosiated event
- FCommands[I].DoOnCommand(UserInputCommand);
- end
- else
- //or execute the asosiated event
- FCommands[I].DoOnCommand(UserInputCommand);
- //recognize the command
- UserInputCommand.UnknownCommand := False;
- break;
- end;
- //external command processing event
- DoOnCommandIssued(UserInputCommand);
- if UserInputCommand.UnknownCommand then
- HandleUnknownCommand(UserInputCommand.Strings[0]);
- end;
- procedure TgxCustomConsole.RefreshHudSize;
- begin
- if FSceneViewer <> nil then
- begin
- FHudSprite.Width := FSceneViewer.Width;
- FHudSprite.Height := FSceneViewer.Height * FSize;
- end
- else
- begin
- FHudSprite.Width := conDefaultConsoleWidth;
- FHudSprite.Height := conDefaultConsoleHeight;
- end;
- FHudSprite.Position.X := FHudSprite.Width / 2;
- FHudSprite.Position.Y := FHudSprite.Height / 2;
- RefreshHud;
- end;
- procedure TgxCustomConsole.SetFontColor(const Color: TColor);
- begin
- FHUDText.ModulateColor.AsWinColor := Color;
- FHUDText.Material.FrontProperties.Ambient.AsWinColor := Color;
- end;
- procedure TgxCustomConsole.ShowConsoleHelp;
- var
- I: Integer;
- begin
- if (FCommands.Count = 0) and (FAdditionalCommands.Count = 0) then
- AddLine(' - There are no registered commands!')
- else
- begin
- if FCommands.Count <> 0 then
- begin
- AddLine(' - List of registered console commands:');
- for I := 0 to FCommands.Count - 1 do
- FCommands[I].ShowShortHelp;
- end;
- if FAdditionalCommands.Count <> 0 then
- begin
- AddLine(' - List of additional console commands:');
- for I := 0 to FAdditionalCommands.Count - 1 do
- AddLine(' - ' + FAdditionalCommands[I]);
- end;
- end;
- end;
- procedure TgxCustomConsole.ClearTypedCommands;
- begin
- FTypedCommands.Clear;
- FCurrentCommand := 0;
- end;
- {$WARNINGS off}
- procedure TgxCustomConsole.AutoCompleteCommand(var MatchCount: Integer;
- var AdditionalCommandsMatchList: TgxConsoleMatchList;
- var CommandsMatchList: TgxConsoleMatchList);
- var
- I: Integer;
- HasEnterKey: Boolean;
- NewInputLine, FirstMatch: string;
- NewMatchCount, FirstMatchIndex: Integer;
- begin
- MatchCount := 0;
- AdditionalCommandsMatchList := [];
- CommandsMatchList := [];
- if FInputLine <> '' then
- begin
- //delete the last "Enter" key, if there is any
- if FInputLine[Length(FInputLine)] = #13 then
- begin
- Delete(FInputLine, Length(FInputLine), 1);
- HasEnterKey := True;
- end;
- //find all the matches
- if FAdditionalCommands.Count <> 0 then
- for I := 0 to FAdditionalCommands.Count - 1 do
- if AnsiStartsText(FInputLine, FAdditionalCommands[I]) then
- begin
- Inc(MatchCount);
- AdditionalCommandsMatchList := AdditionalCommandsMatchList + [I];
- end;
- if FCommands.Count <> 0 then
- for I := 0 to FCommands.Count - 1 do
- if FCommands[I].FVisible then
- if AnsiStartsText(FInputLine, FCommands[I].FCommandName) then
- begin
- Inc(MatchCount);
- CommandsMatchList := CommandsMatchList + [I];
- end;
- //if there is only one, fill it up!
- if MatchCount = 1 then
- begin
- if AdditionalCommandsMatchList <> [] then
- for I := 0 to CONSOLE_MAX_COMMANDS do
- if I in AdditionalCommandsMatchList then
- begin
- FInputLine := FAdditionalCommands[I];
- break;
- end;
- if CommandsMatchList <> [] then
- for I := 0 to CONSOLE_MAX_COMMANDS do
- if I in CommandsMatchList then
- begin
- FInputLine := FCommands[I].FCommandName;
- break;
- end;
- end
- else
- {//if more than 1, try to complete other letters} if MatchCount > 1 then
- begin
- NewInputLine := FInputLine;
- //find 1st match
- if AdditionalCommandsMatchList <> [] then
- for I := 0 to CONSOLE_MAX_COMMANDS do
- if I in AdditionalCommandsMatchList then
- begin
- FirstMatch := FAdditionalCommands[I];
- FirstMatchIndex := I;
- break;
- end;
- if AdditionalCommandsMatchList = [] then
- for I := 0 to CONSOLE_MAX_COMMANDS do
- if I in CommandsMatchList then
- begin
- FirstMatch := FCommands[I].FCommandName;
- FirstMatchIndex := I;
- break;
- end;
- NewMatchCount := MatchCount;
- while (NewMatchCount = MatchCount) and (Length(NewInputLine) <>
- Length(FirstMatch)) do
- begin
- NewInputLine := NewInputLine + FirstMatch[Length(NewInputLine) + 1];
- NewMatchCount := 0;
- if AdditionalCommandsMatchList <> [] then
- for I := FirstMatchIndex to FAdditionalCommands.Count - 1 do
- if AnsiStartsText(NewInputLine, FAdditionalCommands[I]) then
- Inc(NewMatchCount);
- if AdditionalCommandsMatchList = [] then
- begin
- for I := FirstMatchIndex to FCommands.Count - 1 do
- if AnsiStartsText(NewInputLine, FCommands[I].FCommandName) then
- Inc(NewMatchCount);
- end
- else if CommandsMatchList <> [] then
- begin
- for I := 0 to FCommands.Count - 1 do
- if AnsiStartsText(NewInputLine, FCommands[I].FCommandName) then
- Inc(NewMatchCount);
- end;
- end;
- FInputLine := NewInputLine;
- if NewMatchCount <> MatchCount then
- Delete(FInputLine, Length(NewInputLine), 1);
- end;
- //Restore the #13 key
- if HasEnterKey then
- FInputLine := FInputLine + #13;
- end;
- end;
- {$WARNINGS on}
- procedure TgxCustomConsole.AutoCompleteCommand;
- var
- MatchCount: Integer;
- AdditionalCommandsMatchList: TgxConsoleMatchList;
- CommandsMatchList: TgxConsoleMatchList;
- begin
- AutoCompleteCommand(MatchCount, AdditionalCommandsMatchList,
- CommandsMatchList);
- end;
- procedure TgxCustomConsole.RegisterBuiltInCommands;
- begin
- { Special commands }
- with FCommands.Add do
- begin
- FCommandName := '?';
- FShortHelp := 'displays help for a single command or all commands';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandHelp;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'Help';
- FShortHelp := 'displays help for a single command or all commands';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandHelp;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'cls';
- FShortHelp := 'clears screen';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandClearScreen;
- end;
- { Console commands }
- with FCommands.Add do
- begin
- FCommandName := 'Console.Hide';
- FShortHelp := 'hides the console';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandConsoleHide;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'Console.Color';
- FShortHelp := 'displays and allows to change the color of the console';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandConsoleColor;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'Console.Ren';
- FShortHelp := 'renames any command';
- // FLongHelp.Add('') not needed here, because is has an OnHelp event
- FOnCommand := ProcessInternalCommandConsoleRename;
- FOnHelp := GetHelpInternalCommandRename;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'Console.ClearTypedCommands';
- FShortHelp := 'clears Typed Commands list';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandConsoleClearTypedCommands;
- end;
- { System commands }
- with FCommands.Add do
- begin
- FCommandName := 'System.Time';
- FShortHelp := 'displays current system time';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandSystemTime;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'System.Date';
- FShortHelp := 'displays current system date';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandSystemDate;
- end;
- { Viewer commands }
- with FCommands.Add do
- begin
- FCommandName := 'Viewer.FPS';
- FShortHelp := 'displays GLXceneViewer FPS';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandViewerFPS;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'Viewer.ResetPerformanceMonitor';
- FShortHelp := 'resets GLXceneViewer FPS monitor';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandViewerResetPerformanceMonitor;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'Viewer.VSync';
- FShortHelp := 'displays and allows to change GLXceneViewer VSync';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandViewerVSync;
- end;
- with FCommands.Add do
- begin
- FCommandName := 'Viewer.AntiAliasing';
- FShortHelp := 'displays and allows to change GLXceneViewer AntiAliasing';
- FLongHelp.Add(FShortHelp);
- FOnCommand := ProcessInternalCommandViewerAntiAliasing;
- end;
- end;
- procedure TgxCustomConsole.HandleUnknownCommand(const Command: string);
- begin
- AddLine(' - Command "' + Command + '" not recognized!');
- if coShowConsoleHelpIfUnknownCommand in FOptions then
- ShowConsoleHelp;
- end;
- procedure TgxCustomConsole.NavigateDown;
- begin
- Inc(FStartLine);
- if FStartLine > FColsoleLog.Count - numlines then
- FStartLine := FColsoleLog.Count - numlines;
- if FStartLine < 0 then
- FStartLine := 0;
- end;
- procedure TgxCustomConsole.NavigatePageDown;
- begin
- Inc(FStartLine, NumLines);
- if FStartLine > FColsoleLog.Count - numlines then
- FStartLine := FColsoleLog.Count - numlines;
- if FStartLine < 0 then
- FStartLine := 0;
- end;
- procedure TgxCustomConsole.NavigatePageUp;
- begin
- Dec(FStartLine, NumLines);
- if FStartLine > FColsoleLog.Count - numlines then
- FStartLine := FColsoleLog.Count - numlines;
- if FStartLine < 0 then
- FStartLine := 0;
- end;
- procedure TgxCustomConsole.NavigateUp;
- begin
- Dec(FStartLine);
- if FStartLine > FColsoleLog.Count - numlines then
- FStartLine := FColsoleLog.Count - numlines;
- if FStartLine < 0 then
- FStartLine := 0;
- end;
- function TgxCustomConsole.GetFontColor: TColor;
- begin
- Result := FHUDText.ModulateColor.AsWinColor;
- end;
- function TgxCustomConsole.GetHUDSpriteColor: TColor;
- begin
- if Assigned(HUDSprite.Material.MaterialLibrary)
- and (HUDSprite.Material.MaterialLibrary is TgxMaterialLibrary)
- and (HUDSprite.Material.LibMaterialName <> '') then
- Result :=
- TgxMaterialLibrary(HUDSprite.Material.MaterialLibrary).LibMaterialByName(HUDSprite.Material.LibMaterialName).Material.FrontProperties.Ambient.AsWinColor
- else
- Result := HUDSprite.Material.FrontProperties.Ambient.AsWinColor;
- end;
- procedure TgxCustomConsole.SetHUDSpriteColor(const Color: TColor);
- begin
- if Assigned(HUDSprite.Material.MaterialLibrary)
- and (HUDSprite.Material.MaterialLibrary is TgxMaterialLibrary)
- and (HUDSprite.Material.LibMaterialName <> '') then
- TgxMaterialLibrary(HUDSprite.Material.MaterialLibrary).LibMaterialByName(HUDSprite.Material.LibMaterialName).Material.FrontProperties.Ambient.AsWinColor := Color
- else
- HUDSprite.Material.FrontProperties.Ambient.AsWinColor := Color;
- end;
- procedure TgxCustomConsole.SetSize(const Value: Single);
- begin
- if (Value <= 0) or (Value > 1) then
- raise EGLConsoleException.Create('Size must be between 0 and 1!')
- else
- begin
- FSize := Value;
- RefreshHudSize;
- end;
- end;
- procedure TgxCustomConsole.DoOnCommandIssued(var UserInputCommand:
- TgxUserInputCommand);
- begin
- if Assigned(FOnCommandIssued) then
- FOnCommandIssued(nil, Self, UserInputCommand);
- end;
- procedure TgxCustomConsole.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited;
- if Operation = opRemove then
- begin
- if AComponent = FSceneViewer then
- FSceneViewer := nil;
- if AComponent = FHudSprite then
- FHudSprite := nil;
- if AComponent = FHudText then
- FHudText := nil;
- end;
- end;
- procedure TgxCustomConsole.SetSceneViewer(
- const Value: TgxSceneViewer);
- begin
- if FSceneViewer <> nil then
- FSceneViewer.RemoveFreeNotification(Self);
- FSceneViewer := Value;
- if FSceneViewer <> nil then
- begin
- FSceneViewer.FreeNotification(Self);
- RefreshHudSize;
- end;
- end;
- function TgxCustomConsole.GetFont: TgxCustomBitmapFont;
- begin
- Result := FHudText.BitmapFont;
- end;
- procedure TgxCustomConsole.SetFont(const Value: TgxCustomBitmapFont);
- begin
- FHudText.BitmapFont := Value;
- end;
- procedure TgxCustomConsole.SetName(const Value: TComponentName);
- begin
- inherited;
- FHudSprite.Name := Value + 'HudSprite';
- FHudText.Name := Value + 'HudText';
- end;
- { TgxConsoleControls }
- procedure TgxConsoleControls.Assign(Source: TPersistent);
- begin
- if Source is TgxConsoleControls then
- begin
- FNavigateUp := TgxConsoleControls(Source).FNavigateUp;
- FNavigateDown := TgxConsoleControls(Source).FNavigateDown;
- FNavigatePageUp := TgxConsoleControls(Source).FNavigatePageUp;
- FNavigatePageDown := TgxConsoleControls(Source).FNavigatePageDown;
- FNextCommand := TgxConsoleControls(Source).FNextCommand;
- FPreviousCommand := TgxConsoleControls(Source).FPreviousCommand;
- FAutoCompleteCommand := TgxConsoleControls(Source).FAutoCompleteCommand;
- FDblClickDelay := TgxConsoleControls(Source).FDblClickDelay;
- end;
- end;
- constructor TgxConsoleControls.Create(AOwner: TPersistent);
- begin
- FOwner := AOwner;
- FNavigateUp := VK_HOME;
- FNavigateDown := VK_END;
- FNavigatePageUp := VK_PRIOR;
- FNavigatePageDown := VK_NEXT;
- FNextCommand := VK_DOWN;
- FPreviousCommand := VK_UP;
- FAutoCompleteCommand := VK_CONTROL;
- FDblClickDelay := 300;
- end;
- function TgxConsoleControls.GetOwner: TPersistent;
- begin
- Result := FOwner;
- end;
- { TgxConsoleCommand }
- procedure TgxConsoleCommand.Assign(Source: TPersistent);
- begin
- Assert(Source <> nil);
- inherited;
- SetCommandName(TgxConsoleCommand(Source).FCommandName);
- FShortHelp := TgxConsoleCommand(Source).FShortHelp;
- FLongHelp.Assign(TgxConsoleCommand(Source).FLongHelp);
- FVisible := TgxConsoleCommand(Source).FVisible;
- FEnabled := TgxConsoleCommand(Source).FEnabled;
- FSilentDisabled := TgxConsoleCommand(Source).FSilentDisabled;
- end;
- constructor TgxConsoleCommand.Create(Collection: TCollection);
- begin
- inherited;
- Assert((Collection is TgxConsoleCommandList) or (Collection = nil));
- FCommandList := TgxConsoleCommandList(Collection);
- FLongHelp := TStringList.Create;
- FVisible := True;
- FEnabled := True;
- end;
- destructor TgxConsoleCommand.Destroy;
- begin
- FLongHelp.Destroy;
- inherited;
- end;
- procedure TgxConsoleCommand.ShowInvalidUseOfCommandError;
- begin
- FCommandList.FConsole.AddLine(' - Invalid use of command!');
- end;
- procedure TgxConsoleCommand.ShowInvalidNumberOfArgumentsError(const
- ShowHelpAfter: Boolean);
- begin
- FCommandList.FConsole.AddLine(' - Invalid number of arguments!');
- if ShowHelpAfter then
- ShowHelp;
- end;
- procedure TgxConsoleCommand.SetCommandName(const Value: string);
- begin
- //the name must be unique
- if FCommandList.CommandExists(Value) or
- FCommandList.FConsole.FAdditionalCommands.CommandExists(Value) then
- begin
- raise EGLConsoleException.Create(STR_NO_DUPLICATE_NAMES_ALLOWED);
- Exit;
- end;
- FCommandName := Value;
- end;
- procedure TgxConsoleCommand.ShowHelp;
- var
- I: Integer;
- begin
- if Assigned(FOnHelp) then
- FOnHelp(Self)
- else if FLongHelp.Count <> 0 then
- for I := 0 to FLongHelp.Count - 1 do
- FCommandList.FConsole.AddLine(' - ' + FLongHelp[I]);
- end;
- procedure TgxConsoleCommand.DoOnCommand(var UserInputCommand:
- TgxUserInputCommand);
- begin
- Assert(Assigned(FOnCommand));
- if FEnabled then
- FOnCommand(Self, FCommandList.FConsole, UserInputCommand)
- else
- begin
- if not FSilentDisabled then
- FCommandList.FConsole.AddLine(' - Command "' + FCommandName +
- '" has been disabled!');
- end;
- end;
- procedure TgxConsoleCommand.ShowShortHelp;
- begin
- if FVisible then
- FCommandList.FConsole.AddLine(' - ' + FCommandName + ' - ' + FShortHelp);
- end;
- function TgxConsoleCommand.GetDisplayName: string;
- begin
- if FCommandName = '' then
- Result := inherited GetDisplayName
- else
- Result := FCommandName;
- end;
- { TgxConsoleCommandList }
- function TgxConsoleCommandList.Add: TgxConsoleCommand;
- begin
- Result := TgxConsoleCommand(inherited Add);
- end;
- constructor TgxConsoleCommandList.Create(const AOwner: TgxCustomConsole);
- begin
- Assert(AOwner <> nil);
- FConsole := TgxCustomConsole(AOwner);
- inherited Create(TgxConsoleCommand);
- end;
- destructor TgxConsoleCommandList.Destroy;
- begin
- Clear;
- inherited;
- end;
- function TgxConsoleCommandList.GetItems(const Index: Integer):
- TgxConsoleCommand;
- begin
- Result := TgxConsoleCommand(inherited Items[Index]);
- end;
- function TgxConsoleCommandList.LastConsoleCommand: TgxConsoleCommand;
- begin
- Result := GetItems(Count - 1);
- end;
- procedure TgxConsoleCommandList.SortCommands(const Ascending: Boolean);
- begin
- Assert(False, 'Not implemented yet....');
- end;
- function TgxConsoleCommandList.CommandExists(const Command: string): Boolean;
- var
- I: Integer;
- begin
- Result := True;
- if Count <> 0 then
- for I := 0 to Count - 1 do
- if GetItems(I).FCommandName = Command then
- Exit;
- Result := False;
- end;
- function TgxConsoleCommandList.GetCommandIndex(const Command: string): Integer;
- begin
- if Count <> 0 then
- for Result := 0 to Count - 1 do
- if GetItems(Result).FCommandName = Command then
- Exit;
- Result := -1;
- end;
- function TgxConsoleCommandList.GetOwner: TPersistent;
- begin
- Result := FConsole;
- end;
- { TgxConsoleStringList }
- procedure TgxConsoleStringList.Changed;
- begin
- inherited;
- //we'll just assume that user added a command and check it,
- //other cases are not dealt with
- if Count = 0 then
- Exit;
- //check if this command does not duplicate any existing
- if FConsole.FCommands.CommandExists(Strings[Count - 1]) then
- Delete(Count - 1);
- end;
- function TgxConsoleStringList.CommandExists(const Command: string): Boolean;
- begin
- Result := IndexOf(Command) <> -1;
- end;
- constructor TgxConsoleStringList.Create(const Owner: TgxCustomConsole);
- begin
- Assert(Owner <> nil);
- Duplicates := dupError;
- FConsole := Owner;
- end;
- function TgxConsoleStringList.GetOwner: TPersistent;
- begin
- Result := FConsole;
- end;
- initialization
- RegisterClasses([TgxCustomConsole, TgxConsole, TgxConsoleStringList,
- TgxConsoleCommand, TgxConsoleCommandList, TgxConsoleControls]);
- end.
|