From 966184fd0a39f68db299e011e04e9b9fded9ae98 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Sun, 16 Feb 2014 17:45:54 +0000 Subject: [PATCH] Overhaul of the profile management --- G940LEDControl/Forms/ButtonAssignmentFrm.dfm | 45 + G940LEDControl/Forms/ButtonAssignmentFrm.pas | 87 ++ G940LEDControl/Forms/MainFrm.dfm | 900 +++++++++++------- G940LEDControl/Forms/MainFrm.pas | 364 ++++--- G940LEDControl/G940LEDControl.dpr | 7 +- G940LEDControl/G940LEDControl.dproj | 7 +- G940LEDControl/G940LEDControl.res | Bin 28524 -> 27760 bytes .../Resources/Icons/DeleteProfile.ico | Bin 0 -> 1406 bytes G940LEDControl/Resources/Icons/NewProfile.ico | Bin 0 -> 1406 bytes .../Resources/Icons/RenameProfile.ico | Bin 0 -> 1406 bytes .../Resources/Icons/RevertProfile.ico | Bin 0 -> 1406 bytes .../Resources/Icons/SaveProfile.ico | Bin 0 -> 1406 bytes .../Resources/Icons/SetActiveProfile.ico | Bin 0 -> 1406 bytes G940LEDControl/Units/FSXSimConnectClient.pas | 17 +- G940LEDControl/Units/Profile.pas | 17 +- G940LEDControl/Units/ProfileManager.pas | 175 ++-- 16 files changed, 1007 insertions(+), 612 deletions(-) create mode 100644 G940LEDControl/Forms/ButtonAssignmentFrm.dfm create mode 100644 G940LEDControl/Forms/ButtonAssignmentFrm.pas create mode 100644 G940LEDControl/Resources/Icons/DeleteProfile.ico create mode 100644 G940LEDControl/Resources/Icons/NewProfile.ico create mode 100644 G940LEDControl/Resources/Icons/RenameProfile.ico create mode 100644 G940LEDControl/Resources/Icons/RevertProfile.ico create mode 100644 G940LEDControl/Resources/Icons/SaveProfile.ico create mode 100644 G940LEDControl/Resources/Icons/SetActiveProfile.ico diff --git a/G940LEDControl/Forms/ButtonAssignmentFrm.dfm b/G940LEDControl/Forms/ButtonAssignmentFrm.dfm new file mode 100644 index 0000000..15f4d67 --- /dev/null +++ b/G940LEDControl/Forms/ButtonAssignmentFrm.dfm @@ -0,0 +1,45 @@ +object ButtonAssignmentFrame: TButtonAssignmentFrame + Left = 0 + Top = 0 + Width = 261 + Height = 41 + TabOrder = 0 + DesignSize = ( + 261 + 41) + object lblFunction: TLabel + Left = 53 + Top = 6 + Width = 208 + Height = 13 + Anchors = [akLeft, akTop, akRight] + AutoSize = False + Caption = '[runtime: function]' + EllipsisPosition = epEndEllipsis + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + end + object lblCategory: TLabel + Left = 53 + Top = 22 + Width = 208 + Height = 13 + Anchors = [akLeft, akTop, akRight] + AutoSize = False + Caption = '[runtime: category]' + EllipsisPosition = epEndEllipsis + end + object btnConfiguration: TButton + Left = 0 + Top = 0 + Width = 41 + Height = 41 + Caption = 'P&?' + TabOrder = 0 + OnClick = btnConfigurationClick + end +end diff --git a/G940LEDControl/Forms/ButtonAssignmentFrm.pas b/G940LEDControl/Forms/ButtonAssignmentFrm.pas new file mode 100644 index 0000000..123cdb3 --- /dev/null +++ b/G940LEDControl/Forms/ButtonAssignmentFrm.pas @@ -0,0 +1,87 @@ +unit ButtonAssignmentFrm; + +interface +uses + System.Classes, + Vcl.Controls, + Vcl.Forms, + Vcl.StdCtrls; + + +type + TButtonAssignmentFrame = class(TFrame) + btnConfiguration: TButton; + lblFunction: TLabel; + lblCategory: TLabel; + + procedure btnConfigurationClick(Sender: TObject); + private + FLEDIndex: Integer; + FOnConfigurationClick: TNotifyEvent; + + function GetCategoryName: string; + function GetFunctionName: string; + procedure SetCategoryName(const Value: string); + procedure SetFunctionName(const Value: string); + public + constructor Create(AOwner: TComponent); override; + + property LEDIndex: Integer read FLEDIndex write FLEDIndex; + property CategoryName: string read GetCategoryName write SetCategoryName; + property FunctionName: string read GetFunctionName write SetFunctionName; + + property OnConfigurationClick: TNotifyEvent read FOnConfigurationClick write FOnConfigurationClick; + end; + + +implementation +uses + Graphics; + + +{$R *.dfm} + + +{ TButtonAssignmentFrame } +constructor TButtonAssignmentFrame.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + lblCategory.Font.Color := clGrayText; + + SetCategoryName(''); + SetFunctionName(''); +end; + + +function TButtonAssignmentFrame.GetCategoryName: string; +begin + Result := lblCategory.Caption; +end; + + +function TButtonAssignmentFrame.GetFunctionName: string; +begin + Result := lblFunction.Caption; +end; + + +procedure TButtonAssignmentFrame.SetCategoryName(const Value: string); +begin + lblCategory.Caption := Value; +end; + + +procedure TButtonAssignmentFrame.SetFunctionName(const Value: string); +begin + lblFunction.Caption := Value; +end; + + +procedure TButtonAssignmentFrame.btnConfigurationClick(Sender: TObject); +begin + if Assigned(FOnConfigurationClick) then + FOnConfigurationClick(Self); +end; + +end. diff --git a/G940LEDControl/Forms/MainFrm.dfm b/G940LEDControl/Forms/MainFrm.dfm index c2798a3..5122427 100644 --- a/G940LEDControl/Forms/MainFrm.dfm +++ b/G940LEDControl/Forms/MainFrm.dfm @@ -1,12 +1,11 @@ object MainForm: TMainForm Left = 0 Top = 0 - ActiveControl = cbProfileMenu BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle Caption = 'G940 LED Control' - ClientHeight = 548 - ClientWidth = 466 + ClientHeight = 504 + ClientWidth = 598 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -23,360 +22,215 @@ object MainForm: TMainForm AlignWithMargins = True Left = 8 Top = 60 - Width = 450 - Height = 480 + Width = 582 + Height = 436 Margins.Left = 8 Margins.Top = 8 Margins.Right = 8 Margins.Bottom = 8 - ActivePage = tsConfiguration + ActivePage = tsButtons Align = alClient TabOrder = 0 object tsButtons: TTabSheet Caption = ' Button assignment ' - DesignSize = ( - 442 - 452) - object lblP1Function: TLabel - Left = 64 - Top = 73 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP1Category: TLabel - Left = 64 - Top = 89 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblP2Function: TLabel - Left = 64 - Top = 120 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP2Category: TLabel - Left = 64 - Top = 136 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblP3Function: TLabel - Left = 64 - Top = 167 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP3Category: TLabel - Left = 64 - Top = 183 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblP4Function: TLabel - Left = 64 - Top = 214 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP4Category: TLabel - Left = 64 - Top = 230 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblP5Function: TLabel - Left = 64 - Top = 261 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP5Category: TLabel - Left = 64 - Top = 277 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblP6Function: TLabel - Left = 64 - Top = 308 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP6Category: TLabel - Left = 64 - Top = 324 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblP7Function: TLabel - Left = 64 - Top = 355 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP7Category: TLabel - Left = 64 - Top = 371 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblP8Function: TLabel - Left = 64 - Top = 402 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: function]' - EllipsisPosition = epEndEllipsis - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - ExplicitWidth = 364 - end - object lblP8Category: TLabel - Left = 64 - Top = 418 - Width = 365 - Height = 13 - Anchors = [akLeft, akTop, akRight] - AutoSize = False - Caption = '[runtime: category]' - EllipsisPosition = epEndEllipsis - ExplicitWidth = 364 - end - object lblProfile: TLabel - Left = 11 - Top = 19 - Width = 30 - Height = 13 - Caption = 'Profile' - end - object bvlProfiles: TBevel - Left = 11 - Top = 52 - Width = 418 - Height = 13 - Shape = bsTopLine - end - object btnP1: TButton - Left = 11 - Top = 67 - Width = 41 + inline bafP1: TButtonAssignmentFrame + Left = 267 + Top = 30 + Width = 261 Height = 41 - Caption = 'P&1' - TabOrder = 3 - end - object btnP2: TButton - Left = 11 - Top = 114 - Width = 41 - Height = 41 - Caption = 'P&2' - TabOrder = 4 - end - object btnP3: TButton - Left = 11 - Top = 161 - Width = 41 - Height = 41 - Caption = 'P&3' - TabOrder = 5 - end - object btnP4: TButton - Left = 11 - Top = 208 - Width = 41 - Height = 41 - Caption = 'P&4' - TabOrder = 6 - end - object btnP5: TButton - Left = 11 - Top = 255 - Width = 41 - Height = 41 - Caption = 'P&5' - TabOrder = 7 - end - object btnP6: TButton - Left = 11 - Top = 302 - Width = 41 - Height = 41 - Caption = 'P&6' - TabOrder = 8 - end - object btnP7: TButton - Left = 11 - Top = 349 - Width = 41 - Height = 41 - Caption = 'P&7' - TabOrder = 9 - end - object btnP8: TButton - Left = 11 - Top = 396 - Width = 41 - Height = 41 - Caption = 'P&8' - TabOrder = 10 - end - object cmbProfiles: TComboBox - Left = 64 - Top = 16 - Width = 208 - Height = 21 - Style = csDropDownList - Anchors = [akLeft, akTop, akRight] - Sorted = True TabOrder = 0 - OnClick = cmbProfilesClick + ExplicitLeft = 267 + ExplicitTop = 30 + inherited btnConfiguration: TButton + Caption = 'P&1' + end end - object btnSaveProfile: TButton - Left = 279 - Top = 15 - Width = 72 - Height = 23 - Anchors = [akTop, akRight] - Caption = 'Sa&ve As...' + inline bafP2: TButtonAssignmentFrame + Left = 267 + Top = 77 + Width = 261 + Height = 41 TabOrder = 1 - OnClick = btnSaveProfileClick + ExplicitLeft = 267 + ExplicitTop = 77 + inherited btnConfiguration: TButton + Caption = 'P&2' + end end - object btnDeleteProfile: TButton - Left = 357 - Top = 15 - Width = 72 - Height = 23 - Anchors = [akTop, akRight] - Caption = '&Delete' + inline bafP3: TButtonAssignmentFrame + Left = 267 + Top = 124 + Width = 261 + Height = 41 TabOrder = 2 - OnClick = btnDeleteProfileClick + ExplicitLeft = 267 + ExplicitTop = 124 + inherited btnConfiguration: TButton + Caption = 'P&3' + end + end + inline bafP4: TButtonAssignmentFrame + Left = 267 + Top = 171 + Width = 261 + Height = 41 + TabOrder = 3 + ExplicitLeft = 267 + ExplicitTop = 171 + inherited btnConfiguration: TButton + Caption = 'P&4' + end + end + inline bafP5: TButtonAssignmentFrame + Left = 267 + Top = 218 + Width = 261 + Height = 41 + TabOrder = 4 + ExplicitLeft = 267 + ExplicitTop = 218 + inherited btnConfiguration: TButton + Caption = 'P&5' + end + end + inline bafP6: TButtonAssignmentFrame + Left = 267 + Top = 265 + Width = 261 + Height = 41 + TabOrder = 5 + ExplicitLeft = 267 + ExplicitTop = 265 + inherited btnConfiguration: TButton + Caption = 'P&6' + end + end + inline bafP7: TButtonAssignmentFrame + Left = 267 + Top = 312 + Width = 261 + Height = 41 + TabOrder = 6 + ExplicitLeft = 267 + ExplicitTop = 312 + inherited btnConfiguration: TButton + Caption = 'P&7' + end + end + inline bafP8: TButtonAssignmentFrame + Left = 267 + Top = 359 + Width = 261 + Height = 41 + TabOrder = 7 + ExplicitLeft = 267 + ExplicitTop = 359 + inherited btnConfiguration: TButton + Caption = 'P&8' + end + end + object pnlProfiles: TPanel + AlignWithMargins = True + Left = 8 + Top = 8 + Width = 245 + Height = 392 + Margins.Left = 8 + Margins.Top = 8 + Margins.Right = 8 + Margins.Bottom = 8 + Align = alLeft + BevelOuter = bvNone + TabOrder = 8 + object vstProfile: TVirtualStringTree + Left = 0 + Top = 22 + Width = 245 + Height = 370 + Align = alClient + Header.AutoSizeIndex = 0 + Header.Font.Charset = DEFAULT_CHARSET + Header.Font.Color = clWindowText + Header.Font.Height = -11 + Header.Font.Name = 'Tahoma' + Header.Font.Style = [] + Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible] + PopupMenu = pmnProfiles + TabOrder = 0 + Columns = < + item + Position = 0 + Width = 241 + WideText = 'Profile' + end> + end + object tbProfiles: TToolBar + Left = 0 + Top = 0 + Width = 245 + Height = 22 + AutoSize = True + ButtonWidth = 60 + Images = ImageList + List = True + ParentShowHint = False + AllowTextButtons = True + ShowHint = True + TabOrder = 1 + object tbNewProfile: TToolButton + Left = 0 + Top = 0 + Action = actNewProfile + AutoSize = True + end + object tbRenameProfile: TToolButton + Left = 24 + Top = 0 + Action = actRenameProfile + AutoSize = True + end + object tbSaveProfile: TToolButton + Left = 48 + Top = 0 + Action = actSaveProfile + AutoSize = True + Style = tbsTextButton + end + object tbRevertProfile: TToolButton + Left = 103 + Top = 0 + Action = actRevertProfile + AutoSize = True + Style = tbsTextButton + end + object tbDeleteProfile: TToolButton + Left = 167 + Top = 0 + Action = actDeleteProfile + AutoSize = True + end + object ToolButton1: TToolButton + Left = 191 + Top = 0 + Width = 8 + Caption = 'ToolButton1' + ImageIndex = 4 + Style = tbsSeparator + end + object tbSetActiveProfile: TToolButton + Left = 199 + Top = 0 + Action = actSetActiveProfile + end + end end end object tsConfiguration: TTabSheet Caption = ' Configuration ' ImageIndex = 2 object lblProfileSwitching: TLabel - Left = 11 - Top = 19 + Left = 16 + Top = 16 Width = 92 Height = 13 Caption = 'Profile switching' @@ -388,15 +242,15 @@ object MainForm: TMainForm ParentFont = False end object bvlProfileSwitching: TBevel - Left = 224 - Top = 26 - Width = 205 + Left = 229 + Top = 23 + Width = 337 Height = 13 Shape = bsTopLine end object cbProfileMenu: TCheckBox - Left = 11 - Top = 44 + Left = 16 + Top = 41 Width = 409 Height = 17 Caption = ' Add profile selection to FSX "Add-ons" menu' @@ -406,8 +260,8 @@ object MainForm: TMainForm OnClick = cbProfileMenuClick end object cbProfileMenuCascaded: TCheckBox - Left = 31 - Top = 67 + Left = 36 + Top = 64 Width = 389 Height = 17 Caption = ' Cascaded menu (profiles in "G940 Profile" submenu)' @@ -511,7 +365,7 @@ object MainForm: TMainForm OnClick = cbCheckUpdatesClick end object btnCheckUpdates: TButton - Left = 344 + Left = 461 Top = 340 Width = 83 Height = 25 @@ -525,14 +379,14 @@ object MainForm: TMainForm AlignWithMargins = True Left = 3 Top = 3 - Width = 460 + Width = 592 Height = 46 Align = alTop BevelOuter = bvNone TabOrder = 1 object pnlFSX: TPanel AlignWithMargins = True - Left = 233 + Left = 365 Top = 3 Width = 224 Height = 40 @@ -696,7 +550,7 @@ object MainForm: TMainForm AlignWithMargins = True Left = 3 Top = 3 - Width = 224 + Width = 356 Height = 40 Align = alClient BevelOuter = bvNone @@ -1054,4 +908,354 @@ object MainForm: TMainForm end end end + object TrayIcon: TTrayIcon + Left = 120 + Top = 400 + end + object ActionList: TActionList + Images = ImageList + Left = 48 + Top = 400 + object actNewProfile: TAction + Caption = '&New' + Hint = 'Create a new profile based on the currently selected profile' + ImageIndex = 0 + ShortCut = 16462 + OnExecute = actNewProfileExecute + end + object actSaveProfile: TAction + Caption = '&Save' + Hint = 'Save the changes to the profile' + ImageIndex = 2 + ShortCut = 16467 + OnExecute = actSaveProfileExecute + end + object actRevertProfile: TAction + Caption = '&Revert' + Hint = 'Revert the changes to the profile since it was last saved' + ImageIndex = 3 + ShortCut = 16466 + OnExecute = actRevertProfileExecute + end + object actRenameProfile: TAction + Caption = '&Rename' + Hint = 'Rename the selected profile' + ImageIndex = 1 + ShortCut = 113 + OnExecute = actRenameProfileExecute + end + object actDeleteProfile: TAction + Caption = '&Delete' + Hint = 'Delete the selected profile' + ImageIndex = 4 + ShortCut = 16430 + OnExecute = actDeleteProfileExecute + end + object actSetActiveProfile: TAction + Caption = 'Set &active' + Hint = 'Set the selected profile as the active profile' + ImageIndex = 5 + ShortCut = 16397 + OnExecute = actSetActiveProfileExecute + end + end + object ImageList: TImageList + Left = 192 + Top = 400 + Bitmap = { + 494C010106000900040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000002000000001002000000000000020 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000002427AE00161C + AC005A5AA90000000000000000000000000000000000000000005353A9004F4F + A200000000000000000000000000000000000000000000000000000000000000 + 0000000000005C8F5C002979270014700D0014700D00277525005C8F5C000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000004E4EAB001844F600194D + F8001031D2002427AE000000000000000000000000004E4EAB000928D700092E + D7000313B3004E4EAB0000000000000000000000000000000000000000000000 + 00000F7D0F00088800000888000013880000217D000032720000266D0000126D + 0D00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000002022B1002451F9001F51 + FF00194DF8001744E8001017AF00000000004545AD00092ED7001142F9000D3D + F5000D3DF500041ABC006F6FAA00000000000000000000000000000000000585 + 070004A00800009D010004A00800009D0100009D0100009500001E7E0000396B + 0000106902000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000001832DB00285A + FF002451F9002451F9001A4AF100060EAF000F30DD00164AFE001142F9001041 + F6000D3DF5000D3DF5002C2CA200000000000000000000000000158816000BA8 + 170004A0080036C15400DCF3E9007ADD9B00009D010000950000009D01001285 + 0000396B0000126D0D0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000007777B3001832DB004170 + FF002D5DFF00285AFF00285AFF001F51FF00194DF800194DF8001142F9001142 + F9000F3DF200161CAC000000000000000000000000006097600024A82F0008A9 + 1B002BB43E00F6F0F500FCF6FA00FFFEFF007ADD9B00009E0700009D01000095 + 0000217D0000266D00005C8F5C00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000006969B8001A25 + C5003A6DFF003668FF00285AFF00285AFF002451F900194DF8001F51FF00123D + ED002427AE00000000000000000000000000000000002C8E2B0039BF4F0024A8 + 2F00ECE6EA00F5EEF400FCF6FA00FFFEFF00FFFEFF007ADD9B00009E0700009D + 0100009500003671000027752500000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00002F2FB3002E4EE7003668FF00285AFF00285AFF002451F900123DED002C2C + A20000000000000000000000000000000000000000001E93220039BF4F00AAC9 + A700FAEAF900D1E1D1001EAF3300DAEEDD00FFFEFF00FFFEFF007ADD9B00009E + 0700009D0100297C000014700D00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000253FDF003A6DFF003668FF002D5DFF00285AFF001B46EA002427 + AE000000000000000000000000000000000000000000219624005DD27C0017A3 + 25008EBF880011AB24001BB940000BAC2600DAEEDD00FFFEFF00FFFEFF007ADD + 9B00009D01001B86000014700D00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00002B2CC0004B7CFF004170FF003A6DFF003A6DFF00285AFF00285AFF001031 + D2004A4AB200000000000000000000000000000000002C922C0077DC95002CC5 + 59001BB940002CC5590026C04E0022BB45000BAC2600DAEEDD00FFFEFF00FFFE + FF0078DB960013880000267D2600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000253FDF00527CFA004170FF003668FF000C13C1003A6DFF00285AFF002451 + F9000B1DC20000000000000000000000000000000000629C620053C66C0061D8 + 890031CA630031CA63002CC5590026C04E0022BB45000BAC2600DAEEDD00FCF6 + FA00CAECD7000E8E08005C905C00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000004F4F + BD00527CFA005080FF004B7CFF00181FC500000000001B22C4003A6DFF00285A + FF001A4AF1001419B100000000000000000000000000000000001E9A230083E5 + A7004CD3790031CA630031CA630027C3530022BB45001CB53A000BA81F007ACC + 850011AB24000F7D0F0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000252D + D6006A9CFF005788FF002E4EE7007070B90000000000000000001621C7002D5D + FF002451F9001439DD004545AD000000000000000000000000000000000024A4 + 2D0081E3A6005ED8880031CA630027C3530022BB45001CB53A0016B02E000BAC + 2600058A08000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000004B4B + C8003951E2005080FF002929C600000000000000000000000000000000001628 + D300285AFF000F2EE3002123B500000000000000000000000000000000000000 + 00001E9A230056CA730077E09C005DD27C0043C8660036C154001EAA2F001588 + 1600000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000003E3EB90000000000000000000000000000000000000000006B6B + B6002E2EB5000000000000000000000000000000000000000000000000000000 + 000000000000629C62002C922C00229A28001E9322002C922C00609960000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000009B7C6C009B7C + 6C009B7C6C009B7C6C009B7C6C009B7C6C009B7C6C009B7C6C009B7C6C009B7C + 6C00987A69009B7C6C00000000000000000000000000000000009A7C6A009A7C + 6A009A7C6A009A7C6A009A7C6A009A7C6A009A7C6A009A7C6A009A7C6A009A7C + 6A009A7C6A009A7C6A0000000000000000000000000000000000AF704E00A747 + 1100895E4600A7ABAB00B9B2AB00C8C7C300C9C9CC00AFAFAF0099A2A8008238 + 0D00A7471100A34B2100A4776300000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000009B7766000000 + 0000FAF4E900FAF4E900FAF4E900FAF4E900FAF3E800FAF3E800FAF3E800F9EF + E000F9EFE00097796700000000000000000000000000000000009B7766000000 + 0000FAF4E900FAF4E900EEE9DE00EEE9DE00EEE9DE00FAF4E900FAF2E500F9EF + E000F8EDDA0097796700000000000000000000000000BC764500BE631700CD78 + 25009E877000B9875900CE700D00DCAF7A00FEFFFF00FEFFFF00D9E2EA00AD70 + 2400DD943500ECBE7500A4440D00000000000000000000000000C5985E00D88D + 2E00C2813000BC976D0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000A27F6F000000 + 0000FCF6EE00FCF6EE00FCF6EE00FAF4E900FAF4E900FAF4E900FAF3E800FAF3 + E800F8EDDA00987A690000000000000000000000000000000000A27F6F000000 + 0000DDC2B500DDC2B500B5A9A400B1A19A00DDC2B500DCBBA900DCBAA500DCBA + A500FAF2E50097796700000000000000000000000000CA680C00C0702800C36C + 1E00A7876B00AE7C5A00BA580800C69A6C00D9DFE500F9F9F900F9FFFF00A363 + 1D00D4852D00E5AF6900A4440D00000000000000000000000000DB963800FFE2 + C300F6C69400EAA04B00D8852500C28649000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000A38070000000 + 0000FCF8F100FCF8F100FCF8F100FCF8F100FAF4E900FAF4E900FAF4E900FAF4 + E900FAF3E8009B7C6C0000000000000000000000000000000000A38070000000 + 0000DDC2B500E9DDDA006F6D7100928B9600C3CDB900EAD8CC00DAB8A500DCBA + A500FAF2E5009A7C6A00000000000000000000000000CA680C00BB682300BF66 + 1900B4906E00B37C6000AF490000B5875E00BFC6CD00D9DFE500FEFFFF00A363 + 1D00D4852D00E5AF6900A4440D00000000000000000000000000E4933600FFD9 + B200FFC79000FFC98E00FFC98E00EFA65800D4802600C7864400000000000000 + 000000000000B6886600B0825D00000000000000000000000000A98778000000 + 0000FCF8F100FCF8F100FCF8F100FCF8F100FCF8F100FCF8F100FAF4E900FAF4 + E900FAF4E9009B7C6C0000000000000000000000000000000000A98778000000 + 0000DECAC600E9DDDA00A8BBCE0034B356002CB4440071B46F00ECDBD200DCBA + A500FAF4E9009A7C6A00000000000000000000000000CA680C00BF661900BF66 + 1900B07D5800C0BFBD00B0ACA80098918B009A8E8400A3978A00AEA79F009058 + 1F00A7672300DA954200A4440D000000000000000000BB926700E8A15000FFD5 + A900FFC48B00FFCD9900FFCD9900FFC58300FFCC8700DE862B00000000000000 + 000000000000B5886800AD683200000000000000000000000000AB897A000000 + 000000000000FCF8F10000000000FCF8F10000000000FCF8F100FCF8F100FAF4 + E900FAF4E9009B7C6C0000000000000000000000000000000000AB897A000000 + 0000DBC7C200E6D7D40099D0A70066FF98005AEC86002EAD460087BE8100EAD8 + CC00FAF4E9009A7C6A00000000000000000000000000C8660900B55D1B00B55D + 1B00B85B0F00BA580800BA580800C2620E00C5671000C8691300C8691300CD78 + 2500D4852D00D3893200A4440D000000000000000000B88C5900FFCD9900FFC4 + 8B00FFC58300FFCD9900DE862B00B9733000C27D3800C0956D00000000000000 + 000000000000B5856200B55B1900000000000000000000000000AB897A000000 + 0000EDEEFB00F1F2FB0000000000FCF8F100FCF8F100FCF8F100FCF8F100FCF8 + F100FAF4E9009B7C6C0000000000000000000000000000000000AB897A000000 + 0000DBC7C200DECAC600DBE4D60056E17D006AFF9D0056E17D002AA43C009CC4 + 9400FCF8F2009A7C6A00000000000000000000000000C8680900B0551400B169 + 3300AE703F00AE703F00B1764100B1764100B1764100B1764100B1764100B47D + 4600BD804100D4852D00A4440D000000000000000000BF813A00FFD9B200FFC5 + 8300FFC48B00FFC18000FEBB7500BF7F3E000000000000000000000000000000 + 000000000000B7754200CB661100000000000000000000000000A69DA900A7B3 + FF008391FE00A6CDFF00C7D1FD00F5F5FB000000000000000000FCF8F100FCF8 + F100FAF4E9009B7C6C0000000000000000000000000000000000B19080000000 + 0000000000000000000000000000D1F8DC0054EE83006AFF9D0050DC7700249E + 3800B7DCB600B69F9400000000000000000000000000C2620E00AF490000B39D + 8900E6F2FB00E4EDF300E4EDF300E4EDF300E4EDF300DDE5EC00D5DEE400D1DC + E600AD9A8A00CD782500A74711000000000000000000CA873800FFD9B200D68B + 3400D4882F00FFD9AE00FEBB7500DE8D3500B996750000000000000000000000 + 000000000000C56E2800CD660D000000000000000000000000007890CE005497 + FF005DB4FF004FA1FF006176FF00C7D1FD0000000000FCF8F100FCF8F100FCF8 + F100FCF8F1009B7C6C0000000000000000000000000000000000AF8F80000000 + 0000DFCDCB00DFCDCB00DECAC600ECDBD200ADEAB9005AF6880064FF970042DA + 690034873E00C6BDB600000000000000000000000000C8660900A8430300B99A + 8400F9FFFF00D5D3D000BDBDBC00C0BFBD00C0BFBD00C2C1C000C9C9CC00DFE3 + E600B19B8500CF7C2200A4440D000000000000000000D58D3D00FFCA9400B082 + 5D00B4835600FDCF9F00FFBF7A00FFB96C00C672240000000000000000000000 + 0000B5856200E87E1500C16115000000000000000000000000003653E20060E1 + FF001DE5FF0057EDFF005DB4FF00A1C0FE00F5F5FB0000000000FCF8F100FAF4 + E900F0E8E000A27F6F0000000000000000000000000000000000B19080000000 + 0000000000000000000000000000000000000000000091EFAC0055FC88009AC1 + A400CDBBB6006E6D8C00000000000000000000000000C8660900A23C0000B99A + 8400FEFFFF00F1F1F100EDEDED00EDEDED00E9E9E900DFE3E600E1E1E100E9E9 + E900AD9A8A00CD792000A4440D000000000000000000C18E5800CE893F000000 + 000000000000C4772600FFE0B900FFB36200FFB15C00D0762100B9703400BA6B + 2D00D9721200FFA22200A76135000000000000000000000000005997EE0057ED + FF0000CDFF003CECFF003A82FF00899BFE00F1F2FB00FCF8F100A3807000A782 + 7000A7827000A380700000000000000000000000000000000000B19080000000 + 0000000000000000000000000000000000000000000000000000A5C5A6000000 + 00007892F500203DDC00292AA1000000000000000000C56206009E370000BD9C + 8A00FEFFFF00DDDCDB00C1C0BF00C2C1C000C2C1C000C2C1C000C9C9CC00E9E9 + E900B39D8900CD792000A4440D00000000000000000000000000000000000000 + 00000000000000000000CD7A2900FFD9B200FFB15C00FFA94800FFA94800FFA1 + 3200FF9D2300E1730E00B58868000000000000000000000000004960DC00499E + FF0063F8FF006DE2FF00437BFF00ADBDFE00FAF8FA0000000000A7827000F5E2 + D900B18E7E00AB9E980000000000000000000000000000000000B89888000000 + 000000000000000000000000000000000000FCF8F20000000000DECAC6008C99 + DE004277FF002D4AD8001F209F000000000000000000C56206009E370000BD9C + 8A00FEFFFF00FEFFFF00EDEDED00F1F1F100EDEDED00DFE3E600E5E4E300E6EA + ED00B5A08900C2701D00A9480D00000000000000000000000000000000000000 + 0000000000000000000000000000C6722400FFCA9400FFD09400FFC17500FFA9 + 3B00EA781100B5704900000000000000000000000000000000008E88BB00668D + FF005D9BFF004E71FF00A6CDFF00E3E8FF000000000000000000A3807000B18E + 7E00AB9E98000000000000000000000000000000000000000000B89888000000 + 0000000000000000000000000000000000000000000000000000B1908000C1B9 + D0003545C5002C30A700000000000000000000000000C260070093280000BD9C + 8A00FEFFFF00DFE3E600D0CFCD00D0CFCD00C9C9CC00D0CFCD00D5D3D000F1F1 + F100B5A089008A4F1400B0551400000000000000000000000000000000000000 + 000000000000000000000000000000000000A8714D00B8652100BC621B00AC5D + 2700B0825D000000000000000000000000000000000000000000C0A8A300ACAB + B500958AB3009D91AF00B29B9F00C0A59700AC887700AC887700A7827000AB9E + 9800000000000000000000000000000000000000000000000000B8988800B898 + 8800B1908000B1908000B1908000B1908000AC887700AC887700A3807000B5A9 + A4000000000000000000000000000000000000000000BF8D5800C0540200C8A4 + 8300D5D3D000D5D4D200D5D4D200D0CFCD00CCCAC800C8C7C300C0BFBD00BDBD + BC00B1947B00C0580200B07D5800000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000200000000100010000000000000100000000000000000000 + 000000000000000000000000FFFFFF00FFFFFFFF00000000C7CFF81F00000000 + 8383F00F000000008101E00700000000C001C003000000008003800100000000 + C007800100000000F00F800100000000F80F800100000000F007800100000000 + F007800100000000E083C00300000000E0C1E00700000000E1E1F00F00000000 + FBE7F81F00000000FFFFFFFF00000000FFFFFFFFFFFFFFFFC003C003C001FFFF + D003D0038001C3FFD003D0038001C0FFD003D0038001C039D003D00380018039 + DA83D00380018039D203D003800180F9C0C3DE0380018079C083D00380018071 + C043DF8380019801C003DFD18001FC01C043DF418001FE03C0C7DFC38001FF07 + C00FC00F8001FFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 + 000000000000} + end + object pmnProfiles: TPopupMenu + Images = ImageList + Left = 48 + Top = 344 + object pmnProfilesSetActive: TMenuItem + Action = actSetActiveProfile + Default = True + end + object pmnProfilesSep1: TMenuItem + Caption = '-' + end + object pmnProfilesNew: TMenuItem + Action = actNewProfile + end + object pmnProfilesSave: TMenuItem + Action = actSaveProfile + end + object pmnProfilesRevert: TMenuItem + Action = actRevertProfile + end + object pmnProfilesDelete: TMenuItem + Action = actDeleteProfile + end + end end diff --git a/G940LEDControl/Forms/MainFrm.pas b/G940LEDControl/Forms/MainFrm.pas index 92b669b..5bdcacf 100644 --- a/G940LEDControl/Forms/MainFrm.pas +++ b/G940LEDControl/Forms/MainFrm.pas @@ -1,7 +1,5 @@ unit MainFrm; -// #ToDo1 -oMvR: 3-3-2013: trigger profile update when Save As only changes the name - interface uses System.Classes, @@ -21,11 +19,12 @@ uses pngimage, X2UtPersistIntf, + ButtonAssignmentFrm, FSXSimConnectIntf, LEDStateConsumer, Profile, ProfileManager, - Settings; + Settings, VirtualTrees, Vcl.ImgList, Vcl.ActnList, Vcl.ToolWin, Vcl.Menus; const @@ -45,13 +44,6 @@ const type - TLEDControls = record - ConfigureButton: TButton; - CategoryLabel: TLabel; - FunctionLabel: TLabel; - end; - - TMainForm = class(TForm, IProfileObserver) imgStateNotFound: TImage; lblG940Throttle: TLabel; @@ -72,35 +64,6 @@ type btnCheckUpdates: TButton; lblProxy: TLabel; tsButtons: TTabSheet; - btnP1: TButton; - lblP1Function: TLabel; - lblP1Category: TLabel; - btnP2: TButton; - lblP2Function: TLabel; - lblP2Category: TLabel; - btnP3: TButton; - lblP3Function: TLabel; - lblP3Category: TLabel; - btnP4: TButton; - lblP4Function: TLabel; - lblP4Category: TLabel; - btnP5: TButton; - lblP5Function: TLabel; - lblP5Category: TLabel; - btnP6: TButton; - lblP6Function: TLabel; - lblP6Category: TLabel; - btnP7: TButton; - lblP7Function: TLabel; - lblP7Category: TLabel; - btnP8: TButton; - lblP8Function: TLabel; - lblP8Category: TLabel; - lblProfile: TLabel; - cmbProfiles: TComboBox; - btnSaveProfile: TButton; - btnDeleteProfile: TButton; - bvlProfiles: TBevel; pnlFSX: TPanel; imgFSXStateNotConnected: TImage; imgFSXStateConnected: TImage; @@ -112,11 +75,44 @@ type cbProfileMenuCascaded: TCheckBox; lblProfileSwitching: TLabel; bvlProfileSwitching: TBevel; + TrayIcon: TTrayIcon; + bafP1: TButtonAssignmentFrame; + bafP2: TButtonAssignmentFrame; + bafP3: TButtonAssignmentFrame; + bafP4: TButtonAssignmentFrame; + bafP5: TButtonAssignmentFrame; + bafP6: TButtonAssignmentFrame; + bafP7: TButtonAssignmentFrame; + bafP8: TButtonAssignmentFrame; + vstProfile: TVirtualStringTree; + pnlProfiles: TPanel; + tbProfiles: TToolBar; + tbNewProfile: TToolButton; + tbSaveProfile: TToolButton; + ActionList: TActionList; + actNewProfile: TAction; + actSaveProfile: TAction; + actRevertProfile: TAction; + tbRevertProfile: TToolButton; + ImageList: TImageList; + tbDeleteProfile: TToolButton; + actDeleteProfile: TAction; + ToolButton1: TToolButton; + tbSetActiveProfile: TToolButton; + actSetActiveProfile: TAction; + pmnProfiles: TPopupMenu; + pmnProfilesNew: TMenuItem; + pmnProfilesSave: TMenuItem; + pmnProfilesRevert: TMenuItem; + pmnProfilesDelete: TMenuItem; + pmnProfilesSetActive: TMenuItem; + pmnProfilesSep1: TMenuItem; + tbRenameProfile: TToolButton; + actRenameProfile: TAction; procedure FormCreate(Sender: TObject); procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType); procedure btnCheckUpdatesClick(Sender: TObject); - procedure LEDButtonClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure cmbProfilesClick(Sender: TObject); procedure cbCheckUpdatesClick(Sender: TObject); @@ -124,8 +120,14 @@ type procedure btnDeleteProfileClick(Sender: TObject); procedure cbProfileMenuClick(Sender: TObject); procedure cbProfileMenuCascadedClick(Sender: TObject); + procedure actNewProfileExecute(Sender: TObject); + procedure actSaveProfileExecute(Sender: TObject); + procedure actRevertProfileExecute(Sender: TObject); + procedure actSetActiveProfileExecute(Sender: TObject); + procedure actDeleteProfileExecute(Sender: TObject); + procedure actRenameProfileExecute(Sender: TObject); private - FLEDControls: array[0..LED_COUNT - 1] of TLEDControls; + FLEDControls: array[0..LED_COUNT - 1] of TButtonAssignmentFrame; FEventMonitor: TOmniEventMonitor; FProfilesFilename: string; @@ -180,6 +182,8 @@ type procedure HandleDeviceStateMessage(AMessage: TOmniMessage); procedure HandleFSXStateMessage(AMessage: TOmniMessage); + procedure LEDConfigurationClick(Sender: TObject); + procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE; property EventMonitor: TOmniEventMonitor read FEventMonitor; @@ -287,7 +291,7 @@ begin worker := TFSXStateMonitorWorker.Create; EventMonitor.Monitor(CreateTask(worker)).Run; - TProfileManager.Attach(Self); + Profiles.Attach(Self); FindLEDControls; @@ -306,7 +310,7 @@ begin FinalizeProfileMenu; UnregisterDeviceArrival; - TProfileManager.Detach(Self); + Profiles.Detach(Self); end; @@ -378,7 +382,7 @@ var profile: TProfile; begin - profile := TProfileManager.Instance.ActiveProfile; + profile := Profiles.ActiveProfile; if Settings.ActiveProfile <> profile.Name then begin @@ -386,12 +390,13 @@ begin SaveSettings; end; - FLockChangeProfile := True; - try - cmbProfiles.ItemIndex := cmbProfiles.Items.IndexOfObject(profile); - finally - FLockChangeProfile := False; - end; + // #ToDo1 -oMvR: 21-4-2013: invalidate profile node +// FLockChangeProfile := True; +// try +// cmbProfiles.ItemIndex := cmbProfiles.Items.IndexOfObject(profile); +// finally +// FLockChangeProfile := False; +// end; LoadActiveProfile; end; @@ -411,20 +416,17 @@ procedure TMainForm.FindLEDControls; var ledIndex: Integer; ledNumber: string; + buttonFrame: TButtonAssignmentFrame; begin for ledIndex := 0 to Pred(LED_COUNT) do begin ledNumber := IntToStr(Succ(ledIndex)); - FLEDControls[ledIndex].ConfigureButton := (ComponentByName('btnP' + ledNumber, ledIndex) as TButton); - FLEDControls[ledIndex].CategoryLabel := (ComponentByName('lblP' + ledNumber + 'Category', ledIndex) as TLabel); - FLEDControls[ledIndex].FunctionLabel := (ComponentByName('lblP' + ledNumber + 'Function', ledIndex) as TLabel); + buttonFrame := (ComponentByName('bafP' + ledNumber, ledIndex) as TButtonAssignmentFrame); + buttonFrame.OnConfigurationClick := LEDConfigurationClick; - FLEDControls[ledIndex].ConfigureButton.OnClick := LEDButtonClick; - FLEDControls[ledIndex].CategoryLabel.Caption := ''; - FLEDControls[ledIndex].CategoryLabel.Font.Color := clGrayText; - FLEDControls[ledIndex].FunctionLabel.Caption := ''; + FLEDControls[ledIndex] := buttonFrame; end; end; @@ -454,43 +456,43 @@ begin begin Debug.Log('UI: Succesfully converted 0.x profile'); defaultProfile.Name := DefaultProfileName; - defaultProfile.IsTemporary := True; end; if Assigned(defaultProfile) then - TProfileManager.Add(defaultProfile); + Profiles.Add(defaultProfile); end else begin persistXML := TX2UtPersistXML.Create; try persistXML.FileName := FProfilesFilename; - TProfileManager.Load(persistXML.CreateReader); + Profiles.Load(persistXML.CreateReader); finally FreeAndNil(persistXML); end; end; { Make sure we always have a profile } - if TProfileManager.Instance.Count = 0 then + if Profiles.Count = 0 then begin Debug.Log('UI: No profiles found, creating default profile'); - TProfileManager.Add(CreateDefaultProfile); + Profiles.Add(CreateDefaultProfile); end; - FLockChangeProfile := True; - try - cmbProfiles.Items.BeginUpdate; - try - cmbProfiles.Items.Clear; - - for profile in TProfileManager.Instance do - cmbProfiles.Items.AddObject(profile.Name, profile); - finally - cmbProfiles.Items.EndUpdate; - end; - finally - FLockChangeProfile := False; - end; + // #ToDo1 -oMvR: 21-4-2013: load tree +// FLockChangeProfile := True; +// try +// cmbProfiles.Items.BeginUpdate; +// try +// cmbProfiles.Items.Clear; +// +// for profile in TProfileManager.Instance do +// cmbProfiles.Items.AddObject(profile.Name, profile); +// finally +// cmbProfiles.Items.EndUpdate; +// end; +// finally +// FLockChangeProfile := False; +// end; finally Debug.UnIndent; end; @@ -507,7 +509,7 @@ begin persistXML := TX2UtPersistXML.Create; try persistXML.FileName := FProfilesFilename; - TProfileManager.Instance.Save(persistXML.CreateWriter); + Profiles.Save(persistXML.CreateWriter); finally FreeAndNil(persistXML); end; @@ -552,13 +554,21 @@ begin { Default profile } profile := nil; if Length(Settings.ActiveProfile) > 0 then - profile := TProfileManager.Instance.Find(Settings.ActiveProfile); + begin + { Version 0.2 used the profile name, not a UID } + if Settings.ActiveProfile[1] <> '{' then + begin + profile := Profiles.FindByName(Settings.ActiveProfile); + Settings.ActiveProfile := profile.UID; + end else + profile := Profiles.FindByUID(Settings.ActiveProfile); + end; { LoadProfiles ensures there's always at least 1 profile } - if (not Assigned(profile)) and (TProfileManager.Instance.Count > 0) then - profile := TProfileManager.Instance[0]; + if (not Assigned(profile)) and (Profiles.Count > 0) then + profile := Profiles[0]; - TProfileManager.Instance.ActiveProfile := profile; + Profiles.ActiveProfile := profile; { Auto-update } cbCheckUpdates.Checked := Settings.CheckUpdates; @@ -601,7 +611,7 @@ begin { Default button functions are assigned during UpdateButton } Result := TProfile.Create; Result.Name := DefaultProfileName; - Result.IsTemporary := True; +// Result.IsTemporary := True; end; @@ -611,7 +621,8 @@ var buttonIndex: Integer; begin - activeProfile := TProfileManager.Instance.ActiveProfile; + // #ToDo1 -oMvR: 21-4-2013: change to LoadSelectedProfile + activeProfile := Profiles.ActiveProfile; if not Assigned(activeProfile) then exit; @@ -652,16 +663,52 @@ begin if Assigned(buttonFunction) then begin - FLEDControls[AButtonIndex].CategoryLabel.Caption := buttonFunction.GetCategoryName; - FLEDControls[AButtonIndex].FunctionLabel.Caption := buttonFunction.GetDisplayName; + FLEDControls[AButtonIndex].CategoryName := buttonFunction.GetCategoryName; + FLEDControls[AButtonIndex].FunctionName := buttonFunction.GetDisplayName; end; end; +procedure TMainForm.actDeleteProfileExecute(Sender: TObject); +begin +// +end; + + +procedure TMainForm.actNewProfileExecute(Sender: TObject); +begin + // +end; + + +procedure TMainForm.actRenameProfileExecute(Sender: TObject); +begin + // +end; + + +procedure TMainForm.actRevertProfileExecute(Sender: TObject); +begin + // +end; + + +procedure TMainForm.actSaveProfileExecute(Sender: TObject); +begin + // +end; + + +procedure TMainForm.actSetActiveProfileExecute(Sender: TObject); +begin + // +end; + + procedure TMainForm.AddProfile(AProfile: TProfile); begin - cmbProfiles.Items.AddObject(AProfile.Name, AProfile); - TProfileManager.Instance.Add(AProfile, True); +// cmbProfiles.Items.AddObject(AProfile.Name, AProfile); + Profiles.Add(AProfile, True); end; @@ -671,18 +718,18 @@ var oldItemIndex: Integer; begin - itemIndex := cmbProfiles.Items.IndexOfObject(AProfile); - if itemIndex > -1 then - begin - oldItemIndex := cmbProfiles.ItemIndex; - FLockChangeProfile := True; - try - cmbProfiles.Items[itemIndex] := AProfile.Name; - cmbProfiles.ItemIndex := oldItemIndex; - finally - FLockChangeProfile := False; - end; - end; +// itemIndex := cmbProfiles.Items.IndexOfObject(AProfile); +// if itemIndex > -1 then +// begin +// oldItemIndex := cmbProfiles.ItemIndex; +// FLockChangeProfile := True; +// try +// cmbProfiles.Items[itemIndex] := AProfile.Name; +// cmbProfiles.ItemIndex := oldItemIndex; +// finally +// FLockChangeProfile := False; +// end; +// end; end; @@ -691,39 +738,39 @@ var itemIndex: Integer; begin - itemIndex := cmbProfiles.Items.IndexOfObject(AProfile); - if itemIndex > -1 then - begin - TProfileManager.Remove(AProfile); - cmbProfiles.Items.Delete(itemIndex); - - if TProfileManager.Instance.Count = 0 then - AddProfile(CreateDefaultProfile); - - if ASetActiveProfile then - begin - if itemIndex >= TProfileManager.Instance.Count then - itemIndex := Pred(TProfileManager.Instance.Count); - - FLockChangeProfile := True; - try - cmbProfiles.ItemIndex := itemIndex; - TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[itemIndex]); - finally - FLockChangeProfile := False; - end; - end; - end; +// itemIndex := cmbProfiles.Items.IndexOfObject(AProfile); +// if itemIndex > -1 then +// begin +// TProfileManager.Remove(AProfile); +// cmbProfiles.Items.Delete(itemIndex); +// +// if TProfileManager.Instance.Count = 0 then +// AddProfile(CreateDefaultProfile); +// +// if ASetActiveProfile then +// begin +// if itemIndex >= TProfileManager.Instance.Count then +// itemIndex := Pred(TProfileManager.Instance.Count); +// +// FLockChangeProfile := True; +// try +// cmbProfiles.ItemIndex := itemIndex; +// TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[itemIndex]); +// finally +// FLockChangeProfile := False; +// end; +// end; +// end; end; procedure TMainForm.cmbProfilesClick(Sender: TObject); begin - if not FLockChangeProfile then - begin - if cmbProfiles.ItemIndex > -1 then - TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]); - end; +// if not FLockChangeProfile then +// begin +// if cmbProfiles.ItemIndex > -1 then +// TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]); +// end; end; @@ -786,7 +833,7 @@ begin end; -procedure TMainForm.LEDButtonClick(Sender: TObject); +procedure TMainForm.LEDConfigurationClick(Sender: TObject); function GetUniqueProfileName(const AName: string): string; var @@ -796,14 +843,15 @@ procedure TMainForm.LEDButtonClick(Sender: TObject); Result := AName; counter := 0; - while Assigned(TProfileManager.Find(Result)) do - begin - Inc(counter); - Result := Format('%s (%d)', [AName, counter]); - end; +// while Assigned(Profiles.Find(Result)) do +// begin +// Inc(counter); +// Result := Format('%s (%d)', [AName, counter]); +// end; end; + // #ToDo1 -oMvR: 6-5-2013: new style! var activeProfile: TProfile; buttonIndex: NativeInt; @@ -811,25 +859,25 @@ var newProfile: Boolean; begin - activeProfile := TProfileManager.Instance.ActiveProfile; + activeProfile := Profiles.ActiveProfile; if not Assigned(activeProfile) then exit; { Behaviour similar to the Windows System Sounds control panel; when a change occurs, create a temporary profile "(modified)" so the original profile can still be selected } - if not activeProfile.IsTemporary then - begin - profile := TProfile.Create; - profile.Assign(activeProfile); - profile.Name := GetUniqueProfileName(profile.Name + ProfilePostfixModified); - profile.IsTemporary := True; - newProfile := True; - end else - begin +// if not activeProfile.IsTemporary then +// begin +// profile := TProfile.Create; +// profile.Assign(activeProfile); +// profile.Name := GetUniqueProfileName(profile.Name + ProfilePostfixModified); +// profile.IsTemporary := True; +// newProfile := True; +// end else +// begin profile := activeProfile; newProfile := False; - end; +// end; buttonIndex := (Sender as TComponent).Tag; if TButtonFunctionForm.Execute(profile, buttonIndex) then @@ -955,13 +1003,13 @@ var begin name := ''; - profile := TProfileManager.Instance.ActiveProfile; + profile := Profiles.ActiveProfile; existingProfile := nil; repeat if InputQuery('Save profile as', 'Save this profile as:', name) then begin - existingProfile := TProfileManager.Find(name); + existingProfile := Profiles.FindByName(name); if existingProfile = profile then existingProfile := nil; @@ -986,24 +1034,24 @@ begin existingProfile.Assign(profile); existingProfile.Name := name; UpdateProfile(existingProfile); - TProfileManager.Instance.ActiveProfile := existingProfile; + Profiles.ActiveProfile := existingProfile; - if profile.IsTemporary then - DeleteProfile(profile, False); +// if profile.IsTemporary then +// DeleteProfile(profile, False); end else begin - if profile.IsTemporary then - begin - profile.Name := name; - profile.IsTemporary := False; - UpdateProfile(profile); - end else - begin +// if profile.IsTemporary then +// begin +// profile.Name := name; +// profile.IsTemporary := False; +// UpdateProfile(profile); +// end else +// begin newProfile := TProfile.Create; newProfile.Assign(profile); newProfile.Name := name; AddProfile(newProfile); - end; +// end; end; SaveProfiles; @@ -1015,7 +1063,7 @@ var activeProfile: TProfile; begin - activeProfile := TProfileManager.Instance.ActiveProfile; + activeProfile := Profiles.ActiveProfile; if Assigned(activeProfile) then begin if MessageBox(Self.Handle, PChar(Format('Do you want to remove the profile named "%s"?', [activeProfile.Name])), diff --git a/G940LEDControl/G940LEDControl.dpr b/G940LEDControl/G940LEDControl.dpr index 6b70f6e..fb776b5 100644 --- a/G940LEDControl/G940LEDControl.dpr +++ b/G940LEDControl/G940LEDControl.dpr @@ -1,8 +1,8 @@ program G940LEDControl; uses - Forms, - SysUtils, + System.SysUtils, + Vcl.Forms, MainFrm in 'Forms\MainFrm.pas' {MainForm}, LogiJoystickDLL in '..\Shared\LogiJoystickDLL.pas', SimConnect in '..\Shared\SimConnect.pas', @@ -36,7 +36,8 @@ uses FSXLEDFunctionProviderIntf in 'Units\FSXLEDFunctionProviderIntf.pas', GxDbugIntf in 'Units\GxDbugIntf.pas', DebugLog in 'Units\DebugLog.pas', - DebugLogGExperts in 'Units\DebugLogGExperts.pas'; + DebugLogGExperts in 'Units\DebugLogGExperts.pas', + ButtonAssignmentFrm in 'Forms\ButtonAssignmentFrm.pas' {ButtonAssignmentFrame: TFrame}; {$R *.res} diff --git a/G940LEDControl/G940LEDControl.dproj b/G940LEDControl/G940LEDControl.dproj index c318d2e..79d86d8 100644 --- a/G940LEDControl/G940LEDControl.dproj +++ b/G940LEDControl/G940LEDControl.dproj @@ -8,7 +8,7 @@ VCL 13.4 True - Release + Debug Win32 1 Application @@ -148,6 +148,11 @@ + +
ButtonAssignmentFrame
+ dfm + TFrame +
Cfg_2 Base diff --git a/G940LEDControl/G940LEDControl.res b/G940LEDControl/G940LEDControl.res index 906ddee2cba7b0ebdff29348afd88ed20b99346a..d98ff0a8e18f4a9808bfeee4072191112fccef14 100644 GIT binary patch delta 147 zcmaEJkMY9|#t90WZ!l$KGPX~4%!!yhJ!dH+=VX^$Em6+0)S}|d{5)GFGd%+kRO030 zoIEjCS%)(xF)zI|F+J5*Ned)cP?VpXT3no8Hn1J__U;f@8d1W zDJcaW^FABjZ{r-}>^tQKuX6+@fj(UoLlOhH&FA!^0z0gGgQtEhG0CP(Qm-avCtzK& zGSW^M%c#?*j;rPb?%+KAcjy-~r5Niak$q;a>krW*9C*#At}twwpTNKC*u@2c_Qr9# zcN%A_($=UCwun&)(*@L-M)`z7uUn=qcL_}K5Ce9km};j5{jVFBIb{dajK6y_>Im3R zJ=U&gCS&tHnL2RE{AKPlAwAoi)%jE7nX7%Ry%9a-e5hWi{pyQ)H7mxedVaXHXpN!F za+M~YyH;=N&s~_eKUMD!7q3|(_LFenhthMGCS3Yi8pu3PvsM=LR3U?6kQtZiV$`U% zq7`SQdKPs&OA#WLLm7LnpSP1?8p&(|Cd5Fs0?qT>13%8C+qj{#slG+qrxxZ>HR9GE D_Ufd< diff --git a/G940LEDControl/Resources/Icons/DeleteProfile.ico b/G940LEDControl/Resources/Icons/DeleteProfile.ico new file mode 100644 index 0000000000000000000000000000000000000000..7db8d4dfc32ce83fc03bb2aebcdba8d45efc74f6 GIT binary patch literal 1406 zcmeH{%}bO~6vlt1eV89JIyyO{HXqL9nB(|SO_?*AgENcKc}-tQb4WB3)Ck>#n-+a+ z`XgGo%F+fCqo6<|vt3Y-L`Yf-LkKKLQnA~8M~i~C?Yu9~dCqyxz30NYF9#Cjr`IFx zK6-b95pYRJ39E#r$5+A@{r0!xJ?Sy@2V!KHVi@yANimvA^nBr=Aoj?msdBIElq|Ac{o zJ6yc@fWE$m3=K^%IQWQE!!#-RPsy>&V6@GWYk!8>IYY8*j%3dqX`XqEuGi?w=FykG z!r+}Fr{W!!ek2(u44@Uz!dq8DZGg}BFIw&mL@@QXbF$9L}k+l z98GK3nm4hx2pnewht3LI?ShhX0`K{C%6bGxCA_@?fBy!R{eqL11U`xS`WMs=3WArV ze?`!IWu4aR8=Sr>XuT=uza{>7s2z8w1OKN3Lj3DLOHDGxugfvSDf?8&ohrTTLf7tW z$>~ZsE8z3($&-RdRg~I<;$Wc0=aX~B;^}Bn)o>^j2vj9$6%HPXwyCNT3ZKx* zXiMLq2`9FPk`#_b+gjA>UunuaJEBolb(`b6WxA`Q%@$P^`&OLW)!kWuGpg3^jSEM5 zE;Lxd(V~=PX~MZkcZJ4>Rj*EC$c)?kj5z&mv=+?1gc~>Dnw*DI5?2!?%i1gQ_;-mF T&6ik^dlsf)aS=9_Ks);rN^Q0Y literal 0 HcmV?d00001 diff --git a/G940LEDControl/Resources/Icons/NewProfile.ico b/G940LEDControl/Resources/Icons/NewProfile.ico new file mode 100644 index 0000000000000000000000000000000000000000..2896fe3912757db9107a0920c2cd595c0e198014 GIT binary patch literal 1406 zcmeH{T}V@57{`Am;%1TS%f47CecAVym}pFv3>iUP6huU11olCa-K3di*hLyN@**ZJ z4U=XvL(IC0V0Y0)f!!5d*g{y~mNS?0?6{}*oQVisbs6}7dCqx%&-*{`dCvpqfebZl zHq_O^g)GPe3RS2S`6`UOsf_e(c0R+tx@x@F&(q#;kw=Y}@HJlM@y!~ZHeI3nb}c>4 zwe+>r(R;U^Kx+g2o+bu7w;1BUgor8^YOZLTR&5|KKAhy;0nq!f~%~+9y=s z7mjubX9g9&68Iq4M}&i;!ik7*N=4N-p(Z4pO9+9^c3%3P(9zb9r{xU~?+xPb=%p|4 zn&2}p!ROuFX-m=SOVOkDeDO9#S1^TN?du;B;-SwZB42nnG|l@@(~O0Onff`577L+` zkD&buqfPuki;trJj`BS$M50Ob$uaaq41Fq2Y&=P9LL(keGO5m_B{cM8f|Rb!DdhZg zz5@Se1w_<;_?NO~m8p7(>K;Au5aEnd9YSl_y4^^&4PB9=6=Ysa?2Ejx2^tmdlWm@A_MLG>N~6zUwo ITri&f19Iu)I{*Lx literal 0 HcmV?d00001 diff --git a/G940LEDControl/Resources/Icons/RenameProfile.ico b/G940LEDControl/Resources/Icons/RenameProfile.ico new file mode 100644 index 0000000000000000000000000000000000000000..93dfa42bac45780693f59079eb848ad5c44ba430 GIT binary patch literal 1406 zcmeH{ZAcS97{~t>lD+zZ3B9_?LT$w=N2}CowJc#0W?EXXNtjBeews<5Wwb?NrIN2D z>P#iY#5uK5s7u3Au_(1|&JqhJrX{`TG_SiABGHFF^wH<|-`($d?m6zBg9EH+v$F&3 zZ4hn^I00~_qAqZ#nBQVnzlNFlZ;pL5I-0}-o=hENxQqXroQ-zA_ZDF!8%V^FS;p-di!``6-8nVN_PsR?lA zqj=stR&YU0R5mG9?TTi=eA3rX!W6 z3@wk;XxFHb_ap;3jY?#9mY}%#9%>D0+!`%M#ZW!8?e)+%snFY01HD#*lx!nPH63WI z?}Ywo6AaA_Ft%!8eAa@#_UGv9XoIn{6@y)E80u-mhwfJx*1v@5&1($xcEi-GgMOe3 zFUAcR?C-&d$%yffI!uhd#rIDGFn{icdF(yRUrd-9AH$Ey2~19zG0ikRJ?pXNrgIhe z{}mvF{AE+?S;oTih*TO95+aqHJ~f~50wNOecZhZg1QH875K)ko`vL!*0tx+lfaOFS zba?5KWdQ=Ig`J4+G4D<57jO5UVetujSNlbtp_Vw89)p}*=W4fb-!_)NnfUpM1B4qk z+S=@9Y>5-H-^FXs>RC+o61O!gse{MzNhlHfaGY1nFd^I{Yge)LJRX;tqoV_#(Vxaj T&_M6;Pon>20~1?s3$Wau-{2j3 literal 0 HcmV?d00001 diff --git a/G940LEDControl/Resources/Icons/RevertProfile.ico b/G940LEDControl/Resources/Icons/RevertProfile.ico new file mode 100644 index 0000000000000000000000000000000000000000..e7573837720055713a07ee3a350ec275e566f84d GIT binary patch literal 1406 zcmeH{T`bjc7{@=7(hFf!Qpr2XYe+-cTY_?l#E+R|;fo8m&tAv>NO_25pLKld_y(dK!h&Gw`HY$$^n zCg{?vc$s0&Sgr*h@=TdLY0ktMD|(K*(wS{fZ>}TVC!859bYrN%j?UA8G~_6Fnje8C zJDT?5Acl*a87*~Uyv&_3wFkrHUW`_G(pl_HzdDdt72A1J>Bo4LKOx^7(cG;(??|MaShV#N%{?_83#G`H1HQi1tE+PTIO6 zL{AA*x>Ce|8qr;e=&M4!sOC#=jkGTy`fK<$a1Akdl^?HfAcmwq(uf$lFL{J`CwZ?$ zeC(QYA@k;Z2mWsdgb@Gm!4P|gz`0>=2ls`p5B{ULtMQ zNXgWgq`gh5cp^TTmHJkSnp~uyg literal 0 HcmV?d00001 diff --git a/G940LEDControl/Resources/Icons/SaveProfile.ico b/G940LEDControl/Resources/Icons/SaveProfile.ico new file mode 100644 index 0000000000000000000000000000000000000000..749f6f2b5036f08bd569f5e9b57455855c1279e6 GIT binary patch literal 1406 zcmeH{T}<0m7>6IwZB#8*Mj(W+GT0WJvN$Jx#IGR(Hqp)Lh~2RJpbmjFgn1EEK}Ho6-?(EgYKr$i2v&JMz6f`!r#g7ob$Zr zeQ(}3IS?i+i3DMfK)C>7fE2+(h(y7m`0on)CTVCSrEr5g%nH9Qmlo^oK_}tT)m9;qBXRspTxB#9G5H{_s&K1=PzVn zcLeVINIV51JW3Hm$~!ox7SmrS!Be!DK~)TWB};It6Y%bp;(arb5nU2q&2n7o6hx#- z-f%yY#x!~=)9I|)PFKxVoOLpe)Tpu66w}eDqTTowUw`lvXUru`*tE>pityP>xbAoZ zbG;tZ`}?sp)pFciOZ&lUy3Be`9Nfpr!v;DJ8R$7wi{o$|ou3%!vb;x|^BiIi4!w@kxST!ox|}%Acyaf-__EKefj-U-4Kh6B!8?4G z!NFn9d50Mt@iI0#!ua`7#xH!u_{ED%PJF}I#4O{NeO$US!{u+MxpH-uOVihwoVm`_ z)D$zmtN46Arf2;4zWbgj{}0Sw3*h(r2?PT80zWYuxPd<~$Lxc?gF%Ax z^ZY9KfBiQ*F#nIUc{J*g!dLcalm+2Y3G3jAxU`MW+`GkOs!rVS;_YzHgZFJpk9?u( z!=~8m+z?CSpUV{GsH;pjIX*r^RkT&MZTF%j&kOH&$HYh?BU4gWtxC&YFYwCfrAbMT zhqU(TY=KimI}S7odiU+hytF7GKSJK5D^{sWHTstx2-Po;n~V(&_4=Cnyfp%^xOJDQ z;?>g9QceAiKiSk^Y|!tkQ>+%l@~~Ydy;iHy>Wqqo(eP|?iLSg{Tee44ym?v1-v$wC OflK%YEB}Qq}E{7{@=RvdPlvW?DIpI=AWEoRwv1WMM{Dc2Sp=O`Bcpre#@Zmq`)Eva%Z% zmR+dGOGUk?7gD6rg_7P>FOo_qq9Bn7x=XZvXNvTqpg+Lh;kkX!b34yD=K&va1qUOz zl2!f?2E+*x5K)3;+ON~?onvE(nn^c6B1!5|Nl(mpr0?{ro zZ-+4(A$bGDZZ=}9G-7g@FmH*)zgmIP4eI^iU!x?bR*9w>B6fpT;M#qna-E=hK_^A= zQwlg8fOfBzVeT;e&WJwG2BK;TN7)=9WF*oNJ|>! zaRjvJQ8!1Sx@02!oRN@=20|{2n3hDsuG)~UB%!;Wis5_$Q7!Qpni8>GOCzFn3XwOa z5!ITGUdZU1(@ANY%fwsrn9yb?za}5Y0SAtQ4xGoFIP0A(ZCHw_eGajAaxverW4@b* z_1+?qZ`-jwEMj!WGNwK#Cii{`c^&0sJ>9~hr&Sa@*-l}no2`$kDeBxq#mhP>UmRuI zi+Z+poxs)AK*g&DYTMkjJZxm=n+xoE+ek;xGakQw%<~Ujy!`Z@o_F1R`S6+E?jL;p z_=TTed+~hp;OQ0g%j12ugKTgD|1$xP=O5oorbeMqXAY$B4GkTs3RDj12edI#j3nv& z0{Yg6-WZd!wn)-R!vkcGnUhRu>&wcEA|;(lDRNjcCY6+ym3x68wOC9UE7q+}S>pwU zivQo5KX&=J$w@LGjS#l2Fne~tAeGBO0R@(S#BFHp8Be1<3xzjC47J|{gj)-lf4 z+tI}0#j-siN#1+%iC?fRe}2w*eV-+GmTgp=ZPtMKry`Hwdn9}mt-TWE+eOYD;=%q# N@;%u{_LXDg*xw|C#B%@u literal 0 HcmV?d00001 diff --git a/G940LEDControl/Units/FSXSimConnectClient.pas b/G940LEDControl/Units/FSXSimConnectClient.pas index 0299f1c..0bf5e99 100644 --- a/G940LEDControl/Units/FSXSimConnectClient.pas +++ b/G940LEDControl/Units/FSXSimConnectClient.pas @@ -118,6 +118,7 @@ type FProfileMenu: Boolean; FProfileMenuCascaded: Boolean; + // #ToDo1 -oMvR: 6-5-2013: change to object list FMenuProfiles: TStringList; FMenuWasCascaded: Boolean; protected @@ -311,9 +312,9 @@ begin if AEnabled <> FObservingProfileManager then begin if AEnabled then - TProfileManager.Attach(Self) + Profiles.Attach(Self) else - TProfileManager.Detach(Self); + Profiles.Detach(Self); FObservingProfileManager := AEnabled; end; @@ -552,9 +553,9 @@ begin exit; profileName := FMenuProfiles[Pred(AEventID)]; - profile := TProfileManager.Find(profileName); + profile := Profiles.FindByUID(profileName); if Assigned(profile) then - TProfileManager.Instance.ActiveProfile := profile; + Profiles.ActiveProfile := profile; end; @@ -685,8 +686,12 @@ begin if ProfileMenu then begin - for profile in TProfileManager.Instance do - FMenuProfiles.Add(profile.Name); + try + for profile in Profiles.LockList do + FMenuProfiles.Add(profile.Name); + finally + Profiles.UnlockList; + end; FMenuProfiles.Sort; diff --git a/G940LEDControl/Units/Profile.pas b/G940LEDControl/Units/Profile.pas index dfd588d..7fa01af 100644 --- a/G940LEDControl/Units/Profile.pas +++ b/G940LEDControl/Units/Profile.pas @@ -44,8 +44,8 @@ type TProfile = class(TPersistent) private + FUID: string; FName: string; - FIsTemporary: Boolean; FButtons: TProfileButtonList; function GetButton(Index: Integer): TProfileButton; @@ -61,8 +61,8 @@ type function HasButton(AIndex: Integer): Boolean; + property UID: string read FUID write FUID; property Name: string read FName write FName; - property IsTemporary: Boolean read FIsTemporary write FIsTemporary; property ButtonCount: Integer read GetButtonCount; property Buttons[Index: Integer]: TProfileButton read GetButton; @@ -71,7 +71,7 @@ type TProfileList = class(TObjectList) public - function Find(const AName: string): TProfile; +// function Find(const AName: string): TProfile; procedure Load(AReader: IX2PersistReader); procedure Save(AWriter: IX2PersistWriter); @@ -92,7 +92,6 @@ const KeyProviderUID = 'ProviderUID'; KeyFunctionUID = 'FunctionUID'; - KeyIsTemporary = 'IsTemporary'; { TProfileButton } @@ -232,8 +231,8 @@ begin begin sourceProfile := TProfile(Source); + FUID := sourceProfile.UID; FName := sourceProfile.Name; - FIsTemporary := sourceProfile.IsTemporary; FButtons.Clear; for buttonIndex := 0 to Pred(sourceProfile.ButtonCount) do @@ -251,8 +250,8 @@ var begin buttonIndex := 0; - if not AReader.ReadBoolean(KeyIsTemporary, FIsTemporary) then - FIsTemporary := False; +// if not AReader.ReadBoolean(KeyIsTemporary, FIsTemporary) then +// FIsTemporary := False; while AReader.BeginSection(SectionButton + IntToStr(buttonIndex)) do try @@ -277,7 +276,7 @@ var buttonIndex: Integer; begin - AWriter.WriteBoolean(KeyIsTemporary, IsTemporary); +// AWriter.WriteBoolean(KeyIsTemporary, IsTemporary); for buttonIndex := 0 to Pred(FButtons.Count) do begin @@ -330,6 +329,7 @@ end; { TProfileList } +{ function TProfileList.Find(const AName: string): TProfile; var profile: TProfile; @@ -344,6 +344,7 @@ begin break; end; end; +} procedure TProfileList.Load(AReader: IX2PersistReader); diff --git a/G940LEDControl/Units/ProfileManager.pas b/G940LEDControl/Units/ProfileManager.pas index a0bc2e4..32f83ab 100644 --- a/G940LEDControl/Units/ProfileManager.pas +++ b/G940LEDControl/Units/ProfileManager.pas @@ -3,7 +3,6 @@ unit ProfileManager; interface uses System.Classes, - System.SyncObjs, Profile, X2UtPersistIntf; @@ -21,57 +20,53 @@ type TProfileManager = class; - TProfileManagerEnumerator = class(TProfileList.TEnumerator) - private - FManager: TProfileManager; - public - constructor Create(AManager: TProfileManager); - destructor Destroy; override; + ILockedProfileList = interface + ['{4F647762-AA70-4315-BB1C-E85E320F4E82}'] + function GetEnumerator: TProfileList.TEnumerator; end; + TProfileManager = class(TObject) private - FLock: TCriticalSection; - FProfiles: TProfileList; FObservers: TInterfaceList; + FProfileList: TProfileList; FActiveProfile: TProfile; - function GetActiveProfile: TProfile; function GetCount: Integer; function GetItem(Index: Integer): TProfile; procedure SetActiveProfile(const Value: TProfile); procedure SetItem(Index: Integer; const Value: TProfile); protected property Observers: TInterfaceList read FObservers; - property Profiles: TProfileList read FProfiles; + property ProfileList: TProfileList read FProfileList; public - class function Instance(): TProfileManager; - constructor Create; destructor Destroy; override; - procedure Lock; - procedure Unlock; + procedure Add(AProfile: TProfile; ASetActive: Boolean = False); + function FindByName(const AName: string): TProfile; + function FindByUID(const AName: string): TProfile; + function Remove(const AProfile: TProfile): Integer; - class procedure Add(AProfile: TProfile; ASetActive: Boolean = False); - class function Find(const AName: string): TProfile; - class function Remove(const AProfile: TProfile): Integer; + procedure Load(AReader: IX2PersistReader); + procedure Save(AWriter: IX2PersistWriter); - class procedure Load(AReader: IX2PersistReader); - class procedure Save(AWriter: IX2PersistWriter); + procedure Attach(AObserver: IProfileObserver); + procedure Detach(AObserver: IProfileObserver); - class procedure Attach(AObserver: IProfileObserver); - class procedure Detach(AObserver: IProfileObserver); + function LockList: ILockedProfileList; + procedure UnlockList; - function GetEnumerator: TProfileManagerEnumerator; - - property ActiveProfile: TProfile read GetActiveProfile write SetActiveProfile; + property ActiveProfile: TProfile read FActiveProfile write SetActiveProfile; property Count: Integer read GetCount; property Items[Index: Integer]: TProfile read GetItem write SetItem; default; end; + { Singleton } + function Profiles: TProfileManager; + implementation @@ -83,8 +78,20 @@ var ProfileManagerInstance: TProfileManager; -{ TProfileManager } -class function TProfileManager.Instance: TProfileManager; + +type + TLockedProfileList = class(TInterfacedObject, ILockedProfileList) + private + FList: TProfileList; + public + constructor Create(AList: TProfileList); + + function GetEnumerator: TProfileList.TEnumerator; + end; + + + +function Profiles: TProfileManager; begin if not Assigned(ProfileManagerInstance) then ProfileManagerInstance := TProfileManager.Create; @@ -93,136 +100,130 @@ begin end; +{ TProfileManager } constructor TProfileManager.Create; begin inherited Create; FObservers := TInterfaceList.Create; - FProfiles := TProfileList.Create(True); - FLock := TCriticalSection.Create; + FProfileList := TProfileList.Create(True); end; destructor TProfileManager.Destroy; begin - FreeAndNil(FLock); - FreeAndNil(FProfiles); + FreeAndNil(FProfileList); FreeAndNil(FObservers); inherited; end; -procedure TProfileManager.Lock; -begin - -end; - - -procedure TProfileManager.Unlock; -begin - -end; - - -class procedure TProfileManager.Add(AProfile: TProfile; ASetActive: Boolean); +procedure TProfileManager.Add(AProfile: TProfile; ASetActive: Boolean); var observer: IInterface; begin - Instance.Lock; + TMonitor.Enter(ProfileList); try - Instance.Profiles.Add(AProfile); + ProfileList.Add(AProfile); finally - Instance.Unlock; + TMonitor.Exit(ProfileList); end; - for observer in Instance.Observers do + for observer in Observers do (observer as IProfileObserver).ObserveAdd(AProfile); if ASetActive then - Instance.SetActiveProfile(AProfile); + SetActiveProfile(AProfile); end; -class function TProfileManager.Find(const AName: string): TProfile; +function TProfileManager.FindByName(const AName: string): TProfile; begin - Result := Instance.Profiles.Find(AName); +// Result := Instance.ProfileList.Find(AName); end; -class function TProfileManager.Remove(const AProfile: TProfile): Integer; +function TProfileManager.FindByUID(const AName: string): TProfile; +begin + // +end; + + +function TProfileManager.Remove(const AProfile: TProfile): Integer; var observer: IInterface; begin - Instance.Lock; + TMonitor.Enter(ProfileList); try - Result := Instance.Profiles.Remove(AProfile); + Result := ProfileList.Remove(AProfile); finally - Instance.Unlock; + TMonitor.Exit(ProfileList); end; - for observer in Instance.Observers do + for observer in Observers do (observer as IProfileObserver).ObserveRemove(AProfile); end; -class procedure TProfileManager.Load(AReader: IX2PersistReader); +procedure TProfileManager.Load(AReader: IX2PersistReader); begin - Instance.Lock; + TMonitor.Enter(ProfileList); try - Instance.Profiles.Load(AReader); + ProfileList.Load(AReader); finally - Instance.Unlock; + TMonitor.Exit(ProfileList); end; end; -class procedure TProfileManager.Save(AWriter: IX2PersistWriter); +procedure TProfileManager.Save(AWriter: IX2PersistWriter); begin - Instance.Lock; + TMonitor.Enter(ProfileList); try - Instance.Profiles.Save(AWriter); + ProfileList.Save(AWriter); finally - Instance.Unlock; + TMonitor.Exit(ProfileList); end; end; -class procedure TProfileManager.Attach(AObserver: IProfileObserver); +procedure TProfileManager.Attach(AObserver: IProfileObserver); begin - Instance.Observers.Add(AObserver as IProfileObserver); + Observers.Add(AObserver as IProfileObserver); end; -class procedure TProfileManager.Detach(AObserver: IProfileObserver); +procedure TProfileManager.Detach(AObserver: IProfileObserver); begin - Instance.Observers.Remove(AObserver as IProfileObserver); + Observers.Remove(AObserver as IProfileObserver); end; -function TProfileManager.GetActiveProfile: TProfile; +function TProfileManager.LockList: ILockedProfileList; begin - Result := Instance.FActiveProfile; + TMonitor.Enter(ProfileList); + Result := TLockedProfileList.Create(ProfileList); +end; + + +procedure TProfileManager.UnlockList; +begin + TMonitor.Exit(ProfileList); end; function TProfileManager.GetCount: Integer; begin - Result := Instance.Profiles.Count; -end; - - -function TProfileManager.GetEnumerator: TProfileManagerEnumerator; -begin - Result := TProfileManagerEnumerator.Create(Self); + Result := ProfileList.Count; end; function TProfileManager.GetItem(Index: Integer): TProfile; begin - Result := Profiles[Index]; + Result := ProfileList[Index]; end; @@ -242,27 +243,25 @@ end; procedure TProfileManager.SetItem(Index: Integer; const Value: TProfile); begin - Profiles[Index] := Value; + ProfileList[Index] := Value; end; -{ TProfileManagerEnumerator } -constructor TProfileManagerEnumerator.Create(AManager: TProfileManager); +{ TLockedProfileList } +constructor TLockedProfileList.Create(AList: TProfileList); begin - inherited Create(AManager.Profiles); + inherited Create; - FManager := AManager; - FManager.Lock; + FList := AList; end; -destructor TProfileManagerEnumerator.Destroy; +function TLockedProfileList.GetEnumerator: TProfileList.TEnumerator; begin - FManager.Unlock; - - inherited; + Result := FList.GetEnumerator; end; + initialization finalization FreeAndNil(ProfileManagerInstance);