You've already forked lazarus-ccr
Sudoku: change ScratchPad:
- different text representation of digitset - custom editor for DigitSets - forbid editing cells taht are already locked (in FRawData) - disable RangeSelect in the grids git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7245 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
63
applications/sudoku/digitseteditor.lfm
Normal file
63
applications/sudoku/digitseteditor.lfm
Normal file
@ -0,0 +1,63 @@
|
||||
object DigitSetEditorForm: TDigitSetEditorForm
|
||||
Left = 668
|
||||
Height = 240
|
||||
Top = 144
|
||||
Width = 320
|
||||
BorderStyle = bsDialog
|
||||
Caption = 'DigitSetEditorForm'
|
||||
ClientHeight = 240
|
||||
ClientWidth = 320
|
||||
KeyPreview = True
|
||||
OnActivate = FormActivate
|
||||
OnKeyPress = FormKeyPress
|
||||
OnShow = FormShow
|
||||
LCLVersion = '2.1.0.0'
|
||||
object DigitCG: TCheckGroup
|
||||
Left = 16
|
||||
Height = 89
|
||||
Top = 16
|
||||
Width = 136
|
||||
AutoFill = True
|
||||
Caption = 'Digits'
|
||||
ChildSizing.LeftRightSpacing = 6
|
||||
ChildSizing.VerticalSpacing = 6
|
||||
ChildSizing.EnlargeHorizontal = crsScaleChilds
|
||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 3
|
||||
ClientHeight = 69
|
||||
ClientWidth = 132
|
||||
Columns = 3
|
||||
Items.Strings = (
|
||||
'1'
|
||||
'2'
|
||||
'3'
|
||||
'4'
|
||||
'5'
|
||||
'6'
|
||||
'7'
|
||||
'8'
|
||||
'9'
|
||||
)
|
||||
ParentBiDiMode = False
|
||||
TabOrder = 0
|
||||
Data = {
|
||||
09000000020202020202020202
|
||||
}
|
||||
end
|
||||
object btnOK: TButton
|
||||
AnchorSideLeft.Control = DigitCG
|
||||
AnchorSideRight.Control = DigitCG
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 16
|
||||
Height = 25
|
||||
Top = 112
|
||||
Width = 136
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
Caption = '&Ok'
|
||||
Default = True
|
||||
ModalResult = 1
|
||||
TabOrder = 1
|
||||
end
|
||||
end
|
95
applications/sudoku/digitseteditor.pas
Normal file
95
applications/sudoku/digitseteditor.pas
Normal file
@ -0,0 +1,95 @@
|
||||
unit DigitSetEditor;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
|
||||
SudokuType;
|
||||
|
||||
type
|
||||
|
||||
{ TDigitSetEditorForm }
|
||||
|
||||
TDigitSetEditorForm = class(TForm)
|
||||
btnOK: TButton;
|
||||
DigitCG: TCheckGroup;
|
||||
procedure FormActivate(Sender: TObject);
|
||||
procedure FormKeyPress(Sender: TObject; var Key: char);
|
||||
procedure FormShow(Sender: TObject);
|
||||
private
|
||||
FPreferredRight: Integer;
|
||||
function GetDigitSet: TDigitSet;
|
||||
procedure SetDigitSet(ASet: TDigitSet);
|
||||
procedure SetRight({%H-}Data: PtrInt);
|
||||
|
||||
public
|
||||
property DigitSet: TDigitSet read GetDigitSet write SetDigitSet;
|
||||
property PreferredRight: Integer read FPreferredRight write FPreferredRight;
|
||||
end;
|
||||
|
||||
var
|
||||
DigitSetEditorForm: TDigitSetEditorForm;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
{ TDigitSetEditorForm }
|
||||
|
||||
procedure TDigitSetEditorForm.FormKeyPress(Sender: TObject; var Key: char);
|
||||
var
|
||||
Digit: Integer;
|
||||
begin
|
||||
if (Key in ['1'..'9']) then
|
||||
begin
|
||||
Digit := Ord(Key) - Ord('0');
|
||||
DigitCG.Checked[Pred(Digit)] := not DigitCG.Checked[Pred(Digit)];
|
||||
Key := #0;
|
||||
end;
|
||||
if (Key = #27) then //escape
|
||||
begin
|
||||
Key := #0;
|
||||
ModalResult := mrCancel;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDigitSetEditorForm.FormShow(Sender: TObject);
|
||||
begin
|
||||
Application.QueueAsyncCall(@SetRight, FPreferredRight)
|
||||
end;
|
||||
|
||||
procedure TDigitSetEditorForm.FormActivate(Sender: TObject);
|
||||
begin
|
||||
OnACtivate := nil;
|
||||
ClientWidth := 2 * DigitCG.Left + DigitCG.Width;
|
||||
ClientHeight := btnOK.Top + btnOK.Height + DigitCG.Top;
|
||||
end;
|
||||
|
||||
function TDigitSetEditorForm.GetDigitSet: TDigitSet;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := [];
|
||||
for i := 0 to DigitCG.Items.Count - 1 do
|
||||
if DigitCG.Checked[i] then Include(Result, Succ(i));
|
||||
end;
|
||||
|
||||
procedure TDigitSetEditorForm.SetDigitSet(ASet: TDigitSet);
|
||||
var
|
||||
D: TDigits;
|
||||
begin
|
||||
for D in TDigits do
|
||||
begin
|
||||
DigitCG.Checked[D-1] := (D in ASet); //don't use Pred(D) here, gives RangeCheckError when D=1
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDigitSetEditorForm.SetRight(Data: PtrInt);
|
||||
begin
|
||||
Left := FPreferredRight - Width;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -22,6 +22,8 @@ object ScratchForm: TScratchForm
|
||||
RowCount = 9
|
||||
ScrollBars = ssNone
|
||||
TabOrder = 0
|
||||
OnClick = ScratchGridClick
|
||||
OnPrepareCanvas = ScratchGridPrepareCanvas
|
||||
end
|
||||
object btnCopy: TButton
|
||||
AnchorSideLeft.Control = ScratchGrid
|
||||
|
@ -6,7 +6,8 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, StdCtrls,
|
||||
SudokuType;
|
||||
Math,
|
||||
SudokuType, DigitSetEditor;
|
||||
|
||||
type
|
||||
|
||||
@ -20,12 +21,16 @@ type
|
||||
procedure btnCopyClick(Sender: TObject);
|
||||
procedure FormActivate(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure ScratchGridClick(Sender: TObject);
|
||||
procedure ScratchGridPrepareCanvas(sender: TObject; aCol, aRow: Integer;
|
||||
{%H-}aState: TGridDrawState);
|
||||
private
|
||||
FRawData: TRawGrid;
|
||||
FOnCopyValues: TCopyValuesEvent;
|
||||
procedure SetRawData(Data: TRawGrid);
|
||||
procedure GridToValues(out Values: TValues);
|
||||
procedure KeepInView;
|
||||
procedure EditCell(ACol, ARow: Integer);
|
||||
public
|
||||
property RawData: TRawGrid write SetRawData;
|
||||
property OnCopyValues: TCopyValuesEvent read FOnCopyValues write FOnCopyValues;
|
||||
@ -38,6 +43,51 @@ implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
function DigitSetToStr(ASet: TDigitSet): String;
|
||||
function Get(D: Integer): Char;
|
||||
begin
|
||||
if (D in ASet) then
|
||||
Result := Char(Ord('0') + D)
|
||||
else
|
||||
Result := 'x';//#32;
|
||||
end;
|
||||
begin
|
||||
Result := Format('%s-%s-%s'+LineEnding+'%s-%s-%s'+LineEnding+'%s-%s-%s',[Get(1),Get(2),Get(3),Get(4),Get(5),Get(6),Get(7),Get(8),Get(9)]);
|
||||
end;
|
||||
|
||||
function StrToDigitSet(const S: String): TDigitSet;
|
||||
var
|
||||
Ch: Char;
|
||||
begin
|
||||
Result := [];
|
||||
for Ch in S do
|
||||
if (Ch in ['1'..'9']) then
|
||||
Include(Result, Ord(Ch) - Ord('0'));
|
||||
end;
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
function TryCellTextToDigit(const AText: String; out Value: TDigits): Boolean;
|
||||
var
|
||||
Ch: Char;
|
||||
S: String;
|
||||
begin
|
||||
Result := False;
|
||||
S := '';
|
||||
for Ch in AText do
|
||||
if (Ch in ['1'..'9']) then S := S + Ch;
|
||||
if (Length(S) = 1) then
|
||||
begin
|
||||
Ch := S[1];
|
||||
if (Ch in ['1'..'9']) then
|
||||
begin
|
||||
Value := Ord(Ch) - Ord('0');
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TScratchForm }
|
||||
|
||||
procedure TScratchForm.FormActivate(Sender: TObject);
|
||||
@ -45,8 +95,14 @@ begin
|
||||
Self.OnActivate := nil;
|
||||
ScratchGrid.ClientWidth := 9 * ScratchGrid.DefaultColWidth;
|
||||
ScratchGrid.ClientHeight := 9 * ScratchGrid.DefaultRowHeight;
|
||||
//writeln(format('ScratchGrid: %d x %d',[ScratchGrid.ClientWidth,ScratchGrid.ClientHeight]));
|
||||
ClientWidth := 2 * ScratchGrid.Left + ScratchGrid.Width;
|
||||
ClientHeight := btnCopy.Top + btnCopy.Height + 10;
|
||||
//writeln(format('btnCopy.Top: %d, btnCopy.Height: %d',[btnCopy.Top,btnCopy.Height]));
|
||||
Self.ReAlign;
|
||||
//ClientHeight := btnCopy.Top + btnCopy.Height + 10;
|
||||
//Above doesn't work: at this time btnCopy.Top still holds designtime value, even when it's top is anchored to the grid
|
||||
ClientHeight := ScratchGrid.Top + ScratchGrid.Height + 10 + btnCopy.Height + 10;
|
||||
//writeln(format('ClientHeight: %d',[ClientHeight]));
|
||||
KeepInView;
|
||||
end;
|
||||
|
||||
@ -61,8 +117,54 @@ begin
|
||||
end;
|
||||
|
||||
procedure TScratchForm.FormCreate(Sender: TObject);
|
||||
var
|
||||
DefWH: Integer;
|
||||
begin
|
||||
ScratchGrid.DefaultColWidth := ScratchGrid.Canvas.TextWidth(' [1,2,3,4,5,6,7,8,9] ') + 8;
|
||||
DefWH := Max(ScratchGrid.Canvas.TextWidth(' 8-8-8 '), 3 * ScratchGrid.Canvas.TextHeight('8')) + 10;
|
||||
ScratchGrid.DefaultColWidth := DefWH;
|
||||
ScratchGrid.DefaultRowHeight := DefWH;
|
||||
end;
|
||||
|
||||
procedure TScratchForm.ScratchGridClick(Sender: TObject);
|
||||
var
|
||||
Col, Row: Integer;
|
||||
begin
|
||||
Col := ScratchGrid.Col;
|
||||
Row := ScratchGrid.Row;
|
||||
if not FRawData[Col+1,Row+1].Locked then
|
||||
EditCell(Col, Row);
|
||||
end;
|
||||
|
||||
procedure TScratchForm.ScratchGridPrepareCanvas(sender: TObject; aCol, aRow: Integer; aState: TGridDrawState);
|
||||
var
|
||||
NeedsColor: Boolean;
|
||||
GridTextStyle: TTextStyle;
|
||||
begin
|
||||
GridTextStyle := (Sender as TStringGrid).Canvas.TextStyle;
|
||||
GridTextStyle.Alignment := taCenter;
|
||||
GridTextStyle.Layout := tlCenter;
|
||||
GridTextStyle.SingleLine := False;
|
||||
(Sender as TStringGrid).Canvas.TextStyle := GridTextStyle;
|
||||
NeedsColor := False;
|
||||
if aCol in [0..2, 6..8] then
|
||||
begin
|
||||
if aRow in [0..2, 6..8] then
|
||||
NeedsColor := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if aRow in [3..5] then
|
||||
NeedsColor := True;
|
||||
end;
|
||||
if NeedsColor then
|
||||
(Sender as TStringGrid).Canvas.Brush.Color := $00EEEEEE;
|
||||
//if (aRow=0) and (aCol=0) then
|
||||
if FRawData[aCol+1, aRow+1].Locked then
|
||||
begin
|
||||
(Sender as TStringGrid).Canvas.Brush.Color := $00F8E3CB; // $00F1CEA3;
|
||||
(Sender as TStringGrid).Canvas.Font.Color := clRed;
|
||||
(Sender as TStringGrid).Canvas.Font.Style := [fsBold]
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TScratchForm.SetRawData(Data: TRawGrid);
|
||||
@ -79,7 +181,8 @@ begin
|
||||
if Data[Col,Row].Locked then
|
||||
S := IntToStr(Data[Col,Row].Value)
|
||||
else
|
||||
S := DbgS(Data[Col,Row].DigitsPossible);
|
||||
//S := DbgS(Data[Col,Row].DigitsPossible);
|
||||
S := DigitSetToStr(Data[Col,Row].DigitsPossible);
|
||||
ScratchGrid.Cells[Col-1,Row-1] := S;
|
||||
end;
|
||||
end;
|
||||
@ -88,7 +191,7 @@ end;
|
||||
procedure TScratchForm.GridToValues(out Values: TValues);
|
||||
var
|
||||
Col, Row: Integer;
|
||||
AValue: Longint;
|
||||
AValue: TDigits;
|
||||
S: String;
|
||||
begin
|
||||
Values := Default(TValues);
|
||||
@ -97,9 +200,10 @@ begin
|
||||
for Row := 0 to 8 do
|
||||
begin
|
||||
S := ScratchGrid.Cells[Col, Row];
|
||||
//DigitSet := StrToDigitSet(S);
|
||||
if Length(S) >= 1 then
|
||||
begin
|
||||
if TryStrToInt(S, AValue) then
|
||||
if TryCellTextToDigit(S, AValue) then
|
||||
Values[Col + 1, Row + 1] := AValue;
|
||||
end;
|
||||
end;
|
||||
@ -119,5 +223,22 @@ begin
|
||||
Left := FL;
|
||||
end;
|
||||
|
||||
procedure TScratchForm.EditCell(ACol, ARow: Integer);
|
||||
var
|
||||
S: String;
|
||||
DigitSet: TDigitSet;
|
||||
begin
|
||||
S := ScratchGrid.Cells[ACol, ARow];
|
||||
DigitSet := StrToDigitSet(S);
|
||||
DigitSetEditorForm.DigitSet := DigitSet;
|
||||
DigitSetEditorForm.Top := Top;
|
||||
DigitSetEditorForm.PreferredRight := Left;
|
||||
if (DigitSetEditorForm.ShowModal = mrOK) then
|
||||
begin
|
||||
S := DigitSetToStr(DigitSetEditorForm.DigitSet);
|
||||
ScratchGrid.Cells[ACol, ARow] := S;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -15,11 +15,6 @@
|
||||
<Item2 Name="Debug">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<UseAnsiStrings Value="False"/>
|
||||
</SyntaxOptions>
|
||||
</Parsing>
|
||||
<CodeGeneration>
|
||||
<Checks>
|
||||
<IOChecks Value="True"/>
|
||||
@ -60,7 +55,7 @@
|
||||
<PackageName Value="LCL"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="4">
|
||||
<Units Count="5">
|
||||
<Unit0>
|
||||
<Filename Value="sudoku.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
@ -71,6 +66,7 @@
|
||||
<ComponentName Value="Form1"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="SudokuMain"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="sudokutype.pas"/>
|
||||
@ -85,6 +81,13 @@
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="ScratchPad"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="digitseteditor.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="DigitSetEditorForm"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="DigitSetEditor"/>
|
||||
</Unit4>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@ -27,12 +27,13 @@ program sudoku;
|
||||
uses
|
||||
Interfaces, // this includes the LCL widgetset
|
||||
Forms
|
||||
{ add your units here }, sudokumain, scratchpad;
|
||||
{ add your units here }, sudokumain, scratchpad, digitseteditor;
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TForm1, Form1);
|
||||
Application.CreateForm(TScratchForm, ScratchForm);
|
||||
Application.CreateForm(TDigitSetEditorForm, DigitSetEditorForm);
|
||||
Application.Run;
|
||||
end.
|
||||
|
||||
|
@ -23,7 +23,7 @@ object Form1: TForm1
|
||||
DefaultRowHeight = 30
|
||||
FixedCols = 0
|
||||
FixedRows = 0
|
||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goEditing, goSmoothScroll]
|
||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goEditing, goSmoothScroll]
|
||||
RowCount = 9
|
||||
ScrollBars = ssNone
|
||||
TabOrder = 2
|
||||
|
@ -1,4 +1,4 @@
|
||||
unit sudokumain;
|
||||
unit SudokuMain;
|
||||
|
||||
{
|
||||
***************************************************************************
|
||||
@ -267,8 +267,8 @@ procedure TForm1.ShowScratchPad(RawData: TRawGrid);
|
||||
begin
|
||||
ScratchForm.OnCopyValues := @OnCopyBackValues;
|
||||
ScratchForm.RawData := RawData;
|
||||
ScratchForm.ScratchGrid.Options := SGrid.Options + [goEditing];
|
||||
ScratchForm.ScratchGrid.OnPrepareCanvas := @Self.SGridPrepareCanvas;
|
||||
ScratchForm.ScratchGrid.Options := SGrid.Options - [goEditing];
|
||||
ScratchForm.Left := Left + Width + 10;
|
||||
ScratchForm.Show;
|
||||
end;
|
||||
|
||||
|
Reference in New Issue
Block a user