Browse Source

Compiler Target and Compiler Optimization Target Processor lists are scrollable

Margers 10 months ago
parent
commit
0396174bbf
3 changed files with 260 additions and 14 deletions
  1. 22 6
      packages/ide/fpmcomp.inc
  2. 46 8
      packages/ide/fpmopts.inc
  3. 192 0
      packages/ide/wviews.pas

+ 22 - 6
packages/ide/fpmcomp.inc

@@ -14,27 +14,43 @@
  **********************************************************************}
 
 procedure TIDEApp.Target;
-var R,R2: TRect;
+var R,R2,R3: TRect;
     D: PCenterDialog;
-    RB: PRadioButtons;
-    TargetCount,I: integer;
+    RB: PScrollerRadioButtons;
+    VScrollBar : PScrollBar;
+    TargetCount,TargetHeight,I: Sw_Integer;
     LastItem: PSItem;
     L: longint;
 begin
   TargetCount:=TargetSwitches^.ItemCount;
-  R.Assign(0,0,60,4+TargetCount);
+  TargetHeight:=TargetCount;
+  GetExtent(R);
+  if (R.B.Y-R.A.Y) < (TargetHeight+9) then TargetHeight:= (R.B.Y-R.A.Y)-9;
+  if TargetHeight<3 then TargetHeight:=3;
+  R.Assign(0,0,60,4+TargetHeight);
   New(D, Init(R, dialog_target));
   with D^ do
   begin
     HelpCtx:=hcTarget;
     GetExtent(R); R.Grow(-3,-1); Inc(R.A.Y);
-    R2.Copy(R); Inc(R2.A.Y); R2.B.Y:=R2.A.Y+TargetCount;
+    R2.Copy(R); Inc(R2.A.Y); R2.B.Y:=R2.A.Y+TargetHeight;
+    {have scroll bar for Targets only if they does not fit in view}
+    VScrollBar :=nil;
+    if TargetHeight<>TargetCount then
+    begin
+      Dec(R2.B.X);
+      R3.Copy(R2);R3.A.X:=R3.B.X; R3.B.X:=R3.B.X+1;
+      R3.B.Y:=R3.B.Y-3; {-3 because of InsertButtons later}
+      VScrollBar := New(PScrollBar, Init(R3));
+      Insert(VScrollBar);
+    end;
     LastItem:=nil;
     for I:=TargetCount-1 downto 0 do
       LastItem:=NewSItem(TargetSwitches^.ItemName(I), LastItem);
-    New(RB, Init(R2, LastItem));
+    New(RB, Init(R2, LastItem, VScrollBar));
     L:=ord(TargetSwitches^.GetCurrSel);
     RB^.SetData(L);
+    RB^.CentreSelected;
     Insert(RB);
     R2.Copy(R);
     R2.B.Y:=R2.A.Y+1;

+ 46 - 8
packages/ide/fpmopts.inc

@@ -63,7 +63,9 @@ procedure TIDEApp.DoCompilerSwitch;
 var R,R2,R3,TabR,TabIR: TRect;
     D: PCenterDialog;
     CB1,CB2,CB3,CB4,CB5: PCheckBoxes;
-    RB1,RB1b,RB2,RB4,RB5,RB6: PRadioButtons;
+    RB1,RB1b: PScrollerRadioButtons;
+    RB2,RB4,RB5,RB6: PRadioButtons;
+    VScrollBar1,VScrollBar2 : PScrollBar;
     Items: PSItem;
     IL: PEditorInputLine;
     IL2: PEditorInputLine;
@@ -74,8 +76,21 @@ var R,R2,R3,TabR,TabIR: TRect;
     Label21,Label22,Label23,Label23b,
     Label31,Label41,
     Label51,Label52,Label53: PLabel;
+    TargetHeight,ProcessorHeight: sw_integer;
 begin
