Page 1 of 1

Posted: Wed Nov 29, 2006 12:15 am
by Pieter Zijlstra
Identifying the tab is not that difficult, the problem is that as soon as you change the alignment of the tab a part of the ruler becomes empty and a new tab will be added on the second MouseDown. To prevent the extra tab, Ruler.pas needs to be changed.

But first identifying the tab, this can be done in the OnRulerItemSelect of the ruler.

Some helper functions...

Code: Select all

function InRange(pos, min, max, tol: Integer): Boolean;
begin
  Result := True;
  if (min - pos) > tol then Result := False;
  if (pos - max) > tol then Result := False;
end;

function NearBy(pos, tar, tol: Integer): Boolean;
begin
  Result := InRange(pos, tar, tar, tol);
end;
In the OnRulerItemSelect search the current tab in the collection...

Code: Select all

type
  TForm1 = class(TForm)
  private
    FTabNr: Integer;
  // ...

procedure TForm1.rulHorizontalRulerItemSelect(Sender: TObject; X: Integer);
var
  I: Integer;
begin
  FTabNr := -1;
  for I := 0 to rulHorizontal.Tabs.Count - 1 do
    if NearBy(rulHorizontal.Tabs[I].Left, X, 4) then
      FTabNr := I;
end;
In the OnDoubleClick of the ruler...

Code: Select all

procedure TForm1.rulHorizontalDblClick(Sender: TObject);
begin
  if FTabNr >= 0 then
    if rulHorizontal.Tabs[FTabNr].Align = taLeftAlign then
      rulHorizontal.Tabs[FTabNr].Align := taRightAlign
    else
      rulHorizontal.Tabs[FTabNr].Align := taLeftAlign;
end;
The problem is that after the DblClick a second MouseDown is generated by TControl albeit with a shiftstate ssDouble, but TRuler does not check for this (yet). This requires the following change in the MouseDown... the line which checks for if Button = mbLeft should be ...

Code: Select all

// Ruler.pas 
procedure TCustomRuler.MouseDown(...);
// ...
  if (Button = mbLeft) and not (ssDouble in Shift) then
// ...
end;
HTH,
Pieter

Posted: Sat Dec 09, 2006 10:02 am
by j&b
Hello Pieter,

I want to change rulHorizontal.Tabs[FTabNr].Align= taLeftAlign to rulHorizontal.Tabs[FTabNr].Align:= taDecimalAlign

But something must be wrong.

