forked from geraldholdsworth/DiscImageManager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImportSelectorUnit.pas
280 lines (254 loc) · 9.44 KB
/
ImportSelectorUnit.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
unit ImportSelectorUnit;
{
Copyright (C) 2018-2023 Gerald Holdsworth [email protected]
This source is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public Licence as published by the Free
Software Foundation; either version 3 of the Licence, or (at your option)
any later version.
This code is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public Licence for more
details.
A copy of the GNU General Public Licence is available on the World Wide Web
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1335, USA.
}
{$mode objfpc}{$H+}
interface
uses
Classes,SysUtils,Forms,Controls,Graphics,Dialogs,ComCtrls,ExtCtrls,LCLIntf,
GJHCustomComponents,DiscImage;
type
{ TImportSelectorForm }
TImportSelectorForm = class(TForm)
TickIcons: TImageList;
ImageList2: TImageList;
ButtonPanel: TPanel;
ImportDirList: TTreeView;
OKButton,
CancelButton: TGJHButton;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure ImportDirListCreateNodeClass(Sender: TCustomTreeView;
var NodeClass: TTreeNodeClass);
procedure ImportDirListCustomDraw(Sender: TCustomTreeView;
const ARect: TRect; var DefaultDraw: Boolean);
procedure ImportDirListGetImageIndex(Sender: TObject; Node: TTreeNode);
procedure ButtonPanelResize(Sender: TObject);
procedure TickNode(Node: TTreeNode; Ticked: Boolean);
procedure ToggleTreeViewTickBoxes(Node: TTreeNode);
function IsNodeTicked(ANode:TTreeNode): Boolean;
function IsNodeTicked(dir,entry: Integer): Boolean; overload;
procedure TreeView1Click(Sender: TObject);
private
ratio : Real;
const
//Tick, Untick or Indeterminate graphics
ImgIndexTicked = 0;
ImgIndexUnTicked= 1;
ImgIndexInter = 2;
public
//Copy of the image that is being imported (used to get the correct icon)
FImage: TDiscImage;
end;
var
ImportSelectorForm: TImportSelectorForm;
implementation
{$R *.lfm}
uses MainUnit;
{------------------------------------------------------------------------------}
//Tick, or untick, the node. Affects any children and parents too.
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.TickNode(Node: TTreeNode; Ticked: Boolean);
var
Child: TTreeNode;
ParentStatus: Integer;
begin
//Ensure that the node actually exists
if Assigned(Node) then
begin
//Set it
if Ticked then Node.StateIndex:=ImgIndexTicked;
//Unset it
if not Ticked then Node.StateIndex:=ImgIndexUnTicked;
//Now we'll set/unset any children and grandchildren
Child:=Node.GetFirstChild; //The first child
//Continue until there are no more
while Child<>nil do
begin
//Copy the parent's ticked status
TickNode(Child,Ticked);
//And move onto the next child
Child:=Node.GetNextChild(Child);
end;
//Now we'll go upwards and do the parents and grandparents
while Node.Parent<>nil do //While there is a parent
begin
//Make a note of this node's status
ParentStatus:=Node.StateIndex;
//Get the parent's first child, which could be this one
Child:=Node.Parent.GetFirstChild;
//And go through all the parent's children
while Child<>nil do
begin
//If different to what we have noted then change the noted status
if Child.StateIndex<>ParentStatus then ParentStatus:=ImgIndexInter;
//And next child
Child:=Node.Parent.GetNextChild(Child);
end;
//Assign the noted status to the parent
Node.Parent.StateIndex:=ParentStatus;
//And move up a level
Node:=Node.Parent;
end;
end;
end;
{------------------------------------------------------------------------------}
//This just creates our custom TTreeNode
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.ImportDirListCreateNodeClass(
Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
begin
NodeClass:=TMyTreeNode;
end;
{------------------------------------------------------------------------------}
//Tile the tree
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.ImportDirListCustomDraw(Sender: TCustomTreeView;
const ARect: TRect; var DefaultDraw: Boolean);
begin
//Tile the tree
MainForm.TileCanvas(Sender.Canvas,ARect);
end;
{------------------------------------------------------------------------------}
//Update the icons
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.ImportDirListGetImageIndex(Sender: TObject;
Node: TTreeNode);
begin
MainForm.WriteToDebug('Selector Form -> ImportDirList');
if Visible then MainForm.WriteToDebug('Selector Form Visible')
else MainForm.WriteToDebug('Selector Form not Visible');
MainForm.GetImageIndex(Node,FImage);
end;
{------------------------------------------------------------------------------}
//The button panel is being resized
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.ButtonPanelResize(Sender: TObject);
begin
if ButtonPanel.ClientWidth<OKButton.Width+CancelButton.Width+3*Round(8*ratio)then
ButtonPanel.ClientWidth:=OKButton.Width+CancelButton.Width+3*Round(8*ratio);
if ButtonPanel.ClientHeight<OKButton.Height+2*Round(8*ratio)then
ButtonPanel.ClientHeight:=OKButton.Height+2*Round(8*ratio);
OKButton.Left:=ButtonPanel.ClientWidth-OKButton.Width-Round(8*ratio);
CancelButton.Left:=OKButton.Left-CancelButton.Width-Round(8*ratio);
end;
{------------------------------------------------------------------------------}
//Tile the form
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.FormPaint(Sender: TObject);
begin
MainForm.FileInfoPanelPaint(Sender);
end;
{------------------------------------------------------------------------------}
//Create the form
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.FormCreate(Sender: TObject);
begin
ratio:=PixelsPerInch/DesignTimePPI;
//Create the buttons
OKButton:=MainForm.CreateButton(ButtonPanel as TControl,'OK',True,0,0,mrOK);
CancelButton:=MainForm.CreateButton(ButtonPanel as TControl,'Cancel',False,0,
Round(4*ratio),mrCancel);
//Set the default minimum sizes
Constraints.MinHeight:=Round(456*ratio);
Constraints.MinWidth :=Round(400*ratio);
end;
{------------------------------------------------------------------------------}
//Form is just being shown
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.FormShow(Sender: TObject);
begin
//Change the form size to its default
Height:=Constraints.MinHeight;
Width :=Constraints.MinWidth;
end;
{------------------------------------------------------------------------------}
//Toggle ticked/unticked
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.ToggleTreeViewTickBoxes(Node: TTreeNode);
begin
//Check that the node exists
if Assigned(Node) then
begin
//If unticked or in an inderminate state, then set as ticked
if(Node.StateIndex=ImgIndexUnTicked)or(Node.StateIndex=ImgIndexInter)then
TickNode(Node,True)
else //If ticked, then untick
if Node.StateIndex=ImgIndexTicked then
TickNode(Node,False);
end;
end;
{------------------------------------------------------------------------------}
//Is the node ticked?
{------------------------------------------------------------------------------}
function TImportSelectorForm.IsNodeTicked(ANode:TTreeNode): Boolean;
begin
Result:=False;
If Assigned(ANode) then
Result:=ANode.StateIndex<>ImgIndexUnTicked;
end;
function TImportSelectorForm.IsNodeTicked(dir,entry: Integer): Boolean;
var
index: Integer;
Node : TTreeNode;
begin
//Counter into all the nodes
index:=0;
//Setup the Node to eventually query
Node:=nil;
//Go through the nodes until we either find it, or run out of nodes
while(Node=nil)and(index<ImportDirList.Items.Count)do
begin
//Check each node
if(TMyTreeNode(ImportDirList.Items[index]).ParentDir=dir)
and(ImportDirList.Items[index].Index=entry)
and(ImportDirList.Items[index].Level>0)then
Node:=ImportDirList.Items[index];
//Move onto the next
inc(index);
end;
//Query this node for a result (a nil Node will return False)
Result:=IsNodeTicked(Node);
end;
{------------------------------------------------------------------------------}
//User has clicked on a tickbox on one of the items
{------------------------------------------------------------------------------}
procedure TImportSelectorForm.TreeView1Click(Sender: TObject);
var
P : TPoint;
Node: TTreeNode;
ht : THitTests;
begin
//Set the TPoint to something, so the IDE doesn't whinge
P.X:=0;
//Get the position of the mouse
GetCursorPos(P);
//And convert it so it is local to the tree view
P:=ImportDirList.ScreenToClient(P);
//Where abouts has the mouse been clicked on?
ht:=ImportDirList.GetHitTestInfoAt(P.X,P.Y);
//State Icon? That's what we need.
if(htOnStateIcon in ht)then
begin
//Get the node under the moust
Node:=ImportDirList.GetNodeAt(P.X,P.Y);
//Toggle the state
ToggleTreeViewTickBoxes(Node);
end;
//It will leave it selected, so un-select
ImportDirList.ClearSelection;
end;
end.