-  R.Assign(0,0,76,31);
+  {decide height of dialog view}
+  GetExtent(R);
+  Count:=ProcessorOptimizationSwitches^.ItemCount;
+  Count:=max(Count,ProcessorCodeGenerationSwitches^.ItemCount); {lines we need to be able to show}
+  if Count < 10 then Count:=10; {10 lines are needed in Assembler page}
+  TargetHeight:=Count+11; {11 lines for rest (empty lines, borders, pages, conditions...)}
+  if TargetHeight> 31 then TargetHeight:=31; {don't go wild, limit ourselvs on 31 line}
+  if (R.B.Y-R.A.Y) < (TargetHeight+5) then
+    TargetHeight:= (R.B.Y-R.A.Y)-5; {screen allow exactly this much lines}
+  if TargetHeight<21 then
+    TargetHeight:=21; {at last 21 for our view}
+  {actual height will be TargetHeight + 2 border lines + 3 lines for Ok buttons (min 26 lines)}
+  R.Assign(0,0,76,TargetHeight);
   New(D, Init(R, dialog_compilerswitches));
   with D^ do
   begin
@@ -158,33 +173,54 @@ begin
 
     { --- Sheet 3 --- }
     Count:=ProcessorOptimizationSwitches^.ItemCount;
+    ProcessorHeight:=Count;
+    if (ProcessorHeight+11 > TargetHeight) then
+      ProcessorHeight:=ProcessorHeight-((ProcessorHeight+11) -TargetHeight);
     R.Copy(TabIR);
     R2.Copy(R);
     R2.B.X:=R2.A.X+(R2.B.X-R2.A.X) div 2;
     Dec(R2.B.X,4);
-    R2.B.Y:=R2.A.Y+Count;
+    R2.B.Y:=R2.A.Y+ProcessorHeight;
+    VScrollBar1:=nil;
+    if ProcessorHeight<>Count then
+    begin
+      R3.Copy(R2);R3.A.X:=R3.B.X; R3.B.X:=R3.B.X+1;
+      VScrollBar1:=New(PScrollBar, Init(R3));
+    end;
     Items:=nil;
     for I:=Count-1 downto 0 do
       Items:=NewSItem(ProcessorOptimizationSwitches^.ItemName(I), Items);
-    New(RB1, Init(R2, Items));
+    New(RB1, Init(R2, Items, VScrollBar1));
     L:=ProcessorOptimizationSwitches^.GetCurrSel;
     RB1^.SetData(L);
+    RB1^.CentreSelected;
     Dec(R2.A.Y);
     R2.B.Y:=R2.A.Y+1;
     New(Label23, Init(R2, label_compiler_opt_targetprocessor, RB1));
 
     Count:=ProcessorCodeGenerationSwitches^.ItemCount;
+    ProcessorHeight:=Count;
+    if (ProcessorHeight+11 > TargetHeight) then
+      ProcessorHeight:=ProcessorHeight-((ProcessorHeight+11) -TargetHeight);
     R.Copy(TabIR);
     R2.Copy(R);
     R2.A.X:=R2.A.X+(R2.B.X-R2.A.X) div 2;
-    R2.B.X:=R2.B.X-3;
-    R2.B.Y:=R2.A.Y+Count;
+    R2.B.X:=R2.B.X-4;
+    R2.B.Y:=R2.A.Y+ProcessorHeight;
+    VScrollBar2:=nil;
+    if ProcessorHeight<>Count then
+    begin
+      Dec(R2.B.X);
+      R3.Copy(R2);R3.A.X:=R3.B.X; R3.B.X:=R3.B.X+1;
+      VScrollBar2:=New(PScrollBar, Init(R3));
+    end;
     Items:=nil;
     for I:=Count-1 downto 0 do
       Items:=NewSItem(ProcessorCodeGenerationSwitches^.ItemName(I), Items);
-    New(RB1b, Init(R2, Items));
+    New(RB1b, Init(R2, Items, VScrollBar2));
     L:=ProcessorCodeGenerationSwitches^.GetCurrSel;
     RB1b^.SetData(L);
+    RB1b^.CentreSelected;
     Dec(R2.A.Y);
     R2.B.Y:=R2.A.Y+1;
     New(Label23b, Init(R2, label_compiler_codegen_targetprocessor, RB1b));
@@ -287,10 +323,12 @@ begin
         nil)))),
       NewTabDef('~P~rocessor',RB1,
         NewTabItem(Label23,
+        NewTabItem(VScrollBar1,
         NewTabItem(RB1,
         NewTabItem(Label23b,
+        NewTabItem(VScrollBar2,
         NewTabItem(RB1b,
-        nil)))),
+        nil)))))),
       NewTabDef(page_compiler_verbose,CB4,
         NewTabItem(Label31,
         NewTabItem(CB4,

+ 192 - 0
packages/ide/wviews.pas

@@ -197,6 +197,22 @@ type
       function GetPalette: PPalette; virtual;
     end;
 
+    PScrollerRadioButtons = ^TScrollerRadioButtons;
+    TScrollerRadioButtons = object (TRadioButtons)
+      VScrollBar  : PScrollBar;
+      Delta : TPoint;
+      constructor Init (Var Bounds: TRect; AStrings: PSItem; aVScrollBar:PScrollBar);
+      procedure HandleEvent (Var Event: TEvent); Virtual;
+      procedure MovedTo (Item: Sw_Integer); Virtual;
+      procedure ScrollDraw; Virtual;
+      procedure Draw; Virtual;
+      procedure DrawScrollMultiBox (Const Icon, Marker: String);
+      procedure ScrollTo (X,Y: Sw_Integer); Virtual;
+      procedure CentreSelected;
+      private
+      function FindSel (P: TPoint): Sw_Integer;
+   end;
+
     PPanel = ^TPanel;
     TPanel = object(TGroup)
       constructor Init(var Bounds: TRect);
@@ -2309,6 +2325,182 @@ begin
   GetPalette:=@P;
 end;
 
+constructor TScrollerRadioButtons.Init (Var Bounds: TRect; AStrings: PSItem; aVScrollBar:PScrollBar);
+var Y : sw_word;
+begin
+  inherited init (Bounds, AStrings);
+  VScrollBar:=aVScrollBar;
+  EventMask := evMouseDown + evKeyDown + evCommand + evBroadcast;
+  Y:=Strings.count;
+  if (VScrollBar<> nil) and (Y>=size.Y) and (Size.Y>0) then
+    VScrollBar^.SetParams(0, 0,Y-Size.Y, Size.Y-1, VScrollBar^.ArStep);       { Set vert scrollbar }
+end;
+
+procedure TScrollerRadioButtons.HandleEvent (Var Event: TEvent);
+VAR I: Sw_Integer; Mouse: TPoint;
+   LinesScroll : sw_integer;
+begin
+   If ((Options AND ofSelectable) <> 0) Then
+   begin
+     If (Event.What = evMouseDown) Then Begin             { MOUSE EVENT }
+      if (Event.Buttons=mbScrollUp) then                  { mouse scroll up}
+         begin
+           LinesScroll:=1;
+           if Event.Double then LinesScroll:=LinesScroll+4;
+           ScrollTo(Delta.X, Delta.Y + LinesScroll);
+           ClearEvent(Event);                             { Event was handled }
+         end else
+       if (Event.Buttons=mbScrollDown) then               { mouse scroll down }
+         begin
+           LinesScroll:=-1;
+           if Event.Double then LinesScroll:=LinesScroll-4;
+           ScrollTo(Delta.X, Delta.Y + LinesScroll);
+           ClearEvent(Event);                             { Event was handled }
+         end else
+       if (VScrollBar<>nil) then begin       { mouse click if we have scrollbar}
+         MakeLocal(Event.Where, Mouse);                   { Make point local }
+         I := FindSel(Mouse);                             { Find selected item }
+         If (I <> -1) Then                                { Check in view }
+           If ButtonState(I) Then Sel := I;               { If enabled select }
+         DrawView;                                        { Now draw changes }
+         Repeat
+           MakeLocal(Event.Where, Mouse);                 { Make point local }
+         Until NOT MouseEvent(Event, evMouseMove);        { Wait for mouse up }
+         MakeLocal(Event.Where, Mouse);                   { Make point local }
+         If (FindSel(Mouse) = Sel) AND ButtonState(Sel)   { If valid/selected }
+         Then Begin
+           Press(Sel);                                    { Call pressed }
+           DrawView;                                      { Now draw changes }
+         End;
+         ClearEvent(Event);                               { Event was handled }
+       end;
+     end;
+   end;
+
+   Inherited HandleEvent(Event);                      { Call ancestor }
+
+   If (Event.What = evBroadcast) AND
+     (Event.Command = cmScrollBarChanged) AND         { Scroll bar change }
+     ({(Event.InfoPtr = HScrollBar) OR}               { Our scrollbar? }
+      (Event.InfoPtr = VScrollBar)) Then
+   begin
+     ScrollDraw;
+     ClearEvent(Event);
+  end;
+end;
+
+procedure TScrollerRadioButtons.ScrollTo (X,Y: Sw_Integer);
+begin
+  if X>Size.X then X:=Size.X-1;
+  if X<0 then X:=0;
+  if (Y>(Strings.Count-Size.Y)) then Y:=(Strings.Count-Size.Y);
+  if Y<0 then Y:=0;
+  if Delta.Y<>Y then
+  begin
+    Delta.Y:=Y;
+    if (VScrollBar<>nil) then if VScrollBar^.Value<>Delta.Y then VScrollBar^.SetValue(Delta.Y);
+    DrawView;
+  end;
+end;
+
+function TScrollerRadioButtons.FindSel (P: TPoint): Sw_Integer;
+var I, S, Vh: Sw_Integer; R: TRect;
+begin
+   GetExtent(R);                                      { Get view extents }
+   If R.Contains(P) Then Begin                        { Point in view }
+     Vh := Size.Y;                            { View height }
+     I := 0;                                          { Preset zero value }
+     {While (P.X >= Column(I+Vh)) Do Inc(I, Vh);}       { Inc view size }
+     S := I + P.Y+ Delta.Y;                                { Line to select }
+     If ((S >= 0) AND (S < Strings.Count))            { Valid selection }
+       Then FindSel := S Else FindSel := -1;          { Return selected item }
+   End Else FindSel := -1;                            { Point outside view }
+end;
+
+procedure TScrollerRadioButtons.MovedTo (Item: Sw_Integer);
+begin
+  if (Item<Delta.Y) then begin Delta.Y:=Item; end;
+  if (Item>=(Size.Y+Delta.Y)) then begin Delta.Y:=Item-Size.Y+1; end;
+  if (VScrollBar<>nil) then if VScrollBar^.Value<>Delta.Y then VScrollBar^.SetValue(Delta.Y);
+  inherited MovedTo(Item);
+end;
+
+procedure TScrollerRadioButtons.ScrollDraw;
+begin
+  if (VScrollBar<> nil) then Delta.Y:=VScrollBar^.Value;
+  Drawview;
+end;
+
+procedure TScrollerRadioButtons.CentreSelected;
+var Y : Sw_Integer;
+begin
+  if (VScrollBar<> nil) then
+  begin
+    Y:=Sel-(Size.Y div 2);
+    if Y<0 then Y:=0;
+    if (Size.Y+Y) >= Strings.Count then Y:=Strings.Count-Size.Y;
+    if Y<0 then Y:=0;
+    if Delta.Y<>Y then
+    begin
+      Delta.Y:=Y;
+      VScrollBar^.SetValue(Y);
+      DrawView;
+    end;
+  end;
+end;
+
+procedure TScrollerRadioButtons.Draw;
+begin
+  if VScrollBar=nil then begin inherited draw; exit; end;
+  if Size.Y >= Strings.Count then begin inherited draw; exit; end;
+  DrawScrollMultiBox(' ( ) ',' *');
+end;
+
+procedure TScrollerRadioButtons.DrawScrollMultiBox (Const Icon, Marker: String);
+VAR I, J, Cur, Col: Sw_Integer;
+    CNorm, CSel, CDis, Color: Word; B: TDrawBuffer;
+begin
+   CNorm := GetColor($0301);                          { Normal colour }
+   CSel := GetColor($0402);                           { Selected colour }
+   CDis := GetColor($0505);                           { Disabled colour }
+   For I := 0 To Size.Y-1 Do Begin                { For each line }
+     MoveChar(B, ' ', Byte(CNorm), Size.X);       { Fill buffer }
+     {For J := 0 To (Strings.Count - 1) DIV Size.Y + 1
+     Do}
+     J:=0;
+     Begin
+       Cur := {J*Size.Y} Delta.Y + I;                { Current line }
+       If (Cur < Strings.Count) Then Begin
+         Col := {Column(Cur)}1;                          { Calc column }
+         If (Col + CStrLen(PString(Strings.At(Cur))^)+
+         5 < Sizeof(TDrawBuffer) DIV SizeOf(Word))
+         AND (Col < Size.X) Then Begin            { Text fits in column }
+           If NOT ButtonState(Cur) Then
+             Color := CDis Else If (Cur = Sel) AND    { Disabled colour }
+             (State and sfFocused <> 0) Then
+               Color := CSel Else                     { Selected colour }
+               Color := CNorm;                        { Normal colour }
+           MoveChar(B[Col], ' ', Byte(Color),
+             Size.X-Col);                         { Set this colour }
+           MoveStr(B[Col], Icon, Byte(Color));        { Transfer icon string }
+           WordRec(B[Col+2]).Lo := Byte(Marker[
+             MultiMark(Cur) + 1]);                    { Transfer marker }
+           MoveCStr(B[Col+5], PString(Strings.At(
+             Cur))^, Color);                          { Transfer item string }
+           If ShowMarkers AND (State AND sfFocused <> 0)
+           AND (Cur = Sel) Then Begin                 { Current is selected }
+             WordRec(B[Col]).Lo := Byte(SpecialChars[0]);
+              WordRec(B[{Column(Cur+Size.Y)}1-1]).Lo
+                := Byte(SpecialChars[1]);             { Set special character }
+           End;
+         End;
+       End;
+     End;
+     WriteBuf(0, I, Size.X, 1, B);              { Write buffer }
+   End;
+  SetCursor({Column(Sel)}1+2,{Row(Sel)}Sel-Delta.Y);
+end;
+
 constructor TAdvancedListBox.Load(var S: TStream);
 begin
   inherited Load(S);