RVCtrlData.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:11k
源码类别:

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       TCustomRVFormattedData is an ancestor class     }
  5. {       representing RichView document linked with      }
  6. {       RichView control. It's an ancestor of           }
  7. {       TRichViewRVData.                                }
  8. {                                                       }
  9. {       Copyright (c) Sergey Tkachenko                  }
  10. {       svt@trichview.com                               }
  11. {       http://www.trichview.com                        }
  12. {                                                       }
  13. {*******************************************************}
  14. unit RVCtrlData;
  15. interface
  16. {$I RV_Defs.inc}
  17. uses SysUtils, Windows, Classes, Graphics, Controls, Forms,
  18.      CRVData, CRVFData,
  19.      RVStyle, RVScroll,
  20.      RVItem;
  21. type                                    
  22.   TRVControlData = class (TCustomRVFormattedData)
  23.     public
  24.       TopLevelFocusedItemNo: Integer;
  25.       TopLevelFocusedRVData: TCustomRVFormattedData;
  26.       TabNavigation: TRVTabNavigationType;
  27.       procedure ClearTemporal; override;
  28.       procedure DoTabNavigation(Shift: Boolean; PrevCtrl: TWinControl);
  29.       procedure PaintBuffered;
  30.       procedure DrawFocusedRect(Canvas: TCanvas);
  31.       procedure Deselect(NewPartiallySelected: TCustomRVItemInfo; MakeEvent: Boolean); override;
  32.       procedure ExecuteFocused;
  33.       procedure AdjustFocus(NewFocusedItemNo: Integer; TopLevelRVData: TPersistent; TopLevelItemNo: Integer); override;
  34.       procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);override;
  35.       constructor Create;
  36.   end;
  37. implementation
  38. {=============================== TRVControlData ===============================}
  39. constructor TRVControlData.Create;
  40. begin
  41.   inherited Create;
  42.   TabNavigation := rvtnTab;
  43.   TopLevelFocusedItemNo := -1;
  44. end;
  45. {------------------------------------------------------------------------------}
  46. procedure TRVControlData.AdjustFocus(NewFocusedItemNo: Integer;
  47.   TopLevelRVData: TPersistent; TopLevelItemNo: Integer);
  48. begin
  49.   if (TopLevelFocusedRVData<>nil) and (TopLevelFocusedItemNo>=0) and
  50.      (TopLevelFocusedItemNo<TopLevelFocusedRVData.ItemCount) then
  51.     TopLevelFocusedRVData.GetItem(TopLevelFocusedItemNo).ClearFocus;
  52.   inherited AdjustFocus(NewFocusedItemNo, TopLevelRVData, TopLevelItemNo);
  53.   TopLevelFocusedItemNo := TopLevelItemNo;
  54.   TopLevelFocusedRVData := TCustomRVFormattedData(TopLevelRVData);
  55. end;
  56. {------------------------------------------------------------------------------}
  57. function FindNextControl(ParentControl, CurControl: TWinControl;
  58.                          GoForward: Boolean): TWinControl;
  59. var
  60.   i, StartIdx: Integer;
  61.   OldCurControl: TWinControl;
  62.   TabList: TList;
  63.   {....................................................}
  64.   function HasAsParent(CurControl: TWinControl): Boolean;
  65.   begin
  66.      while CurControl<>nil do begin
  67.        if CurControl=OldCurControl then begin
  68.          Result := True;
  69.          exit;
  70.        end;
  71.        CurControl := CurControl.Parent;
  72.      end;
  73.      Result := False;
  74.   end;
  75.   {....................................................}
  76. begin
  77.   OldCurControl := CurControl;
  78.   Result := nil;
  79.   TabList := TList.Create;
  80.   try
  81.     ParentControl.GetTabOrderList(TabList);
  82.     if TabList.Count > 0 then begin
  83.       StartIdx := TabList.IndexOf(CurControl);
  84.       if StartIdx = -1 then
  85.         if GoForward then
  86.           StartIdx := TabList.Count-1
  87.         else
  88.           StartIdx := 0;
  89.       i := StartIdx;
  90.       repeat
  91.         if GoForward then begin
  92.           inc(i);
  93.           if i = TabList.Count then
  94.             i := 0;
  95.           end
  96.         else begin
  97.           if i = 0 then
  98.             i := TabList.Count;
  99.           dec(i);
  100.         end;
  101.         CurControl := TabList[i];
  102.         if not HasAsParent(CurControl) and
  103.            CurControl.CanFocus and CurControl.TabStop then begin
  104.           Result := CurControl;
  105.           break;
  106.         end;
  107.       until i = StartIdx;
  108.     end;
  109.   finally
  110.     TabList.Free;
  111.   end;
  112. end;
  113. {------------------------------------------------------------------------------}
  114. procedure TRVControlData.ClearTemporal;
  115. begin
  116.   if DrawItems<>nil then begin
  117.     //ClearFocus;
  118.     TopLevelFocusedItemNo := -1;
  119.     TopLevelFocusedRVData := nil;
  120.   end;
  121.   inherited ClearTemporal;
  122. end;
  123. {------------------------------------------------------------------------------}
  124. procedure TRVControlData.Deselect(NewPartiallySelected: TCustomRVItemInfo;
  125.                                   MakeEvent: Boolean);
  126. begin
  127.   if rvstDeselecting in State then
  128.     exit;
  129.   State := State + [rvstDeselecting];
  130.   try
  131.     ClearFocus;
  132.     if TopLevelFocusedItemNo<>-1 then
  133.       Invalidate;
  134.     TopLevelFocusedItemNo := -1;
  135.     TopLevelFocusedRVData := nil;
  136.   finally
  137.     State := State - [rvstDeselecting];
  138.   end;
  139.   inherited Deselect(NewPartiallySelected, MakeEvent);
  140. end;
  141. {------------------------------------------------------------------------------}
  142. procedure TRVControlData.DoTabNavigation(Shift: Boolean;
  143.   PrevCtrl: TWinControl);
  144. var ItemNo: Integer;
  145.     Next: TWinControl;
  146.     TopLevelItem, item: TCustomRVItemInfo;
  147.     OldFocusedItemNo: Integer;
  148. begin
  149.   if rvstDoNotTab in State then begin
  150.     Exclude(State,rvstDoNotTab);
  151.     exit;
  152.   end;
  153.   if PrevCtrl<>nil then
  154.     try
  155.       if GetParentForm(PrevCtrl)<>GetParentForm(GetParentControl) then
  156.         exit;
  157.     except
  158.       PrevCtrl := nil;
  159.     end;
  160.   if (FocusedItemNo<>-1) and (PrevCtrl=nil) then
  161.     exit;
  162.   OldFocusedItemNo := FocusedItemNo;
  163.   if PrevCtrl<>nil then begin
  164.     // May be focus was moved to another control inside RichView?
  165.     if (FocusedItemNo=-1) or
  166.        not TCustomRVItemInfo(Items.Objects[FocusedItemNo]).OwnsControl(PrevCtrl) then
  167.       ItemNo := FindControlItemNo(PrevCtrl)
  168.     else
  169.       ItemNo := FocusedItemNo;
  170.     if ItemNo<>-1 then begin
  171.       DrawFocusedRect(GetCanvas);
  172.       if TopLevelFocusedRVData<>nil then
  173.         TopLevelFocusedRVData.ClearFocus;
  174.       FocusedItemNo := ItemNo;
  175.       item := TCustomRVItemInfo(Items.Objects[ItemNo]);
  176.       item.AdjustFocusToControl(PrevCtrl, TPersistent(TopLevelFocusedRVData),TopLevelFocusedItemNo);
  177.       if item.GetBoolValue(rvbpImmediateControlOwner) then begin
  178.         TopLevelFocusedItemNo := ItemNo;
  179.         TopLevelFocusedRVData := Self;
  180.       end;
  181.       DrawFocusedRect(GetCanvas);
  182.     end;
  183.   end;
  184.   // Moving focus to next/previous focusable item
  185.   DrawFocusedRect(GetCanvas);
  186.  if TopLevelFocusedRVData<>nil then
  187.    TopLevelFocusedRVData.ClearFocus;
  188.   ItemNo := GetNextFocusedItem(FocusedItemNo, not Shift,
  189.     TopLevelFocusedRVData, TopLevelFocusedItemNo);
  190.   if ItemNo=-1 then begin
  191.     TopLevelFocusedItemNo := -1;
  192.     TopLevelFocusedRVData := nil;
  193.   end;
  194.   if (PrevCtrl<>GetParentControl) and (ItemNo=-1) and (FocusedItemNo=-1) then begin
  195.     GetParentControl.SetFocus;
  196.     exit;
  197.   end;
  198.   FocusedItemNo := ItemNo;
  199.   if TopLevelFocusedItemNo<>-1 then begin
  200.     TopLevelItem := TCustomRVItemInfo(TopLevelFocusedRVData.Items.Objects[TopLevelFocusedItemNo]);
  201.     TopLevelItem.Focusing;
  202.     end
  203.   else
  204.     TopLevelItem := nil;
  205.   DrawFocusedRect(GetCanvas);
  206.   if TopLevelItem<>nil then
  207.     with TopLevelFocusedRVData.DrawItems[TopLevelItem.DrawItemNo] do
  208.       TopLevelFocusedRVData.ShowRectangle(Left,Top,Width,Height)
  209.   else begin
  210.     Next := GetParentForm(GetParentControl);
  211.     if Next=nil then
  212.       Next := GetParentControl.Parent;
  213.     Next := FindNextControl(Next, GetParentControl, (not Shift));
  214.     if Next<>nil then
  215.       Next.SetFocus
  216.     else if OldFocusedItemNo<>-1 then
  217.       DoTabNavigation(Shift, GetParentControl);
  218.   end;
  219. end;
  220. {------------------------------------------------------------------------------}
  221. procedure TRVControlData.DrawFocusedRect(Canvas: TCanvas);
  222. var i: Integer;
  223.     item: TCustomRVItemInfo;
  224.     x,y: Integer;
  225.     ax, ay: Integer;
  226. begin
  227.   if TopLevelFocusedItemNo<>-1 then begin
  228.     item := TopLevelFocusedRVData.GetItem(TopLevelFocusedItemNo);
  229.     if item.GetBoolValueEx(rvbpXORFocus, GetRVStyle) then begin
  230.       TopLevelFocusedRVData.GetOriginEx(x,y);
  231.       GetOriginEx(ax,ay);
  232.       Canvas.Font.Color := clBlack;
  233.       Canvas.Brush.Style := bsSolid;
  234.       for i := item.DrawItemNo to TopLevelFocusedRVData.DrawItems.Count-1 do begin
  235.         if TopLevelFocusedRVData.DrawItems[i].ItemNo<>TopLevelFocusedItemNo then break;
  236.         with TopLevelFocusedRVData.DrawItems[i] do
  237.           Canvas.DrawFocusRect(Bounds(x+Left-GetHOffs-1-ax,y+Top-GetVOffs-1-ay,Width+2,Height+2));
  238.       end;
  239.     end;
  240.   end;
  241. end;
  242. {------------------------------------------------------------------------------}
  243. procedure TRVControlData.ExecuteFocused;
  244. begin
  245.   if TopLevelFocusedRVData<>nil then
  246.     TCustomRVItemInfo(TopLevelFocusedRVData.Items.Objects[TopLevelFocusedItemNo]).Execute(Self);
  247. end;
  248. {------------------------------------------------------------------------------}
  249. procedure TRVControlData.PaintBuffered;
  250. var r,r2: TRect;
  251.     OldPalette: HPALETTE;
  252.     MemBitmap, OldBitmap: HBITMAP;
  253.     MemDC: HDC;
  254.     BufferCanvas: TCanvas;
  255.     errmsg: String;
  256.     error: Boolean;
  257.     Canvas: TCanvas;
  258. begin
  259.   Canvas := GetCanvas;
  260.   r := Canvas.ClipRect;
  261.   DrawFocusedRect(Canvas);
  262.   {$IFNDEF RVDONOTUSEDRAGDROP}
  263.   DrawDragDropCaret(Canvas, False);
  264.   {$ENDIF}
  265.   with r do
  266.     MemBitmap := CreateCompatibleBitmap(Canvas.Handle, Right-Left, Bottom-Top);
  267.   MemDC := CreateCompatibleDC(0);
  268.   OldBitmap := SelectObject(MemDC, MemBitmap);
  269.   if GetRVPalette<>0 then begin
  270.     OldPalette := SelectPalette(MemDC, GetRVPalette, False);
  271.     RealizePalette(MemDC);
  272.     end
  273.   else
  274.     OldPalette := 0;
  275.   BufferCanvas := TCanvas.Create;
  276.   BufferCanvas.Handle := MemDC;
  277.   DrawBackground(BufferCanvas, r);
  278.   ApplyZoom(BufferCanvas);
  279.   r2 := r;
  280.   ZoomRectDown(r2);
  281.   error := False;
  282.   errmsg := '';
  283.   try
  284.     PaintTo(BufferCanvas, r2);
  285.   except
  286.     on E: Exception do begin
  287.       error := True;
  288.       errmsg := E.Message;
  289.     end;
  290.   end;
  291.   RestoreZoom(BufferCanvas);
  292.   with r do
  293.     BitBlt(Canvas.Handle, Left, Top, Right-Left, Bottom-Top, MemDC, 0, 0, SRCCOPY);
  294.   if GetRVPalette<>0 then
  295.     SelectPalette(MemDC, OldPalette, True);
  296.   SelectObject(MemDC, OldBitmap);
  297.   BufferCanvas.Handle := 0;
  298.   BufferCanvas.Free;
  299.   DeleteDC(MemDC);
  300.   DeleteObject(MemBitmap);
  301.   if error then begin
  302.     with Canvas.Font do begin
  303.       Name := 'Arial';
  304.       Size := 10;
  305.       Color := clRed;
  306.       Style := [];
  307.     end;
  308.     Canvas.Brush.Color := clWhite;
  309.     Canvas.TextOut(0,0,'Error:'+errmsg);
  310.   end;
  311.   {$IFNDEF RVDONOTUSEDRAGDROP}
  312.   DrawDragDropCaret(Canvas, False);
  313.   {$ENDIF}
  314.   DrawFocusedRect(Canvas);
  315. end;
  316. {------------------------------------------------------------------------------}
  317. procedure TRVControlData.MouseUp(Button: TMouseButton; Shift: TShiftState;
  318.   X, Y: Integer);
  319. begin
  320.   DrawFocusedRect(GetCanvas);
  321.   inherited MouseUp(Button, Shift, X, Y);
  322.   DrawFocusedRect(GetCanvas);
  323. end;
  324. end.