1
0
mirror of synced 2024-11-22 10:03:51 +00:00

Overhaul of the profile management

This commit is contained in:
Mark van Renswoude 2014-02-16 17:45:54 +00:00
parent 0a9d825261
commit 966184fd0a
16 changed files with 1007 additions and 612 deletions

View File

@ -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

View File

@ -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.

View File

@ -1,12 +1,11 @@
object MainForm: TMainForm object MainForm: TMainForm
Left = 0 Left = 0
Top = 0 Top = 0
ActiveControl = cbProfileMenu
BorderIcons = [biSystemMenu, biMinimize] BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsSingle BorderStyle = bsSingle
Caption = 'G940 LED Control' Caption = 'G940 LED Control'
ClientHeight = 548 ClientHeight = 504
ClientWidth = 466 ClientWidth = 598
Color = clBtnFace Color = clBtnFace
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText Font.Color = clWindowText
@ -23,360 +22,215 @@ object MainForm: TMainForm
AlignWithMargins = True AlignWithMargins = True
Left = 8 Left = 8
Top = 60 Top = 60
Width = 450 Width = 582
Height = 480 Height = 436
Margins.Left = 8 Margins.Left = 8
Margins.Top = 8 Margins.Top = 8
Margins.Right = 8 Margins.Right = 8
Margins.Bottom = 8 Margins.Bottom = 8
ActivePage = tsConfiguration ActivePage = tsButtons
Align = alClient Align = alClient
TabOrder = 0 TabOrder = 0
object tsButtons: TTabSheet object tsButtons: TTabSheet
Caption = ' Button assignment ' Caption = ' Button assignment '
DesignSize = ( inline bafP1: TButtonAssignmentFrame
442 Left = 267
452) Top = 30
object lblP1Function: TLabel Width = 261
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
Height = 41 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 TabOrder = 0
OnClick = cmbProfilesClick ExplicitLeft = 267
ExplicitTop = 30
inherited btnConfiguration: TButton
Caption = 'P&1'
end end
object btnSaveProfile: TButton end
Left = 279 inline bafP2: TButtonAssignmentFrame
Top = 15 Left = 267
Width = 72 Top = 77
Height = 23 Width = 261
Anchors = [akTop, akRight] Height = 41
Caption = 'Sa&ve As...'
TabOrder = 1 TabOrder = 1
OnClick = btnSaveProfileClick ExplicitLeft = 267
ExplicitTop = 77
inherited btnConfiguration: TButton
Caption = 'P&2'
end end
object btnDeleteProfile: TButton end
Left = 357 inline bafP3: TButtonAssignmentFrame
Top = 15 Left = 267
Width = 72 Top = 124
Height = 23 Width = 261
Anchors = [akTop, akRight] Height = 41
Caption = '&Delete'
TabOrder = 2 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
end end
object tsConfiguration: TTabSheet object tsConfiguration: TTabSheet
Caption = ' Configuration ' Caption = ' Configuration '
ImageIndex = 2 ImageIndex = 2
object lblProfileSwitching: TLabel object lblProfileSwitching: TLabel
Left = 11 Left = 16
Top = 19 Top = 16
Width = 92 Width = 92
Height = 13 Height = 13
Caption = 'Profile switching' Caption = 'Profile switching'
@ -388,15 +242,15 @@ object MainForm: TMainForm
ParentFont = False ParentFont = False
end end
object bvlProfileSwitching: TBevel object bvlProfileSwitching: TBevel
Left = 224 Left = 229
Top = 26 Top = 23
Width = 205 Width = 337
Height = 13 Height = 13
Shape = bsTopLine Shape = bsTopLine
end end
object cbProfileMenu: TCheckBox object cbProfileMenu: TCheckBox
Left = 11 Left = 16
Top = 44 Top = 41
Width = 409 Width = 409
Height = 17 Height = 17
Caption = ' Add profile selection to FSX "Add-ons" menu' Caption = ' Add profile selection to FSX "Add-ons" menu'
@ -406,8 +260,8 @@ object MainForm: TMainForm
OnClick = cbProfileMenuClick OnClick = cbProfileMenuClick
end end
object cbProfileMenuCascaded: TCheckBox object cbProfileMenuCascaded: TCheckBox
Left = 31 Left = 36
Top = 67 Top = 64
Width = 389 Width = 389
Height = 17 Height = 17
Caption = ' Cascaded menu (profiles in "G940 Profile" submenu)' Caption = ' Cascaded menu (profiles in "G940 Profile" submenu)'
@ -511,7 +365,7 @@ object MainForm: TMainForm
OnClick = cbCheckUpdatesClick OnClick = cbCheckUpdatesClick
end end
object btnCheckUpdates: TButton object btnCheckUpdates: TButton
Left = 344 Left = 461
Top = 340 Top = 340
Width = 83 Width = 83
Height = 25 Height = 25
@ -525,14 +379,14 @@ object MainForm: TMainForm
AlignWithMargins = True AlignWithMargins = True
Left = 3 Left = 3
Top = 3 Top = 3
Width = 460 Width = 592
Height = 46 Height = 46
Align = alTop Align = alTop
BevelOuter = bvNone BevelOuter = bvNone
TabOrder = 1 TabOrder = 1
object pnlFSX: TPanel object pnlFSX: TPanel
AlignWithMargins = True AlignWithMargins = True
Left = 233 Left = 365
Top = 3 Top = 3
Width = 224 Width = 224
Height = 40 Height = 40
@ -696,7 +550,7 @@ object MainForm: TMainForm
AlignWithMargins = True AlignWithMargins = True
Left = 3 Left = 3
Top = 3 Top = 3
Width = 224 Width = 356
Height = 40 Height = 40
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
@ -1054,4 +908,354 @@ object MainForm: TMainForm
end end
end 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 end