I tried your code (look at 'Current Tab (TRVRuler)' in this forum), but now I can't compile my program,
because I get an error at 'for i := 0 to rulHorizontal.Tabs.Count - 1 do //<----'
('[Fehler] unit1.pas(7668): Undefinierter Bezeichner: 'rulHorizontal')

My 2. question.
What is correct ?

procedure TForm1.RVRuler1RulerItemSelect(Sender: TObject; X: Integer);
(this appears if I doubleClick 'OnRulerItemSelect' and not 'TForm1.rulHorizontal...')

or

procedure TForm1.rulHorizontalRuler1ItemSelect(Sender: TObject; X: Integer);
(I know that I can write this in the editfield of 'OnRulerItemSelect')

Jürgen







//----- TABstop ausrichten -----------------------------------------------------
(*
Ruler.pas ändern (wg. Ausrichtung ändern) //oK
procedure TCustomRuler.MouseDown(...);
// ...
  if (Button = mbLeft) and not (ssDouble in Shift) then
// ...
end;
*)

function TForm1.InRange(pos, min, max, tol: Integer): Boolean;
begin
Result := True;
if (min - pos) > tol then Result := False;
if (pos - max) > tol then Result := False;
end;

function TForm1.NearBy(pos, tar, tol: Integer): Boolean;
begin Result := InRange(pos, tar, tar, tol); end;

procedure TForm1.rulHorizontalRuler1ItemSelect(Sender: TObject; X: Integer);
//procedure TForm1.RVRuler1RulerItemSelect(Sender: TObject; X: Integer);
var i: Integer;
begin
FTabNr := -1;
for i := 0 to rulHorizontal.Tabs.Count - 1 do //<----------------------------------
if NearBy(rulHorizontal.Tabs.Left, X, 4) then FTabNr := I;
end;

procedure TForm1.rulHorizontalDblClick(Sender: TObject);
begin
if FTabNr >= 0 then
if rulHorizontal.Tabs[FTabNr].Align = taLeftAlign then rulHorizontal.Tabs[FTabNr].Align := taDecimalAlign //taRightAlign
else rulHorizontal.Tabs[FTabNr].Align := taLeftAlign;
end;

Posted: Sat Dec 09, 2006 12:20 pm
by j&b
I think I have found the right expression for rulHorizental: rvRuler1.
But something is wrong. After posting memo the decimalTab in rvRuler is changed back to a leftTab

procedure TForm1.RVRuler1DblClick(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if FTabNr >= 0 then
if rvRuler1.Tabs[FTabNr].Align = taLeftAlign then rvRuler1.Tabs[FTabNr].Align := taDecimalAlign //taRightAlign
else rvRuler1.Tabs[FTabNr].Align := taLeftAlign;
end;



I tried another way (this way I want to go):

I created 3 speedButtons with left-, decimal- and right.align

procedure TForm1.sbTabLeftClick(Sender: TObject);
begin sbTabLeft.tag:=1; end;
procedure TForm1.sbDezTabClick(Sender: TObject);
begin sbTabLeft.tag:=2; end;
procedure TForm1.sbTabRightClick(Sender: TObject);
begin sbTabLeft.tag:=3; end;


Now I click the 'decimal-speedButton' (sbTabLeft.tag changes from 1 to 2).
THEN I click into rvRuler (RVRuler1MouseDown) and i get a decimal-tabstop (oK)

procedure TForm1.RVRuler1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin //sbTabLeft -> SpeedButton
if FTabNr >= 0 then begin
if sbTabLeft.tag=1 then rvRuler1.Tabs[FTabNr].Align := taLeftAlign
else if sbTabLeft.tag=2 then rvRuler1.Tabs[FTabNr].Align := taDecimalAlign
else if sbTabLeft.tag=3 then rvRuler1.Tabs[FTabNr].Align := taRightAlign;
end;
end;

But after posting memo decimalTab in rvRuler changes back to a leftTab
If I don't post memo decimalTab works as a leftTab.




//Here are the whole code

//----- TABstop ausrichten -----------------------------------------------------
(*
Ruler.pas ändern (wg. Ausrichtung ändern)
procedure TCustomRuler.MouseDown(...);
// ...
  if (Button = mbLeft) and not (ssDouble in Shift) then
// ...
end;
*)

procedure TForm1.sbTabLeftClick(Sender: TObject);
begin sbTabLeft.tag:=1; end;
procedure TForm1.sbDezTabClick(Sender: TObject);
begin sbTabLeft.tag:=2; end;
procedure TForm1.sbTabRightClick(Sender: TObject);
begin sbTabLeft.tag:=3; end;

function TForm1.InRange(pos, min, max, tol: Integer): Boolean;
begin
Result := True;
if (min - pos) > tol then Result := False;
if (pos - max) > tol then Result := False;
end;

function TForm1.NearBy(pos, tar, tol: Integer): Boolean;
begin Result := InRange(pos, tar, tar, tol); end;

//procedure TForm1.rulHorizontalRuler1ItemSelect(Sender: TObject; X: Integer);
procedure TForm1.RVRuler1RulerItemSelect(Sender: TObject; X: Integer);
var i: Integer;
begin
FTabNr := -1;
//for i := 0 to rulHorizontal.Tabs.Count - 1 do //error
for i := 0 to rvRuler1.Tabs.Count - 1 do
if NearBy(rvRuler1.Tabs.Left, X, 4) then FTabNr := i;
end;

procedure TForm1.RVRuler1DblClick(Sender: TObject);
begin //sbTabLeft -> SpeedButton
if FTabNr >= 0 then
if rvRuler1.Tabs[FTabNr].Align = taLeftAlign then rvRuler1.Tabs[FTabNr].Align := taDecimalAlign
else rvRuler1.Tabs[FTabNr].Align := taLeftAlign;
end;

procedure TForm1.RVRuler1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin //sbTabLeft -> SpeedButton
if FTabNr >= 0 then begin
if sbTabLeft.tag=1 then rvRuler1.Tabs[FTabNr].Align := taLeftAlign
else if sbTabLeft.tag=2 then rvRuler1.Tabs[FTabNr].Align := taDecimalAlign
else if sbTabLeft.tag=3 then rvRuler1.Tabs[FTabNr].Align := taRightAlign;
end;
end;

Posted: Sat Dec 09, 2006 3:38 pm
by Pieter Zijlstra
Hello Jürgen,

The last time I checked, TRichView did not support decimal tabs (Sergey, correct me if I'm wrong).
What you can do is use a fixed number of decimals with a font having a fixed pitch and then use taRightAlign.

--
Pieter

Posted: Sat Dec 09, 2006 4:38 pm
by j&b
Thanks, Pieter.

Hello Sergey, what's with decimal tabs ?

Jürgen