Commit a80040c

Nick committed on
Implemented fine grained selection
commit a80040cf2e6de902efca465d337dc04ff17e6f80 parent e61143c
2 changed files +116−82
Modifiedtracker.pas +4−4
@@ -254,8 +254,8 @@ begin
254 Pen.Width := 2; 254 Pen.Width := 2;
255 MoveTo(0, H); 255 MoveTo(0, H);
256 for I := 0 to 32 do 256 for I := 0 to 32 do
257 LineTo(I*Interval, Round((Wave[I]/$F)*H)); 257 LineTo(I*Interval, Trunc((Wave[I]/$F)*H));
258 LineTo(W, Round((Wave[0]/$F)*H)); 258 LineTo(W, Trunc((Wave[0]/$F)*H));
259 end; 259 end;
260 end; 260 end;
261 261
@@ -746,11 +746,11 @@ var
746 Idx: Integer; 746 Idx: Integer;
747 begin 747 begin
748 if DrawingWave then begin 748 if DrawingWave then begin
749 Idx := Round((X / WaveEditPaintBox.Width)*32); 749 Idx := Trunc((X / WaveEditPaintBox.Width)*32);
750 CurrentWave^[Idx] := 750 CurrentWave^[Idx] :=
751 Min($F, 751 Min($F,
752 Max(0, 752 Max(0,
753 Round((Y / WaveEditPaintBox.Height)*$F))); 753 Trunc((Y / WaveEditPaintBox.Height)*$F)));
754 WaveEditPaintBox.Invalidate; 754 WaveEditPaintBox.Invalidate;
755 end; 755 end;
756 end; 756 end;
Modifiedtrackergrid.pas +112−78
@@ -8,19 +8,27 @@ uses
8 Classes, SysUtils, Controls, Graphics, Constants, LCLType, math, 8 Classes, SysUtils, Controls, Graphics, Constants, LCLType, math,
9 LCLIntf, LMessages, ClipboardUtils, HugeDatatypes; 9 LCLIntf, LMessages, ClipboardUtils, HugeDatatypes;
10 10
11 // TODO: Maybe read these from a config file
11 const 12 const
12 clMisc = clMaroon; 13 clNote = TColor($7F4A00);
13 clPitch = clYellow; 14 clInstrument = TColor($7F7F00);
14 clVolume = clGreen; 15 clVolume = TColor($99FFB7);
15 clPan = clTeal; 16
16 clSong = clRed; 17 clFxMisc = TColor($3F3F7C);
18 clFxPitch = TColor($006262);
19 clFxVolume = TColor($007F26);
20 clFxPan = clInstrument;
21 clFxSong = TColor($00007F);
22
23 NumColumns = 4;
24 NumRows = 64;
17 25
18 type 26 type
19 TCellPart = (cpNote, cpInstrument, cpVolume, cpEffect); 27 TCellPart = (cpNote = 0, cpInstrument = 1, cpVolume = 2, cpEffect = 3);
20 28
21 TSelectionPos = record 29 TSelectionPos = record
22 X, Y: Integer; 30 X, Y: Integer;
23 SelectedPart: set of TCellPart 31 SelectedPart: TCellPart
24 end; 32 end;
25 33
26 { TTrackerGrid } 34 { TTrackerGrid }
@@ -58,18 +66,13 @@ type
58 66
59 function GetEffectColor(EffectCode: Integer): TColor; 67 function GetEffectColor(EffectCode: Integer): TColor;
60 function SelectionsToRect(S1, S2: TSelectionPos): TRect; 68 function SelectionsToRect(S1, S2: TSelectionPos): TRect;
69 function SelectionToRect(Selection: TSelectionPos): TRect;
70 function MousePosToSelection(X, Y: Integer): TSelectionPos;
61 71
62 public 72 public
63 Cursor, Other: TSelectionPos; 73 Cursor, Other: TSelectionPos;
64 SelectedRow: Integer;
65 end; 74 end;
66 75
67 const
68 NotePosition = 0;
69 InstrumentPosition = 3;
70 VolumePosition = 5;
71 EffectPosition = 8;
72
73 implementation 76 implementation
74 77
75 { TTrackerGrid } 78 { TTrackerGrid }
@@ -80,16 +83,15 @@ var
80 begin 83 begin
81 inherited Create(AOwner); 84 inherited Create(AOwner);
82 85
83 ControlStyle := ControlStyle + [csCaptureMouse, csClickEvents, 86 ControlStyle := ControlStyle + [csCaptureMouse, csClickEvents, csDoubleClicks];
84 csDoubleClicks];
85 Self.Parent := Parent; 87 Self.Parent := Parent;
86 88
87 // Kind of a hack 89 // Kind of a hack
88 with Canvas.Font do begin 90 with Canvas.Font do begin
89 Name := 'Pixelite'; 91 Name := 'Pixelite';
90 Size := 12; 92 Size := 12;
91 ColumnWidth := GetTextWidth('C-501v64C01'); 93 ColumnWidth := GetTextWidth('C-5 01v64C01 ');
92 RowHeight := GetTextHeight('C-501v64C01'); 94 RowHeight := GetTextHeight('C-5 01v64C01 ');
93 95
94 CharHeight := RowHeight; 96 CharHeight := RowHeight;
95 CharWidth := GetTextWidth('C'); 97 CharWidth := GetTextWidth('C');
@@ -123,7 +125,7 @@ begin
123 Brush.Color := RGBToColor(206, 197, 181); 125 Brush.Color := RGBToColor(206, 197, 181);
124 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight); 126 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight);
125 end; 127 end;
126 if I = SelectedRow then begin 128 if I = Cursor.Y then begin
127 Brush.Color := RGBToColor(169, 153, 122); 129 Brush.Color := RGBToColor(169, 153, 122);
128 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight); 130 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight);
129 end; 131 end;
@@ -133,7 +135,7 @@ begin
133 end; 135 end;
134 end; 136 end;
135 137
136 {Canvas.Pen.Color := RGBToColor(169, 153, 122); 138 Canvas.Pen.Color := TColor($ABB7BC);
137 Canvas.Pen.Width := 2; 139 Canvas.Pen.Width := 2;
138 R := TRect.Create(0, 0, ColumnWidth+1, Height); 140 R := TRect.Create(0, 0, ColumnWidth+1, Height);
139 Canvas.Rectangle(R); 141 Canvas.Rectangle(R);
@@ -144,15 +146,13 @@ begin
144 R := TRect.Create(ColumnWidth*3, 0, ColumnWidth, Height); 146 R := TRect.Create(ColumnWidth*3, 0, ColumnWidth, Height);
145 Canvas.Rectangle(R); 147 Canvas.Rectangle(R);
146 R := TRect.Create(ColumnWidth*4, 0, ColumnWidth, Height); 148 R := TRect.Create(ColumnWidth*4, 0, ColumnWidth, Height);
147 Canvas.Rectangle(R);} 149 Canvas.Rectangle(R);
148 150
149 RenderSelectedArea; 151 RenderSelectedArea;
150 end; 152 end;
151 153
152 procedure TTrackerGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X, 154 procedure TTrackerGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
153 Y: Integer); 155 Y: Integer);
154 var
155 SelectedColumn: Integer;
156 begin 156 begin
157 inherited MouseDown(Button, Shift, X, Y); 157 inherited MouseDown(Button, Shift, X, Y);
158 158
@@ -162,13 +162,7 @@ begin
162 if not (csDesigning in ComponentState) and CanFocus then 162 if not (csDesigning in ComponentState) and CanFocus then
163 SetFocus; 163 SetFocus;
164 164
165 SelectedRow := Round((Y/Height)*63); 165 Cursor := MousePosToSelection(X, Y);
166 SelectedColumn := Round((X/Width)*4);
167 with Cursor do begin
168 X := SelectedColumn;
169 Y := SelectedRow;
170 SelectedPart := [];
171 end;
172 166
173 ClampCursors; 167 ClampCursors;
174 Other := Cursor; 168 Other := Cursor;
@@ -177,20 +171,12 @@ begin
177 end; 171 end;
178 172
179 procedure TTrackerGrid.MouseMove(Shift: TShiftState; X, Y: Integer); 173 procedure TTrackerGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
180 var
181 SelectedRow, SelectedColumn: Integer;
182 begin 174 begin
183 inherited MouseMove(Shift, X, Y); 175 inherited MouseMove(Shift, X, Y);
184 176
185 if MouseButtonDown then begin 177 if MouseButtonDown then begin
186 Selecting := True; 178 Selecting := True;
187 SelectedRow := Round((Y/Height)*63); 179 Other := MousePosToSelection(X, Y);
188 SelectedColumn := Round((X/Width)*4);
189 with Other do begin
190 X := SelectedColumn;
191 Y := SelectedRow;
192 SelectedPart := [];
193 end;
194 180
195 ClampCursors; 181 ClampCursors;
196 182
@@ -210,13 +196,24 @@ procedure TTrackerGrid.KeyDown(var Key: Word; Shift: TShiftState);
210 begin 196 begin
211 inherited KeyDown(Key, Shift); 197 inherited KeyDown(Key, Shift);
212 198
213 Selecting := False; 199 Writeln(Cursor.SelectedPart, ' ', High(TCellPart), ' ', Low(TCellPart));
214
215 case Key of 200 case Key of
216 VK_UP: Cursor.Y -= 1; 201 VK_UP: Cursor.Y -= 1;
217 VK_DOWN: Cursor.Y += 1; 202 VK_DOWN: Cursor.Y += 1;
218 VK_LEFT: Cursor.X -= 1; 203 VK_LEFT: begin
219 VK_RIGHT: Cursor.X += 1; 204 if ssCtrl in Shift then
205 Cursor.X -= 1
206 else if Cursor.SelectedPart > Low(TCellPart) then begin
207 Cursor.SelectedPart := Pred(Cursor.SelectedPart);
208 end;
209 end;
210 VK_RIGHT: begin
211 if ssCtrl in Shift then
212 Cursor.X += 1
213 else if Cursor.SelectedPart < High(TCellPart) then begin
214 Cursor.SelectedPart := Succ(Cursor.SelectedPart);
215 end;
216 end;
220 else begin 217 else begin
221 with Cells[Cursor.X, Cursor.Y] do begin 218 with Cells[Cursor.X, Cursor.Y] do begin
222 Instrument := Random(20); 219 Instrument := Random(20);
@@ -227,8 +224,11 @@ begin
227 end; 224 end;
228 end; 225 end;
229 226
227 if not (ssShift in Shift) then
228 Other := Cursor;
229 Selecting := ssShift in Shift;
230
230 ClampCursors; 231 ClampCursors;
231 SelectedRow := Cursor.Y;
232 232
233 Invalidate 233 Invalidate
234 end; 234 end;
@@ -249,7 +249,6 @@ procedure TTrackerGrid.RenderSelectedArea;
249 var 249 var
250 R: TRect; 250 R: TRect;
251 begin 251 begin
252 if Selecting then begin
253 R := SelectionsToRect(Cursor, Other); 252 R := SelectionsToRect(Cursor, Other);
254 253
255 with Cursor do begin; 254 with Cursor do begin;
@@ -264,19 +263,6 @@ begin
264 R.Top, 263 R.Top,
265 DSTINVERT); 264 DSTINVERT);
266 end; 265 end;
267 end
268 else
269 with Cursor do
270 BitBlt(
271 Canvas.Handle,
272 Cursor.X*ColumnWidth,
273 Cursor.Y*RowHeight,
274 ColumnWidth,
275 RowHeight,
276 Canvas.Handle,
277 Cursor.X*ColumnWidth,
278 Cursor.Y*RowHeight,
279 DSTINVERT);
280 end; 266 end;
281 267
282 procedure TTrackerGrid.ClampCursors; 268 procedure TTrackerGrid.ClampCursors;
@@ -306,7 +292,7 @@ var
306 begin 292 begin
307 with Canvas do begin 293 with Canvas do begin
308 if NoteMap.TryGetData(Cell.Note, NoteString) then begin 294 if NoteMap.TryGetData(Cell.Note, NoteString) then begin
309 Font.Color := clBlue; 295 Font.Color := clNote;
310 TextOut(PenPos.X, PenPos.Y, NoteString); 296 TextOut(PenPos.X, PenPos.Y, NoteString);
311 end 297 end
312 else begin 298 else begin
@@ -314,8 +300,10 @@ begin
314 TextOut(PenPos.X, PenPos.Y, '...'); 300 TextOut(PenPos.X, PenPos.Y, '...');
315 end; 301 end;
316 302
303 TextOut(PenPos.X, PenPos.Y, ' ');
304
317 if Cell.Instrument <> 0 then begin 305 if Cell.Instrument <> 0 then begin
318 Font.Color := clTeal; 306 Font.Color := clInstrument;
319 TextOut(PenPos.X, PenPos.Y, FormatFloat('00', Cell.Instrument)); 307 TextOut(PenPos.X, PenPos.Y, FormatFloat('00', Cell.Instrument));
320 end 308 end
321 else begin 309 else begin
@@ -339,6 +327,8 @@ begin
339 Font.Color := clGray; 327 Font.Color := clGray;
340 TextOut(PenPos.X, PenPos.Y, '...'); 328 TextOut(PenPos.X, PenPos.Y, '...');
341 end; 329 end;
330
331 TextOut(PenPos.X, PenPos.Y, ' ');
342 end; 332 end;
343 end; 333 end;
344 334
@@ -346,29 +336,73 @@ function TTrackerGrid.GetEffectColor(EffectCode: Integer): TColor;
346 begin 336 begin
347 Result := clBlack; 337 Result := clBlack;
348 case EffectCode of 338 case EffectCode of
349 $0: Result := clMisc; 339 $0: Result := clFxMisc;
350 $1: Result := clPitch; 340 $1: Result := clFxPitch;
351 $2: Result := clPitch; 341 $2: Result := clFxPitch;
352 $3: Result := clPitch; 342 $3: Result := clFxPitch;
353 $4: Result := clPitch; 343 $4: Result := clFxPitch;
354 $5: Result := clSong; 344 $5: Result := clFxSong;
355 $6: Result := clMisc; 345 $6: Result := clFxMisc;
356 $7: Result := clMisc; 346 $7: Result := clFxMisc;
357 $8: Result := clPan; 347 $8: Result := clFxPan;
358 $9: Result := clSong; 348 $9: Result := clFxSong;
359 $A: Result := clVolume; 349 $A: Result := clFxVolume;
360 $B: Result := clSong; 350 $B: Result := clFxSong;
361 $C: Result := clVolume; 351 $C: Result := clFxVolume;
362 $D: Result := clSong; 352 $D: Result := clFxSong;
363 $E: Result := clMisc; 353 $E: Result := clFxMisc;
364 $F: Result := clSong; 354 $F: Result := clFxSong;
365 end; 355 end;
366 end; 356 end;
367 357
368 function TTrackerGrid.SelectionsToRect(S1, S2: TSelectionPos): TRect; 358 function TTrackerGrid.SelectionsToRect(S1, S2: TSelectionPos): TRect;
369 begin 359 begin
370 Result := TRect.Create(S1.X*ColumnWidth, S1.Y*RowHeight, S1.X*ColumnWidth + ColumnWidth, S1.Y*RowHeight + RowHeight); 360 Result := SelectionToRect(S1);
371 Result.Union(TRect.Create(S2.X*ColumnWidth, S2.Y*RowHeight, S2.X*ColumnWidth + ColumnWidth, S2.Y*RowHeight + RowHeight)); 361 Result.Union(SelectionToRect(S2));
362 end;
363
364 function TTrackerGrid.SelectionToRect(Selection: TSelectionPos): TRect;
365 var
366 CharLeft, CharRight: Integer;
367 begin
368 case Selection.SelectedPart of
369 cpNote: begin
370 CharLeft := 0;
371 CharRight := 3;
372 end;
373 cpInstrument: begin
374 CharLeft := 4;
375 CharRight := 6
376 end;
377 cpVolume: begin
378 CharLeft := 6;
379 CharRight := 9;
380 end;
381 cpEffect: begin
382 CharLeft := 9;
383 CharRight := 12;
384 end;
385 end;
386
387 Result.Left := (Selection.X*ColumnWidth) + (CharLeft*CharWidth);
388 Result.Right := (Selection.X*ColumnWidth) + (CharRight*CharWidth);
389 Result.Top := (Selection.Y*RowHeight);
390 Result.Bottom := (Selection.Y*RowHeight) + RowHeight;
391 end;
392
393 function TTrackerGrid.MousePosToSelection(X, Y: Integer): TSelectionPos;
394 begin
395 Result.X := Trunc((X/Width)*NumColumns);
396 Result.Y := Trunc((Y/Height)*NumRows);
397
398 X := (min(X, width-1) mod ColumnWidth);
399 X := Trunc((X/ColumnWidth)*13);
400 case X of
401 0..3: Result.SelectedPart := cpNote;
402 4..6: Result.SelectedPart := cpInstrument;
403 7..9: Result.SelectedPart := cpVolume;
404 10..12: Result.SelectedPart := cpEffect;
405 end;
372 end; 406 end;
373 407
374 end. 408 end.