View File

@ -1,7 +1,5 @@
unit MainFrm; unit MainFrm;
// #ToDo1 -oMvR: 3-3-2013: trigger profile update when Save As only changes the name
interface interface
uses uses
System.Classes, System.Classes,
@ -21,11 +19,12 @@ uses
pngimage, pngimage,
X2UtPersistIntf, X2UtPersistIntf,
ButtonAssignmentFrm,
FSXSimConnectIntf, FSXSimConnectIntf,
LEDStateConsumer, LEDStateConsumer,
Profile, Profile,
ProfileManager, ProfileManager,
Settings; Settings, VirtualTrees, Vcl.ImgList, Vcl.ActnList, Vcl.ToolWin, Vcl.Menus;
const const
@ -45,13 +44,6 @@ const
type type
TLEDControls = record
ConfigureButton: TButton;
CategoryLabel: TLabel;
FunctionLabel: TLabel;
end;
TMainForm = class(TForm, IProfileObserver) TMainForm = class(TForm, IProfileObserver)
imgStateNotFound: TImage; imgStateNotFound: TImage;
lblG940Throttle: TLabel; lblG940Throttle: TLabel;
@ -72,35 +64,6 @@ type
btnCheckUpdates: TButton; btnCheckUpdates: TButton;
lblProxy: TLabel; lblProxy: TLabel;
tsButtons: TTabSheet; 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; pnlFSX: TPanel;
imgFSXStateNotConnected: TImage; imgFSXStateNotConnected: TImage;
imgFSXStateConnected: TImage; imgFSXStateConnected: TImage;
@ -112,11 +75,44 @@ type
cbProfileMenuCascaded: TCheckBox; cbProfileMenuCascaded: TCheckBox;
lblProfileSwitching: TLabel; lblProfileSwitching: TLabel;
bvlProfileSwitching: TBevel; 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 FormCreate(Sender: TObject);
procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType); procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType);
procedure btnCheckUpdatesClick(Sender: TObject); procedure btnCheckUpdatesClick(Sender: TObject);
procedure LEDButtonClick(Sender: TObject);
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure cmbProfilesClick(Sender: TObject); procedure cmbProfilesClick(Sender: TObject);
procedure cbCheckUpdatesClick(Sender: TObject); procedure cbCheckUpdatesClick(Sender: TObject);
@ -124,8 +120,14 @@ type
procedure btnDeleteProfileClick(Sender: TObject); procedure btnDeleteProfileClick(Sender: TObject);
procedure cbProfileMenuClick(Sender: TObject); procedure cbProfileMenuClick(Sender: TObject);
procedure cbProfileMenuCascadedClick(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 private
FLEDControls: array[0..LED_COUNT - 1] of TLEDControls; FLEDControls: array[0..LED_COUNT - 1] of TButtonAssignmentFrame;
FEventMonitor: TOmniEventMonitor; FEventMonitor: TOmniEventMonitor;
FProfilesFilename: string; FProfilesFilename: string;
@ -180,6 +182,8 @@ type
procedure HandleDeviceStateMessage(AMessage: TOmniMessage); procedure HandleDeviceStateMessage(AMessage: TOmniMessage);
procedure HandleFSXStateMessage(AMessage: TOmniMessage); procedure HandleFSXStateMessage(AMessage: TOmniMessage);
procedure LEDConfigurationClick(Sender: TObject);
procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE; procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE;
property EventMonitor: TOmniEventMonitor read FEventMonitor; property EventMonitor: TOmniEventMonitor read FEventMonitor;
@ -287,7 +291,7 @@ begin
worker := TFSXStateMonitorWorker.Create; worker := TFSXStateMonitorWorker.Create;
EventMonitor.Monitor(CreateTask(worker)).Run; EventMonitor.Monitor(CreateTask(worker)).Run;
TProfileManager.Attach(Self); Profiles.Attach(Self);
FindLEDControls; FindLEDControls;
@ -306,7 +310,7 @@ begin
FinalizeProfileMenu; FinalizeProfileMenu;
UnregisterDeviceArrival; UnregisterDeviceArrival;
TProfileManager.Detach(Self); Profiles.Detach(Self);
end; end;
@ -378,7 +382,7 @@ var
profile: TProfile; profile: TProfile;
begin begin
profile := TProfileManager.Instance.ActiveProfile; profile := Profiles.ActiveProfile;
if Settings.ActiveProfile <> profile.Name then if Settings.ActiveProfile <> profile.Name then
begin begin
@ -386,12 +390,13 @@ begin
SaveSettings; SaveSettings;
end; end;
FLockChangeProfile := True; // #ToDo1 -oMvR: 21-4-2013: invalidate profile node
try // FLockChangeProfile := True;
cmbProfiles.ItemIndex := cmbProfiles.Items.IndexOfObject(profile); // try
finally // cmbProfiles.ItemIndex := cmbProfiles.Items.IndexOfObject(profile);
FLockChangeProfile := False; // finally
end; // FLockChangeProfile := False;
// end;
LoadActiveProfile; LoadActiveProfile;
end; end;
@ -411,20 +416,17 @@ procedure TMainForm.FindLEDControls;
var var
ledIndex: Integer; ledIndex: Integer;
ledNumber: string; ledNumber: string;
buttonFrame: TButtonAssignmentFrame;
begin begin
for ledIndex := 0 to Pred(LED_COUNT) do for ledIndex := 0 to Pred(LED_COUNT) do
begin begin
ledNumber := IntToStr(Succ(ledIndex)); ledNumber := IntToStr(Succ(ledIndex));
FLEDControls[ledIndex].ConfigureButton := (ComponentByName('btnP' + ledNumber, ledIndex) as TButton); buttonFrame := (ComponentByName('bafP' + ledNumber, ledIndex) as TButtonAssignmentFrame);
FLEDControls[ledIndex].CategoryLabel := (ComponentByName('lblP' + ledNumber + 'Category', ledIndex) as TLabel); buttonFrame.OnConfigurationClick := LEDConfigurationClick;
FLEDControls[ledIndex].FunctionLabel := (ComponentByName('lblP' + ledNumber + 'Function', ledIndex) as TLabel);
FLEDControls[ledIndex].ConfigureButton.OnClick := LEDButtonClick; FLEDControls[ledIndex] := buttonFrame;
FLEDControls[ledIndex].CategoryLabel.Caption := '';
FLEDControls[ledIndex].CategoryLabel.Font.Color := clGrayText;
FLEDControls[ledIndex].FunctionLabel.Caption := '';
end; end;
end; end;
@ -454,43 +456,43 @@ begin
begin begin
Debug.Log('UI: Succesfully converted 0.x profile'); Debug.Log('UI: Succesfully converted 0.x profile');
defaultProfile.Name := DefaultProfileName; defaultProfile.Name := DefaultProfileName;
defaultProfile.IsTemporary := True;
end; end;
if Assigned(defaultProfile) then if Assigned(defaultProfile) then
TProfileManager.Add(defaultProfile); Profiles.Add(defaultProfile);
end else end else
begin begin
persistXML := TX2UtPersistXML.Create; persistXML := TX2UtPersistXML.Create;
try try
persistXML.FileName := FProfilesFilename; persistXML.FileName := FProfilesFilename;
TProfileManager.Load(persistXML.CreateReader); Profiles.Load(persistXML.CreateReader);
finally finally
FreeAndNil(persistXML); FreeAndNil(persistXML);
end; end;
end; end;
{ Make sure we always have a profile } { Make sure we always have a profile }
if TProfileManager.Instance.Count = 0 then if Profiles.Count = 0 then
begin begin
Debug.Log('UI: No profiles found, creating default profile'); Debug.Log('UI: No profiles found, creating default profile');
TProfileManager.Add(CreateDefaultProfile); Profiles.Add(CreateDefaultProfile);
end; end;
FLockChangeProfile := True; // #ToDo1 -oMvR: 21-4-2013: load tree
try // FLockChangeProfile := True;
cmbProfiles.Items.BeginUpdate; // try
try // cmbProfiles.Items.BeginUpdate;
cmbProfiles.Items.Clear; // try
// cmbProfiles.Items.Clear;
for profile in TProfileManager.Instance do //
cmbProfiles.Items.AddObject(profile.Name, profile); // for profile in TProfileManager.Instance do
finally // cmbProfiles.Items.AddObject(profile.Name, profile);
cmbProfiles.Items.EndUpdate; // finally
end; // cmbProfiles.Items.EndUpdate;
finally // end;
FLockChangeProfile := False; // finally
end; // FLockChangeProfile := False;
// end;
finally finally
Debug.UnIndent; Debug.UnIndent;
end; end;
@ -507,7 +509,7 @@ begin
persistXML := TX2UtPersistXML.Create; persistXML := TX2UtPersistXML.Create;
try try
persistXML.FileName := FProfilesFilename; persistXML.FileName := FProfilesFilename;
TProfileManager.Instance.Save(persistXML.CreateWriter); Profiles.Save(persistXML.CreateWriter);
finally finally
FreeAndNil(persistXML); FreeAndNil(persistXML);
end; end;
@ -552,13 +554,21 @@ begin
{ Default profile } { Default profile }
profile := nil; profile := nil;
if Length(Settings.ActiveProfile) > 0 then 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 } { LoadProfiles ensures there's always at least 1 profile }
if (not Assigned(profile)) and (TProfileManager.Instance.Count > 0) then if (not Assigned(profile)) and (Profiles.Count > 0) then
profile := TProfileManager.Instance[0]; profile := Profiles[0];
TProfileManager.Instance.ActiveProfile := profile; Profiles.ActiveProfile := profile;
{ Auto-update } { Auto-update }
cbCheckUpdates.Checked := Settings.CheckUpdates; cbCheckUpdates.Checked := Settings.CheckUpdates;
@ -601,7 +611,7 @@ begin
{ Default button functions are assigned during UpdateButton } { Default button functions are assigned during UpdateButton }
Result := TProfile.Create; Result := TProfile.Create;
Result.Name := DefaultProfileName; Result.Name := DefaultProfileName;
Result.IsTemporary := True; // Result.IsTemporary := True;
end; end;
@ -611,7 +621,8 @@ var
buttonIndex: Integer; buttonIndex: Integer;
begin begin
activeProfile := TProfileManager.Instance.ActiveProfile; // #ToDo1 -oMvR: 21-4-2013: change to LoadSelectedProfile
activeProfile := Profiles.ActiveProfile;
if not Assigned(activeProfile) then if not Assigned(activeProfile) then
exit; exit;
@ -652,16 +663,52 @@ begin
if Assigned(buttonFunction) then if Assigned(buttonFunction) then
begin begin
FLEDControls[AButtonIndex].CategoryLabel.Caption := buttonFunction.GetCategoryName; FLEDControls[AButtonIndex].CategoryName := buttonFunction.GetCategoryName;
FLEDControls[AButtonIndex].FunctionLabel.Caption := buttonFunction.GetDisplayName; FLEDControls[AButtonIndex].FunctionName := buttonFunction.GetDisplayName;
end; end;
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); procedure TMainForm.AddProfile(AProfile: TProfile);
begin begin
cmbProfiles.Items.AddObject(AProfile.Name, AProfile); // cmbProfiles.Items.AddObject(AProfile.Name, AProfile);
TProfileManager.Instance.Add(AProfile, True); Profiles.Add(AProfile, True);
end; end;
@ -671,18 +718,18 @@ var
oldItemIndex: Integer; oldItemIndex: Integer;
begin begin
itemIndex := cmbProfiles.Items.IndexOfObject(AProfile); // itemIndex := cmbProfiles.Items.IndexOfObject(AProfile);
if itemIndex > -1 then // if itemIndex > -1 then
begin // begin
oldItemIndex := cmbProfiles.ItemIndex; // oldItemIndex := cmbProfiles.ItemIndex;
FLockChangeProfile := True; // FLockChangeProfile := True;
try // try
cmbProfiles.Items[itemIndex] := AProfile.Name; // cmbProfiles.Items[itemIndex] := AProfile.Name;
cmbProfiles.ItemIndex := oldItemIndex; // cmbProfiles.ItemIndex := oldItemIndex;
finally // finally
FLockChangeProfile := False; // FLockChangeProfile := False;
end; // end;
end; // end;
end; end;
@ -691,39 +738,39 @@ var
itemIndex: Integer; itemIndex: Integer;
begin begin
itemIndex := cmbProfiles.Items.IndexOfObject(AProfile); // itemIndex := cmbProfiles.Items.IndexOfObject(AProfile);
if itemIndex > -1 then // if itemIndex > -1 then
begin // begin
TProfileManager.Remove(AProfile); // TProfileManager.Remove(AProfile);
cmbProfiles.Items.Delete(itemIndex); // cmbProfiles.Items.Delete(itemIndex);
//
if TProfileManager.Instance.Count = 0 then // if TProfileManager.Instance.Count = 0 then
AddProfile(CreateDefaultProfile); // AddProfile(CreateDefaultProfile);
//
if ASetActiveProfile then // if ASetActiveProfile then
begin // begin
if itemIndex >= TProfileManager.Instance.Count then // if itemIndex >= TProfileManager.Instance.Count then
itemIndex := Pred(TProfileManager.Instance.Count); // itemIndex := Pred(TProfileManager.Instance.Count);
//
FLockChangeProfile := True; // FLockChangeProfile := True;
try // try
cmbProfiles.ItemIndex := itemIndex; // cmbProfiles.ItemIndex := itemIndex;
TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[itemIndex]); // TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[itemIndex]);
finally // finally
FLockChangeProfile := False; // FLockChangeProfile := False;
end; // end;
end; // end;
end; // end;
end; end;
procedure TMainForm.cmbProfilesClick(Sender: TObject); procedure TMainForm.cmbProfilesClick(Sender: TObject);
begin begin
if not FLockChangeProfile then // if not FLockChangeProfile then
begin // begin
if cmbProfiles.ItemIndex > -1 then // if cmbProfiles.ItemIndex > -1 then
TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]); // TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]);
end; // end;
end; end;
@ -786,7 +833,7 @@ begin
end; end;
procedure TMainForm.LEDButtonClick(Sender: TObject); procedure TMainForm.LEDConfigurationClick(Sender: TObject);
function GetUniqueProfileName(const AName: string): string; function GetUniqueProfileName(const AName: string): string;
var var
@ -796,14 +843,15 @@ procedure TMainForm.LEDButtonClick(Sender: TObject);
Result := AName; Result := AName;
counter := 0; counter := 0;
while Assigned(TProfileManager.Find(Result)) do // while Assigned(Profiles.Find(Result)) do
begin // begin
Inc(counter); // Inc(counter);
Result := Format('%s (%d)', [AName, counter]); // Result := Format('%s (%d)', [AName, counter]);
end; // end;
end; end;
// #ToDo1 -oMvR: 6-5-2013: new style!
var var
activeProfile: TProfile; activeProfile: TProfile;
buttonIndex: NativeInt; buttonIndex: NativeInt;
@ -811,25 +859,25 @@ var
newProfile: Boolean; newProfile: Boolean;
begin begin
activeProfile := TProfileManager.Instance.ActiveProfile; activeProfile := Profiles.ActiveProfile;
if not Assigned(activeProfile) then if not Assigned(activeProfile) then
exit; exit;
{ Behaviour similar to the Windows System Sounds control panel; { Behaviour similar to the Windows System Sounds control panel;
when a change occurs, create a temporary profile "(modified)" when a change occurs, create a temporary profile "(modified)"
so the original profile can still be selected } so the original profile can still be selected }
if not activeProfile.IsTemporary then // if not activeProfile.IsTemporary then
begin // begin
profile := TProfile.Create; // profile := TProfile.Create;
profile.Assign(activeProfile); // profile.Assign(activeProfile);
profile.Name := GetUniqueProfileName(profile.Name + ProfilePostfixModified); // profile.Name := GetUniqueProfileName(profile.Name + ProfilePostfixModified);
profile.IsTemporary := True; // profile.IsTemporary := True;
newProfile := True; // newProfile := True;
end else // end else
begin // begin
profile := activeProfile; profile := activeProfile;
newProfile := False; newProfile := False;
end; // end;
buttonIndex := (Sender as TComponent).Tag; buttonIndex := (Sender as TComponent).Tag;
if TButtonFunctionForm.Execute(profile, buttonIndex) then if TButtonFunctionForm.Execute(profile, buttonIndex) then
@ -955,13 +1003,13 @@ var
begin begin
name := ''; name := '';
profile := TProfileManager.Instance.ActiveProfile; profile := Profiles.ActiveProfile;
existingProfile := nil; existingProfile := nil;
repeat repeat
if InputQuery('Save profile as', 'Save this profile as:', name) then if InputQuery('Save profile as', 'Save this profile as:', name) then
begin begin
existingProfile := TProfileManager.Find(name); existingProfile := Profiles.FindByName(name);
if existingProfile = profile then if existingProfile = profile then
existingProfile := nil; existingProfile := nil;
@ -986,24 +1034,24 @@ begin
existingProfile.Assign(profile); existingProfile.Assign(profile);
existingProfile.Name := name; existingProfile.Name := name;
UpdateProfile(existingProfile); UpdateProfile(existingProfile);
TProfileManager.Instance.ActiveProfile := existingProfile; Profiles.ActiveProfile := existingProfile;
if profile.IsTemporary then // if profile.IsTemporary then
DeleteProfile(profile, False); // DeleteProfile(profile, False);
end else
begin
if profile.IsTemporary then
begin
profile.Name := name;
profile.IsTemporary := False;
UpdateProfile(profile);
end else end else
begin begin
// if profile.IsTemporary then
// begin
// profile.Name := name;
// profile.IsTemporary := False;
// UpdateProfile(profile);
// end else
// begin
newProfile := TProfile.Create; newProfile := TProfile.Create;
newProfile.Assign(profile); newProfile.Assign(profile);
newProfile.Name := name; newProfile.Name := name;
AddProfile(newProfile); AddProfile(newProfile);
end; // end;
end; end;
SaveProfiles; SaveProfiles;
@ -1015,7 +1063,7 @@ var
activeProfile: TProfile; activeProfile: TProfile;
begin begin
activeProfile := TProfileManager.Instance.ActiveProfile; activeProfile := Profiles.ActiveProfile;
if Assigned(activeProfile) then if Assigned(activeProfile) then
begin begin
if MessageBox(Self.Handle, PChar(Format('Do you want to remove the profile named "%s"?', [activeProfile.Name])), if MessageBox(Self.Handle, PChar(Format('Do you want to remove the profile named "%s"?', [activeProfile.Name])),

View File

@ -1,8 +1,8 @@
program G940LEDControl; program G940LEDControl;
uses uses
Forms, System.SysUtils,
SysUtils, Vcl.Forms,
MainFrm in 'Forms\MainFrm.pas' {MainForm}, MainFrm in 'Forms\MainFrm.pas' {MainForm},
LogiJoystickDLL in '..\Shared\LogiJoystickDLL.pas', LogiJoystickDLL in '..\Shared\LogiJoystickDLL.pas',
SimConnect in '..\Shared\SimConnect.pas', SimConnect in '..\Shared\SimConnect.pas',
@ -36,7 +36,8 @@ uses
FSXLEDFunctionProviderIntf in 'Units\FSXLEDFunctionProviderIntf.pas', FSXLEDFunctionProviderIntf in 'Units\FSXLEDFunctionProviderIntf.pas',
GxDbugIntf in 'Units\GxDbugIntf.pas', GxDbugIntf in 'Units\GxDbugIntf.pas',
DebugLog in 'Units\DebugLog.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} {$R *.res}

View File

@ -8,7 +8,7 @@
<FrameworkType>VCL</FrameworkType> <FrameworkType>VCL</FrameworkType>
<ProjectVersion>13.4</ProjectVersion> <ProjectVersion>13.4</ProjectVersion>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config> <Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform> <Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms> <TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType> <AppType>Application</AppType>
@ -148,6 +148,11 @@
<DCCReference Include="Units\GxDbugIntf.pas"/> <DCCReference Include="Units\GxDbugIntf.pas"/>
<DCCReference Include="Units\DebugLog.pas"/> <DCCReference Include="Units\DebugLog.pas"/>
<DCCReference Include="Units\DebugLogGExperts.pas"/> <DCCReference Include="Units\DebugLogGExperts.pas"/>
<DCCReference Include="Forms\ButtonAssignmentFrm.pas">
<Form>ButtonAssignmentFrame</Form>
<FormType>dfm</FormType>
<DesignClass>TFrame</DesignClass>
</DCCReference>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -118,6 +118,7 @@ type
FProfileMenu: Boolean; FProfileMenu: Boolean;
FProfileMenuCascaded: Boolean; FProfileMenuCascaded: Boolean;
// #ToDo1 -oMvR: 6-5-2013: change to object list
FMenuProfiles: TStringList; FMenuProfiles: TStringList;
FMenuWasCascaded: Boolean; FMenuWasCascaded: Boolean;
protected protected
@ -311,9 +312,9 @@ begin
if AEnabled <> FObservingProfileManager then if AEnabled <> FObservingProfileManager then
begin begin
if AEnabled then if AEnabled then
TProfileManager.Attach(Self) Profiles.Attach(Self)
else else
TProfileManager.Detach(Self); Profiles.Detach(Self);
FObservingProfileManager := AEnabled; FObservingProfileManager := AEnabled;
end; end;
@ -552,9 +553,9 @@ begin
exit; exit;
profileName := FMenuProfiles[Pred(AEventID)]; profileName := FMenuProfiles[Pred(AEventID)];
profile := TProfileManager.Find(profileName); profile := Profiles.FindByUID(profileName);
if Assigned(profile) then if Assigned(profile) then
TProfileManager.Instance.ActiveProfile := profile; Profiles.ActiveProfile := profile;
end; end;
@ -685,8 +686,12 @@ begin
if ProfileMenu then if ProfileMenu then
begin begin
for profile in TProfileManager.Instance do try
for profile in Profiles.LockList do
FMenuProfiles.Add(profile.Name); FMenuProfiles.Add(profile.Name);
finally
Profiles.UnlockList;
end;
FMenuProfiles.Sort; FMenuProfiles.Sort;

View File

@ -44,8 +44,8 @@ type
TProfile = class(TPersistent) TProfile = class(TPersistent)
private private
FUID: string;
FName: string; FName: string;
FIsTemporary: Boolean;
FButtons: TProfileButtonList; FButtons: TProfileButtonList;
function GetButton(Index: Integer): TProfileButton; function GetButton(Index: Integer): TProfileButton;
@ -61,8 +61,8 @@ type
function HasButton(AIndex: Integer): Boolean; function HasButton(AIndex: Integer): Boolean;
property UID: string read FUID write FUID;
property Name: string read FName write FName; property Name: string read FName write FName;
property IsTemporary: Boolean read FIsTemporary write FIsTemporary;
property ButtonCount: Integer read GetButtonCount; property ButtonCount: Integer read GetButtonCount;
property Buttons[Index: Integer]: TProfileButton read GetButton; property Buttons[Index: Integer]: TProfileButton read GetButton;
@ -71,7 +71,7 @@ type
TProfileList = class(TObjectList<TProfile>) TProfileList = class(TObjectList<TProfile>)
public public
function Find(const AName: string): TProfile; // function Find(const AName: string): TProfile;
procedure Load(AReader: IX2PersistReader); procedure Load(AReader: IX2PersistReader);
procedure Save(AWriter: IX2PersistWriter); procedure Save(AWriter: IX2PersistWriter);
@ -92,7 +92,6 @@ const
KeyProviderUID = 'ProviderUID'; KeyProviderUID = 'ProviderUID';
KeyFunctionUID = 'FunctionUID'; KeyFunctionUID = 'FunctionUID';
KeyIsTemporary = 'IsTemporary';
{ TProfileButton } { TProfileButton }
@ -232,8 +231,8 @@ begin
begin begin
sourceProfile := TProfile(Source); sourceProfile := TProfile(Source);
FUID := sourceProfile.UID;
FName := sourceProfile.Name; FName := sourceProfile.Name;
FIsTemporary := sourceProfile.IsTemporary;
FButtons.Clear; FButtons.Clear;
for buttonIndex := 0 to Pred(sourceProfile.ButtonCount) do for buttonIndex := 0 to Pred(sourceProfile.ButtonCount) do
@ -251,8 +250,8 @@ var
begin begin
buttonIndex := 0; buttonIndex := 0;
if not AReader.ReadBoolean(KeyIsTemporary, FIsTemporary) then // if not AReader.ReadBoolean(KeyIsTemporary, FIsTemporary) then
FIsTemporary := False; // FIsTemporary := False;
while AReader.BeginSection(SectionButton + IntToStr(buttonIndex)) do while AReader.BeginSection(SectionButton + IntToStr(buttonIndex)) do
try try
@ -277,7 +276,7 @@ var
buttonIndex: Integer; buttonIndex: Integer;
begin begin
AWriter.WriteBoolean(KeyIsTemporary, IsTemporary); // AWriter.WriteBoolean(KeyIsTemporary, IsTemporary);
for buttonIndex := 0 to Pred(FButtons.Count) do for buttonIndex := 0 to Pred(FButtons.Count) do
begin begin
@ -330,6 +329,7 @@ end;
{ TProfileList } { TProfileList }
{
function TProfileList.Find(const AName: string): TProfile; function TProfileList.Find(const AName: string): TProfile;
var var
profile: TProfile; profile: TProfile;
@ -344,6 +344,7 @@ begin
break; break;
end; end;
end; end;
}
procedure TProfileList.Load(AReader: IX2PersistReader); procedure TProfileList.Load(AReader: IX2PersistReader);

View File

@ -3,7 +3,6 @@ unit ProfileManager;
interface interface
uses uses
System.Classes, System.Classes,
System.SyncObjs,
Profile, Profile,
X2UtPersistIntf; X2UtPersistIntf;
@ -21,57 +20,53 @@ type
TProfileManager = class; TProfileManager = class;
TProfileManagerEnumerator = class(TProfileList.TEnumerator) ILockedProfileList = interface
private ['{4F647762-AA70-4315-BB1C-E85E320F4E82}']
FManager: TProfileManager; function GetEnumerator: TProfileList.TEnumerator;
public
constructor Create(AManager: TProfileManager);
destructor Destroy; override;
end; end;
TProfileManager = class(TObject) TProfileManager = class(TObject)
private private
FLock: TCriticalSection;
FProfiles: TProfileList;
FObservers: TInterfaceList; FObservers: TInterfaceList;
FProfileList: TProfileList;
FActiveProfile: TProfile; FActiveProfile: TProfile;
function GetActiveProfile: TProfile;
function GetCount: Integer; function GetCount: Integer;
function GetItem(Index: Integer): TProfile; function GetItem(Index: Integer): TProfile;
procedure SetActiveProfile(const Value: TProfile); procedure SetActiveProfile(const Value: TProfile);
procedure SetItem(Index: Integer; const Value: TProfile); procedure SetItem(Index: Integer; const Value: TProfile);
protected protected
property Observers: TInterfaceList read FObservers; property Observers: TInterfaceList read FObservers;
property Profiles: TProfileList read FProfiles; property ProfileList: TProfileList read FProfileList;
public public
class function Instance(): TProfileManager;
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
procedure Lock; procedure Add(AProfile: TProfile; ASetActive: Boolean = False);
procedure Unlock; 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); procedure Load(AReader: IX2PersistReader);
class function Find(const AName: string): TProfile; procedure Save(AWriter: IX2PersistWriter);
class function Remove(const AProfile: TProfile): Integer;
class procedure Load(AReader: IX2PersistReader); procedure Attach(AObserver: IProfileObserver);
class procedure Save(AWriter: IX2PersistWriter); procedure Detach(AObserver: IProfileObserver);
class procedure Attach(AObserver: IProfileObserver); function LockList: ILockedProfileList;
class procedure Detach(AObserver: IProfileObserver); procedure UnlockList;
function GetEnumerator: TProfileManagerEnumerator; property ActiveProfile: TProfile read FActiveProfile write SetActiveProfile;
property ActiveProfile: TProfile read GetActiveProfile write SetActiveProfile;
property Count: Integer read GetCount; property Count: Integer read GetCount;
property Items[Index: Integer]: TProfile read GetItem write SetItem; default; property Items[Index: Integer]: TProfile read GetItem write SetItem; default;
end; end;
{ Singleton }
function Profiles: TProfileManager;
implementation implementation
@ -83,8 +78,20 @@ var
ProfileManagerInstance: TProfileManager; 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 begin
if not Assigned(ProfileManagerInstance) then if not Assigned(ProfileManagerInstance) then
ProfileManagerInstance := TProfileManager.Create; ProfileManagerInstance := TProfileManager.Create;
@ -93,136 +100,130 @@ begin
end; end;
{ TProfileManager }
constructor TProfileManager.Create; constructor TProfileManager.Create;
begin begin
inherited Create; inherited Create;
FObservers := TInterfaceList.Create; FObservers := TInterfaceList.Create;
FProfiles := TProfileList.Create(True); FProfileList := TProfileList.Create(True);
FLock := TCriticalSection.Create;
end; end;
destructor TProfileManager.Destroy; destructor TProfileManager.Destroy;
begin begin
FreeAndNil(FLock); FreeAndNil(FProfileList);
FreeAndNil(FProfiles);
FreeAndNil(FObservers); FreeAndNil(FObservers);
inherited; inherited;
end; end;
procedure TProfileManager.Lock; procedure TProfileManager.Add(AProfile: TProfile; ASetActive: Boolean);
begin
end;
procedure TProfileManager.Unlock;
begin
end;
class procedure TProfileManager.Add(AProfile: TProfile; ASetActive: Boolean);
var var
observer: IInterface; observer: IInterface;
begin begin
Instance.Lock; TMonitor.Enter(ProfileList);
try try
Instance.Profiles.Add(AProfile); ProfileList.Add(AProfile);
finally finally
Instance.Unlock; TMonitor.Exit(ProfileList);
end; end;
for observer in Instance.Observers do for observer in Observers do
(observer as IProfileObserver).ObserveAdd(AProfile); (observer as IProfileObserver).ObserveAdd(AProfile);
if ASetActive then if ASetActive then
Instance.SetActiveProfile(AProfile); SetActiveProfile(AProfile);
end; end;
class function TProfileManager.Find(const AName: string): TProfile; function TProfileManager.FindByName(const AName: string): TProfile;
begin begin
Result := Instance.Profiles.Find(AName); // Result := Instance.ProfileList.Find(AName);
end; 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 var
observer: IInterface; observer: IInterface;
begin begin
Instance.Lock; TMonitor.Enter(ProfileList);
try try
Result := Instance.Profiles.Remove(AProfile); Result := ProfileList.Remove(AProfile);
finally finally
Instance.Unlock; TMonitor.Exit(ProfileList);
end; end;
for observer in Instance.Observers do for observer in Observers do
(observer as IProfileObserver).ObserveRemove(AProfile); (observer as IProfileObserver).ObserveRemove(AProfile);
end; end;
class procedure TProfileManager.Load(AReader: IX2PersistReader); procedure TProfileManager.Load(AReader: IX2PersistReader);
begin begin
Instance.Lock; TMonitor.Enter(ProfileList);
try try
Instance.Profiles.Load(AReader); ProfileList.Load(AReader);
finally finally
Instance.Unlock; TMonitor.Exit(ProfileList);
end; end;
end; end;
class procedure TProfileManager.Save(AWriter: IX2PersistWriter); procedure TProfileManager.Save(AWriter: IX2PersistWriter);
begin begin
Instance.Lock; TMonitor.Enter(ProfileList);
try try
Instance.Profiles.Save(AWriter); ProfileList.Save(AWriter);
finally finally
Instance.Unlock; TMonitor.Exit(ProfileList);
end; end;
end; end;
class procedure TProfileManager.Attach(AObserver: IProfileObserver); procedure TProfileManager.Attach(AObserver: IProfileObserver);
begin begin
Instance.Observers.Add(AObserver as IProfileObserver); Observers.Add(AObserver as IProfileObserver);
end; end;
class procedure TProfileManager.Detach(AObserver: IProfileObserver); procedure TProfileManager.Detach(AObserver: IProfileObserver);
begin begin
Instance.Observers.Remove(AObserver as IProfileObserver); Observers.Remove(AObserver as IProfileObserver);
end; end;
function TProfileManager.GetActiveProfile: TProfile; function TProfileManager.LockList: ILockedProfileList;
begin begin
Result := Instance.FActiveProfile; TMonitor.Enter(ProfileList);
Result := TLockedProfileList.Create(ProfileList);
end;
procedure TProfileManager.UnlockList;
begin
TMonitor.Exit(ProfileList);
end; end;
function TProfileManager.GetCount: Integer; function TProfileManager.GetCount: Integer;
begin begin
Result := Instance.Profiles.Count; Result := ProfileList.Count;
end;
function TProfileManager.GetEnumerator: TProfileManagerEnumerator;
begin
Result := TProfileManagerEnumerator.Create(Self);
end; end;
function TProfileManager.GetItem(Index: Integer): TProfile; function TProfileManager.GetItem(Index: Integer): TProfile;
begin begin
Result := Profiles[Index]; Result := ProfileList[Index];
end; end;
@ -242,27 +243,25 @@ end;
procedure TProfileManager.SetItem(Index: Integer; const Value: TProfile); procedure TProfileManager.SetItem(Index: Integer; const Value: TProfile);
begin begin
Profiles[Index] := Value; ProfileList[Index] := Value;
end; end;
{ TProfileManagerEnumerator } { TLockedProfileList }
constructor TProfileManagerEnumerator.Create(AManager: TProfileManager); constructor TLockedProfileList.Create(AList: TProfileList);
begin begin
inherited Create(AManager.Profiles); inherited Create;
FManager := AManager; FList := AList;
FManager.Lock;
end; end;
destructor TProfileManagerEnumerator.Destroy; function TLockedProfileList.GetEnumerator: TProfileList.TEnumerator;
begin begin
FManager.Unlock; Result := FList.GetEnumerator;
inherited;
end; end;
initialization initialization
finalization finalization
FreeAndNil(ProfileManagerInstance); FreeAndNil(ProfileManagerInstance);