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

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       Label Item - item class for RichView.           }
  5. {       Non-text item that looks like a text            }
  6. {       (but cannot be wrapped and edited)              }
  7. {       Does not support Unicode.                       }
  8. {                                                       }
  9. {       Copyright (c) Sergey Tkachenko                  }
  10. {       svt@trichview.com                               }
  11. {       http://www.trichview.com                        }
  12. {                                                       }
  13. {*******************************************************}
  14. unit LabelItem;
  15. {$I RV_Defs.inc}
  16. interface
  17. uses SysUtils, Classes, Windows, Graphics, RVFuncs, Controls,
  18.      RVScroll, CRVData, RVStyle, RVItem, RVFMisc, DLines, CRVFData, RichView,
  19.      RVClasses;
  20. const
  21.   rvsLabel = -200;
  22. type
  23.   TRVLabelItemInfo = class(TRVRectItemInfo)
  24.     private
  25.       Width, Height, Descend: Integer;
  26.       FMinWidth: Integer;
  27.       FAlignment: TAlignment;
  28.       FCanUseCustomPPI: Boolean;
  29.       procedure SetMinWidth(const Value: Integer);
  30.       procedure SetAlignment(const Value: TAlignment);
  31.     protected
  32.       procedure DoPaint(r: TRect; Canvas: TCanvas; State: TRVItemDrawStates;
  33.         Style: TRVStyle; dli: TRVDrawLineInfo; ColorMode: TRVColorMode); virtual;
  34.       function GetDescent: Integer; override;
  35.       function GetHeight: Integer; override;
  36.       function GetWidth: Integer;  override;
  37.       function GetAssociatedTextStyleNo: Integer; override;
  38.       procedure SetAssociatedTextStyleNo(Value: Integer); override;      
  39.     public
  40.       Text: String;
  41.       RVStyle: TRVStyle;
  42.       TextStyleNo: Integer;
  43.       ProtectTextStyleNo: Boolean;
  44.       Cursor: TCursor;
  45.       constructor Create(RVData: TPersistent); override;
  46.       constructor CreateEx(RVData: TPersistent; TextStyleNo: Integer; const Text: String);
  47.       function MouseMove(Shift: TShiftState; X, Y, ItemNo: Integer;
  48.         RVData: TObject): Boolean; override;
  49.       function GetMinWidth(sad: PRVScreenAndDevice; Canvas: TCanvas; RVData: TPersistent): Integer; override;
  50.       function GetBoolValue(Prop: TRVItemBoolProperty): Boolean; override;
  51.       function GetBoolValueEx(Prop: TRVItemBoolPropertyEx; RVStyle: TRVStyle): Boolean; override;
  52.       procedure Paint(x,y: Integer; Canvas: TCanvas; State: TRVItemDrawStates;
  53.         Style: TRVStyle; dli: TRVDrawLineInfo); override;
  54.       procedure Print(Canvas: TCanvas; x,y,x2: Integer; Preview, Correction: Boolean;
  55.         const sad: TRVScreenAndDevice; RichView: TRVScroller; dli: TRVDrawLineInfo;
  56.         Part: Integer; ColorMode: TRVColorMode; RVData: TPersistent); override;
  57.       procedure AfterLoading(FileFormat: TRVLoadFormat); override;
  58.       procedure SaveRVF(Stream: TStream; RVData: TPersistent; ItemNo, ParaNo: Integer;
  59.                         const Name: String; Part: TRVMultiDrawItemPart;
  60.                         ForceSameAsPrev: Boolean); override;
  61.       function ReadRVFLine(const s: String; RVData: TPersistent;
  62.                            ReadType, LineNo, LineCount: Integer;
  63.                            var Name: String;
  64.                            var ReadMode: TRVFReadMode;
  65.                            var ReadState: TRVFReadState): Boolean; override;
  66.       procedure Assign(Source: TCustomRVItemInfo); override;
  67.       procedure MarkStylesInUse(Data: TRVDeleteUnusedStylesData); override;
  68.       procedure UpdateStyles(Data: TRVDeleteUnusedStylesData); override;
  69.       procedure ApplyStyleConversion(RVData: TPersistent;
  70.         ItemNo, UserData: Integer); override;
  71.       procedure UpdateMe;
  72.       procedure OnDocWidthChange(DocWidth: Integer; dli: TRVDrawLineInfo; Printing: Boolean; Canvas: TCanvas;
  73.         RVData: TPersistent; sad: PRVScreenAndDevice; var HShift, Desc: Integer;
  74.         NoCaching, Reformatting: Boolean); override;
  75.       procedure Execute(RVData:TPersistent);override;
  76.       {$IFNDEF RVDONOTUSERTF}
  77.       procedure SaveRTF(Stream: TStream; const Path: String;
  78.         RVData: TPersistent; ItemNo: Integer;
  79.         const Name: String; TwipsPerPixel: Double; Level: Integer;
  80.         ColorList: TRVColorList;
  81.         StyleToFont, ListOverrideOffsetsList1, ListOverrideOffsetsList2: TRVIntegerList;
  82.         FontTable: TRVList); override;
  83.       {$ENDIF}
  84.       {$IFNDEF RVDONOTUSEHTML}
  85.       procedure SaveToHTML(Stream: TStream; RVData: TPersistent;
  86.         ItemNo: Integer; const Text, Path: String;
  87.         const imgSavePrefix: String; var imgSaveNo: Integer;
  88.         CurrentFileColor: TColor; SaveOptions: TRVSaveOptions;
  89.         UseCSS: Boolean; Bullets: TRVList); override;
  90.       {$ENDIF}
  91.       function AsText(LineWidth: Integer;
  92.         RVData: TPersistent; const Text, Path: String;
  93.         TextOnly,Unicode: Boolean): String; override;
  94.       procedure Inserted(RVData: TObject; ItemNo: Integer); override;
  95.       property MinWidth: Integer read FMinWidth write SetMinWidth;
  96.       property Alignment: TAlignment read FAlignment write SetAlignment;
  97.   end;
  98. implementation
  99. {==============================================================================}
  100. { TRVLabelItemInfo }
  101. constructor TRVLabelItemInfo.CreateEx(RVData: TPersistent;
  102.   TextStyleNo: Integer; const Text: String);
  103. begin
  104.    inherited Create(RVData);
  105.    StyleNo := rvsLabel;
  106.    VAlign := rvvaBaseLine;
  107.    Self.TextStyleNo := TextStyleNo;
  108.    Self.Text    := Text;
  109.    RVStyle := TCustomRVData(RVData).GetRVStyle;
  110.    FCanUseCustomPPI := rvflCanUseCustomPPI in TCustomRVData(RVData).Flags;
  111.    Cursor := crDefault;
  112.    UpdateMe;
  113. end;
  114. {------------------------------------------------------------------------------}
  115. constructor TRVLabelItemInfo.Create(RVData: TPersistent);
  116. begin
  117.   inherited Create(RVData);
  118.   StyleNo := rvsLabel;
  119.   RVStyle := TCustomRVData(RVData).GetRVStyle;
  120.   FCanUseCustomPPI := rvflCanUseCustomPPI in TCustomRVData(RVData).Flags;
  121.   Cursor := crDefault;
  122. end;
  123. {------------------------------------------------------------------------------}
  124. procedure TRVLabelItemInfo.AfterLoading(FileFormat: TRVLoadFormat);
  125. begin
  126.   inherited;
  127.   UpdateMe;
  128. end;
  129. {------------------------------------------------------------------------------}
  130. procedure TRVLabelItemInfo.UpdateMe;
  131. var DC: HDC;
  132.     Canvas: TCanvas;
  133.     TextMetric: TTextMetric;
  134. begin
  135.    if RVStyle=nil then
  136.      exit;
  137.    DC := GetDC(0);
  138.    Canvas := TCanvas.Create;
  139.    Canvas.Handle := DC;
  140.    RVStyle.ApplyStyle(Canvas, TextStyleNo, rvbdUnspecified, FCanUseCustomPPI);
  141.    FillChar(TextMetric, sizeof(TextMetric), 0);
  142.    GetTextMetrics(Canvas.Handle, TextMetric);
  143.    Descend := TextMetric.tmDescent;
  144.    Height  := TextMetric.tmHeight;
  145.    Width := Canvas.TextWidth(Text);
  146.    if Width<MinWidth then
  147.      Width := MinWidth;
  148.    Canvas.Handle := 0;
  149.    Canvas.Free;
  150.    ReleaseDC(0,DC);
  151. end;
  152. {------------------------------------------------------------------------------}
  153. procedure TRVLabelItemInfo.Assign(Source: TCustomRVItemInfo);
  154. begin
  155.   if Source is TRVLabelItemInfo then begin
  156.     StyleNo := TRVLabelItemInfo(Source).StyleNo;
  157.     TextStyleNo := TRVLabelItemInfo(Source).TextStyleNo;
  158.     Text    := TRVLabelItemInfo(Source).Text;
  159.     ProtectTextStyleNo := TRVLabelItemInfo(Source).ProtectTextStyleNo;
  160.     MinWidth := TRVLabelItemInfo(Source).MinWidth;
  161.     Alignment := TRVLabelItemInfo(Source).Alignment;
  162.     Cursor := TRVLabelItemInfo(Source).Cursor;
  163.   end;
  164.   inherited;
  165. end;
  166. {------------------------------------------------------------------------------}
  167. procedure TRVLabelItemInfo.DoPaint(r: TRect; Canvas: TCanvas;
  168.   State: TRVItemDrawStates; Style: TRVStyle; dli: TRVDrawLineInfo;
  169.   ColorMode: TRVColorMode);
  170. var TextDrawState: TRVTextDrawStates;
  171.     DTOption: Integer;
  172. begin
  173.   TextDrawState := [];
  174.   if rvidsSelected in State then
  175.     include(TextDrawState, rvtsSelected);
  176.   if rvidsControlFocused in State then
  177.     include(TextDrawState, rvtsControlFocused);
  178.   if rvidsHover in State then
  179.     include(TextDrawState, rvtsHover);
  180.   RVStyle.ApplyStyle(Canvas, TextStyleNo, rvbdUnspecified, rvidsCanUseCustomPPI in State);
  181.   RVStyle.ApplyStyleColor(Canvas,TextStyleNo,TextDrawState, False, ColorMode);
  182.   case Alignment of
  183.     taRightJustify:
  184.       DTOption := DT_RIGHT;
  185.     taCenter:
  186.       DTOption := DT_CENTER;
  187.     else
  188.       DTOption := DT_LEFT;
  189.   end;
  190.   if Canvas.Brush.Style<>bsClear then
  191.     Canvas.FillRect(r);
  192.   DrawText(Canvas.Handle, PChar(Text), Length(Text), r, DT_SINGLELINE or DT_NOCLIP or DTOption);
  193.   Canvas.Brush.Style := bsClear;
  194. end;
  195. {------------------------------------------------------------------------------}
  196. procedure TRVLabelItemInfo.Paint(x, y: Integer; Canvas: TCanvas;
  197.   State: TRVItemDrawStates; Style: TRVStyle; dli: TRVDrawLineInfo);
  198. begin
  199.   DoPaint(Bounds(x, y, Width, Height), Canvas, State, Style, dli, rvcmColor);
  200. end;
  201. {------------------------------------------------------------------------------}
  202. procedure TRVLabelItemInfo.Print(Canvas: TCanvas; x, y, x2: Integer;
  203.   Preview, Correction: Boolean; const sad: TRVScreenAndDevice;
  204.   RichView: TRVScroller; dli: TRVDrawLineInfo; Part: Integer;
  205.   ColorMode: TRVColorMode; RVData: TPersistent);
  206. var r: TRect;
  207.    DrawStates: TRVItemDrawStates;
  208. begin
  209.   r := Rect(x, y, Width, Height);
  210.   r.Right  := RV_XToDevice(r.Right,  sad);
  211.   r.Bottom := RV_YToDevice(r.Bottom, sad);
  212.   inc(r.Right,  x);
  213.   inc(r.Bottom, y);
  214.   DrawStates := [];
  215.   if rvflCanUseCustomPPI in TCustomRVData(RVData).Flags then
  216.     Include(DrawStates, rvidsCanUseCustomPPI);
  217.   DoPaint(r, Canvas, DrawStates, TCustomRichView(RichView).Style, dli, ColorMode);
  218. end;
  219. {------------------------------------------------------------------------------}
  220. function TRVLabelItemInfo.GetBoolValueEx(Prop: TRVItemBoolPropertyEx;
  221.   RVStyle: TRVStyle): Boolean;
  222. begin
  223.   case Prop of
  224.     rvbpJump, rvbpAllowsFocus,rvbpXORFocus:
  225.       Result := RVStyle.TextStyles[TextStyleNo].Jump;
  226.     rvbpHotColdJump:
  227.       Result := RVStyle.TextStyles[TextStyleNo].Jump and
  228.                 RVStyle.StyleHoverSensitive(StyleNo);
  229.    rvbpPrintToBMP:
  230.      Result := False;
  231.    else
  232.      Result := inherited GetBoolValueEx(Prop, RVStyle);
  233.   end;
  234. end;
  235. {------------------------------------------------------------------------------}
  236. function TRVLabelItemInfo.GetBoolValue(Prop: TRVItemBoolProperty): Boolean;
  237. begin
  238.   case Prop of
  239.     rvbpAlwaysInText:
  240.       Result := True;
  241.     rvbpDrawingChangesFont:
  242.       Result := True;
  243.     rvbpSwitchToAssStyleNo:
  244.       Result := not ProtectTextStyleNo;
  245.     else
  246.       Result := inherited GetBoolValue(Prop);
  247.   end;
  248. end;
  249. {------------------------------------------------------------------------------}
  250. function TRVLabelItemInfo.GetDescent: Integer;
  251. begin
  252.   Result := Descend;
  253. end;
  254. {------------------------------------------------------------------------------}
  255. function TRVLabelItemInfo.GetHeight: Integer;
  256. begin
  257.   Result := Height;
  258. end;
  259. {------------------------------------------------------------------------------}
  260. function TRVLabelItemInfo.GetWidth: Integer;
  261. begin
  262.   Result := Width;
  263. end;
  264. {------------------------------------------------------------------------------}
  265. function TRVLabelItemInfo.GetMinWidth(sad: PRVScreenAndDevice; Canvas: TCanvas; RVData: TPersistent): Integer;
  266. begin
  267.   Result := Width;
  268.   if MinWidth>Result then
  269.     Result := MinWidth;
  270.   if Sad<>nil then
  271.     Result := MulDiv(Result, sad.ppixDevice, sad.ppixScreen);
  272. end;
  273. {------------------------------------------------------------------------------}
  274. procedure TRVLabelItemInfo.SaveRVF(Stream: TStream; RVData: TPersistent;
  275.   ItemNo, ParaNo: Integer; const Name: String; Part: TRVMultiDrawItemPart;
  276.   ForceSameAsPrev: Boolean);
  277. begin
  278.    // if you want to modify saving/loading, modify
  279.    // 1) second parameter in header - number of additional lines
  280.    // 2) lines after header
  281.    // Do not change other parameters in header
  282.    RVFWriteLine(Stream,
  283.      Format('%d %d %s %d %d %s %s',
  284.             [StyleNo, 6+GetRVFExtraPropertyCount {Line count after header},
  285.              RVFItemSavePara(ParaNo, TCustomRVData(RVData), ForceSameAsPrev),
  286.              Byte(RVFGetItemOptions(ItemOptions, ForceSameAsPrev)) and RVItemOptionsMask,
  287.              0 {text mode saving},
  288.              RVFSaveTag(rvoTagsArePChars in TCustomRVData(RVData).Options,Tag),
  289.              SaveRVFHeaderTail(RVData)]));
  290.    // lines after header
  291.    RVFWriteLine(Stream, Text);
  292.    RVFWriteLine(Stream, IntToStr(TextStyleNo));
  293.    RVFWriteLine(Stream, IntToStr(MinWidth));
  294.    RVFWriteLine(Stream, IntToStr(ord(Alignment)));
  295.    if ProtectTextStyleNo then
  296.      RVFWriteLine(Stream, 'protect')
  297.    else
  298.      RVFWriteLine(Stream, 'no-protect');
  299.    RVFWriteLine(Stream, Name);
  300.    SaveRVFExtraProperties(Stream);  
  301. end;
  302. {------------------------------------------------------------------------------}
  303. function TRVLabelItemInfo.ReadRVFLine(const s: String; RVData: TPersistent;
  304.   ReadType, LineNo, LineCount: Integer; var Name: String;
  305.   var ReadMode: TRVFReadMode; var ReadState: TRVFReadState): Boolean;
  306. begin
  307.   case LineNo of
  308.     0:
  309.       Text := s;
  310.     1:
  311.       begin
  312.         TextStyleNo := StrToInt(s);
  313.         RVStyle := TCustomRVData(RVData).GetRVStyle;
  314.       end;
  315.     2:
  316.       MinWidth := StrToInt(s);
  317.     3:
  318.       Alignment := TAlignment(StrToInt(s));
  319.     4:
  320.       ProtectTextStyleNo := s='protect';
  321.     5:
  322.       Name := s;
  323.     else
  324.       SetExtraPropertyFromRVFStr(s);
  325.   end;
  326.   Result := True;
  327. end;
  328. {------------------------------------------------------------------------------}
  329. procedure TRVLabelItemInfo.MarkStylesInUse(Data: TRVDeleteUnusedStylesData);
  330. begin
  331.   inherited MarkStylesInUse(Data);
  332.   Data.UsedTextStyles[TextStyleNo] := 1;
  333. end;
  334. {------------------------------------------------------------------------------}
  335. procedure TRVLabelItemInfo.UpdateStyles(Data: TRVDeleteUnusedStylesData);
  336. begin
  337.   inherited UpdateStyles(Data);
  338.   dec(TextStyleNo,Data.UsedTextStyles[TextStyleNo]-1);
  339. end;
  340. {------------------------------------------------------------------------------}
  341. procedure TRVLabelItemInfo.ApplyStyleConversion(RVData: TPersistent;
  342.   ItemNo, UserData: Integer);
  343. begin
  344.   if ProtectTextStyleNo then
  345.     exit;
  346.   TCustomRVFormattedData(RVData).DoCurrentTextStyleConversion(TextStyleNo, ParaNo,
  347.     ItemNo, UserData, False);
  348.   UpdateMe;
  349. end;
  350. {------------------------------------------------------------------------------}
  351. {$IFNDEF RVDONOTUSERTF}
  352. procedure TRVLabelItemInfo.SaveRTF(Stream: TStream; const Path: String;
  353.   RVData: TPersistent; ItemNo: Integer; const Name: String; TwipsPerPixel: Double;
  354.   Level: Integer; ColorList: TRVColorList; StyleToFont,
  355.   ListOverrideOffsetsList1, ListOverrideOffsetsList2: TRVIntegerList;
  356.   FontTable: TRVList);
  357. begin
  358.   RVFWrite(Stream, RVMakeRTFStr(Text, False, True));
  359. end;
  360. {$ENDIF}
  361. {------------------------------------------------------------------------------}
  362. {$IFNDEF RVDONOTUSEHTML}
  363. procedure TRVLabelItemInfo.SaveToHTML(Stream: TStream; RVData: TPersistent;
  364.   ItemNo: Integer; const Text, Path, imgSavePrefix: String;
  365.   var imgSaveNo: Integer; CurrentFileColor: TColor;
  366.   SaveOptions: TRVSaveOptions; UseCSS: Boolean; Bullets: TRVList);
  367. begin
  368.   RVFWrite(Stream, RV_MakeHTMLStr(Self.Text, False));
  369. end;
  370. {$ENDIF}
  371. {------------------------------------------------------------------------------}
  372. function TRVLabelItemInfo.AsText(LineWidth: Integer; RVData: TPersistent;
  373.   const Text, Path: String; TextOnly, Unicode: Boolean): String;
  374. begin
  375.   Result := Self.Text;
  376. end;
  377. {------------------------------------------------------------------------------}
  378. procedure TRVLabelItemInfo.Inserted(RVData: TObject; ItemNo: Integer);
  379. begin
  380.   if RVData<>nil then begin
  381.     RVStyle := TCustomRVData(RVData).GetRVStyle;
  382.     FCanUseCustomPPI := rvflCanUseCustomPPI in TCustomRVData(RVData).Flags;
  383.   end;
  384. end;
  385. {------------------------------------------------------------------------------}
  386. procedure TRVLabelItemInfo.Execute(RVData: TPersistent);
  387. begin
  388.   if RVData is TCustomRVFormattedData then begin
  389.     if GetBoolValueEx(rvbpJump, TCustomRVData(RVData).GetRVStyle) then
  390.       TCustomRVFormattedData(RVData).DoJump(JumpID+
  391.           TCustomRVFormattedData(RVData).FirstJumpNo)
  392.   end;
  393. end;
  394. {------------------------------------------------------------------------------}
  395. procedure TRVLabelItemInfo.SetMinWidth(const Value: Integer);
  396. begin
  397.   if FMinWidth<>Value then begin
  398.     FMinWidth := Value;
  399.     UpdateMe;
  400.   end;
  401. end;
  402. {------------------------------------------------------------------------------}
  403. procedure TRVLabelItemInfo.SetAlignment(const Value: TAlignment);
  404. begin
  405.   FAlignment := Value;
  406. end;
  407. {------------------------------------------------------------------------------}
  408. procedure TRVLabelItemInfo.OnDocWidthChange(DocWidth: Integer;
  409.   dli: TRVDrawLineInfo; Printing: Boolean; Canvas: TCanvas;
  410.   RVData: TPersistent; sad: PRVScreenAndDevice; var HShift, Desc: Integer;
  411.   NoCaching, Reformatting: Boolean);
  412. begin
  413.   inherited;
  414.   Desc := GetDescent;
  415. end;
  416. {------------------------------------------------------------------------------}
  417. function TRVLabelItemInfo.MouseMove(Shift: TShiftState; X, Y,
  418.   ItemNo: Integer; RVData: TObject): Boolean;
  419. begin
  420.   Result := inherited MouseMove(Shift, X, Y, ItemNo, RVData);
  421.   if Cursor<>crDefault then begin
  422.     TCustomRVFormattedData(RVData).SetCursor(Cursor);
  423.     Result := True;
  424.   end;
  425. end;
  426. {------------------------------------------------------------------------------}
  427. function TRVLabelItemInfo.GetAssociatedTextStyleNo: Integer;
  428. begin
  429.   Result := TextStyleNo;
  430. end;
  431. {------------------------------------------------------------------------------}
  432. procedure TRVLabelItemInfo.SetAssociatedTextStyleNo(Value: Integer);
  433. begin
  434.   TextStyleNo := Value;
  435. end;
  436. initialization
  437.   RegisterRichViewItemClass(rvsLabel, TRVLabelItemInfo);
  438. end.