1 unit SynColorAttribEditor;
2 
3 {$mode objfpc}{$H+}
4 
5 interface
6 
7 uses
8   Classes, Controls, sysutils, types, typinfo, math, FPCanvas,
9   // LCL
10   LCLProc, LCLType, LCLIntf, Forms, StdCtrls, ExtCtrls, Graphics, GraphUtil,
11   ColorBox, Dialogs, Menus, Spin,
12   // SynEdit
13   SynEditTypes, SynTextDrawer,
14   // IDE
15   EditorOptions, SourceMarks, LazarusIDEStrConsts, EnvironmentOpts;
16 
17 type
18 
19   { TSynColorAttrEditor }
20 
21   TSynColorAttrEditor = class(TFrame)
22     BackPriorLabel: TLabel;
23     BackPriorSpin: TSpinEdit;
24     BackGroundColorBox: TColorBox;
25     BackGroundLabel: TLabel;
26     ColumnPosBevel: TPanel;
27     ForePriorLabel: TLabel;
28     ForePriorSpin: TSpinEdit;
29     MarkupFoldStyleBox: TComboBox;
30     MarkupFoldAlphaSpin: TSpinEdit;
31     MarkupFoldAlphaLabel: TLabel;
32     MarkupFoldColorUseDefaultCheckBox: TCheckBox;
33     MarkupFoldColorBox: TColorBox;
34     FramePriorSpin: TSpinEdit;
35     FramePriorLabel: TLabel;
36     FrameStyleBox: TComboBox;
37     FrameEdgesBox: TComboBox;
38     FrameColorBox: TColorBox;
39     BackGroundUseDefaultCheckBox: TCheckBox;
40     FrameColorUseDefaultCheckBox: TCheckBox;
41     ForegroundColorBox: TColorBox;
42     ForeAlphaLabel: TLabel;
43     BackAlphaLabel: TLabel;
44     FrameAlphaLabel: TLabel;
45     pnlUnderline: TPanel;
46     pnlBold: TPanel;
47     pnlItalic: TPanel;
48     ForeAlphaSpin: TSpinEdit;
49     BackAlphaSpin: TSpinEdit;
50     FrameAlphaSpin: TSpinEdit;
51     TextBoldCheckBox: TCheckBox;
52     TextBoldRadioInvert: TRadioButton;
53     TextBoldRadioOff: TRadioButton;
54     TextBoldRadioOn: TRadioButton;
55     TextBoldRadioPanel: TPanel;
56     TextItalicCheckBox: TCheckBox;
57     TextItalicRadioInvert: TRadioButton;
58     TextItalicRadioOff: TRadioButton;
59     TextItalicRadioOn: TRadioButton;
60     TextItalicRadioPanel: TPanel;
61     TextUnderlineCheckBox: TCheckBox;
62     TextUnderlineRadioInvert: TRadioButton;
63     TextUnderlineRadioOff: TRadioButton;
64     TextUnderlineRadioOn: TRadioButton;
65     TextUnderlineRadioPanel: TPanel;
66     ForeGroundLabel: TLabel;
67     ForeGroundUseDefaultCheckBox: TCheckBox;
68     procedure ForeAlphaSpinChange(Sender: TObject);
69     procedure ForeAlphaSpinEnter(Sender: TObject);
70     procedure ForegroundColorBoxChange(Sender: TObject);
71     procedure ForegroundColorBoxGetColors(Sender: TCustomColorBox; Items: TStrings);
72     procedure ForePriorSpinChange(Sender: TObject);
73     procedure FrameEdgesBoxDrawItem(Control: TWinControl; Index: Integer; ARect: TRect;
74       {%H-}State: TOwnerDrawState);
75     procedure FrameStyleBoxDrawItem(Control: TWinControl; Index: Integer; ARect: TRect;
76       {%H-}State: TOwnerDrawState);
77     procedure GeneralCheckBoxOnChange(Sender: TObject);
78     procedure pnlElementAttributesResize(Sender: TObject);
79     procedure TextStyleRadioOnChange(Sender: TObject);
80   private
81     FCurHighlightElement: TColorSchemeAttribute;
82     FCurrentColorScheme: TColorSchemeLanguage;
83     FOnChanged: TNotifyEvent;
84     FShowPrior: Boolean;
85     UpdatingColor: Boolean;
86 
87     procedure SetCurHighlightElement(AValue: TColorSchemeAttribute);
88     procedure DoChanged;
89     procedure SetShowPrior(AValue: Boolean);
90   public
91     constructor Create(TheOwner: TComponent); override;
92     procedure Setup;
93     procedure UpdateAll;
94     procedure DoResized;
95     // CurrentColorScheme must be set before CurHighlightElement
96     property CurHighlightElement: TColorSchemeAttribute read FCurHighlightElement write SetCurHighlightElement;
97     property CurrentColorScheme: TColorSchemeLanguage read FCurrentColorScheme write FCurrentColorScheme;
98     property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
99     property ShowPrior: Boolean read FShowPrior write SetShowPrior;
100   end;
101 
102 implementation
103 
104 {$R *.lfm}
105 
DefaultToNonenull106 function DefaultToNone(AColor: TColor): TColor;
107 begin
108   if AColor = clDefault then
109     Result := clNone
110   else
111     Result := AColor;
112 end;
113 
NoneToDefaultnull114 function NoneToDefault(AColor: TColor): TColor;
115 begin
116   if AColor = clNone then
117     Result := clDefault
118   else
119     Result := AColor;
120 end;
121 
122 { TSynColorAttrEditor }
123 
124 procedure TSynColorAttrEditor.ForegroundColorBoxChange(Sender: TObject);
125 begin
126   if (FCurHighlightElement = nil) or UpdatingColor then
127     exit;
128   UpdatingColor := True;
129 
130   if Sender = ForegroundColorBox then
131   begin
132     FCurHighlightElement.Foreground := DefaultToNone(ForeGroundColorBox.Selected);
133     ForeGroundUseDefaultCheckBox.Checked := ForeGroundColorBox.Selected <> clDefault;
134   end;
135   if Sender = BackGroundColorBox then
136   begin
137     FCurHighlightElement.Background := DefaultToNone(BackGroundColorBox.Selected);
138     BackGroundUseDefaultCheckBox.Checked := BackGroundColorBox.Selected <> clDefault;
139   end;
140   if Sender = FrameColorBox then
141   begin
142     FCurHighlightElement.FrameColor := DefaultToNone(FrameColorBox.Selected);
143     FrameColorUseDefaultCheckBox.Checked := FrameColorBox.Selected <> clDefault;
144     FrameEdgesBox.Enabled := FrameColorBox.Selected <> clDefault;
145     FrameStyleBox.Enabled := FrameColorBox.Selected <> clDefault;
146   end;
147   if Sender = MarkupFoldColorBox then
148   begin
149     FCurHighlightElement.MarkupFoldLineColor := DefaultToNone(MarkupFoldColorBox.Selected);
150     MarkupFoldColorUseDefaultCheckBox.Checked := MarkupFoldColorBox.Selected <> clDefault;
151     MarkupFoldStyleBox.Enabled := MarkupFoldColorBox.Selected <> clDefault;
152   end;
153   if Sender = FrameEdgesBox then
154   begin
155     FCurHighlightElement.FrameEdges := TSynFrameEdges(FrameEdgesBox.ItemIndex);
156   end;
157   if Sender = FrameStyleBox then
158   begin
159     FCurHighlightElement.FrameStyle := TSynLineStyle(FrameStyleBox.ItemIndex);
160   end;
161   if Sender = MarkupFoldStyleBox then
162   begin
163     FCurHighlightElement.MarkupFoldLineStyle := TSynLineStyle(MarkupFoldStyleBox.ItemIndex);
164   end;
165 
166   UpdatingColor := False;
167   DoChanged;
168 end;
169 
170 procedure TSynColorAttrEditor.ForeAlphaSpinChange(Sender: TObject);
171 var
172   v: Integer;
173 begin
174   if UpdatingColor then
175     exit;
176 
177   UpdatingColor := True;
178   v := TSpinEdit(Sender).Value;
179   if (v = 256) and (Caption <> dlgEdOff) then TSpinEdit(Sender).Caption := dlgEdOff;
180   UpdatingColor := False;
181 
182   if (FCurHighlightElement = nil) then
183     exit;
184 
185   if v = 256 then v := 0;
186 
187   if Sender = ForeAlphaSpin then
188     FCurHighlightElement.ForeAlpha := v;
189   if Sender = BackAlphaSpin then
190     FCurHighlightElement.BackAlpha := v;
191   if Sender = FrameAlphaSpin then
192     FCurHighlightElement.FrameAlpha := v;
193   if Sender = MarkupFoldAlphaSpin then
194     FCurHighlightElement.MarkupFoldLineAlpha := v;
195 
196   DoChanged;
197 end;
198 
199 procedure TSynColorAttrEditor.ForeAlphaSpinEnter(Sender: TObject);
200 begin
201   UpdatingColor := True;
202   If TSpinEdit(Sender).Value = 256 then
203     TSpinEdit(Sender).Caption := '256';
204   UpdatingColor := False;
205 end;
206 
207 procedure TSynColorAttrEditor.ForegroundColorBoxGetColors(Sender: TCustomColorBox; Items: TStrings);
208 var
209   i: longint;
210 begin
211   i := Items.IndexOfObject(TObject(PtrInt(clDefault)));
212   if i >= 0 then begin
213     Items[i] := dlgColorNotModified;
214     Items.Move(i, 1);
215   end;
216 end;
217 
218 procedure TSynColorAttrEditor.ForePriorSpinChange(Sender: TObject);
219 var
220   v: Integer;
221 begin
222   if (FCurHighlightElement = nil) then
223     exit;
224 
225   v := TSpinEdit(Sender).Value;
226 
227   if Sender = ForePriorSpin then
228     FCurHighlightElement.ForePriority := v;
229   if Sender = BackPriorSpin then
230     FCurHighlightElement.BackPriority := v;
231   if Sender = FramePriorLabel then
232     FCurHighlightElement.FramePriority := v;
233 
234   DoChanged;
235 end;
236 
237 procedure TSynColorAttrEditor.FrameEdgesBoxDrawItem(Control: TWinControl; Index: Integer; ARect: TRect;
238   State: TOwnerDrawState);
239 var
240   r: TRect;
241   PCol: Integer;
242 begin
243   if Index  < 0 then exit;;
244 
245   r.top := ARect.top + 3;
246   r.bottom := ARect.bottom - 3;
247   r.left := ARect.left + 5;
248   r.right := ARect.Right - 5;
249 
250   with TCustomComboBox(Control).Canvas do
251   begin
252     FillRect(ARect);
253     Pen.Width := 1;
254     PCol := pen.Color;
255     Pen.Color := clGray;
256     Pen.Style := psDot;
257     Pen.EndCap := pecFlat;
258     Rectangle(r);
259     Pen.Width := 2;
260     pen.Color := PCol;
261     Pen.Style := psSolid;
262     case Index of
263       ord(sfeAround): Rectangle(r);
264       ord(sfeBottom): begin
265           MoveTo(r.Left, r.Bottom);
266           LineTo(r.Right-1, r.Bottom);
267         end;
268       ord(sfeLeft): begin
269           MoveTo(r.Left, r.Top);
270           LineTo(r.Left, r.Bottom-1);
271         end;
272     end;
273   end;
274 end;
275 
276 procedure TSynColorAttrEditor.DoResized;
277 var
278   S: TSpinEdit;
279 begin
280   S := FramePriorSpin;
281   if not S.Visible then
282     S := FrameAlphaSpin;
283   if Width > S.Left + S.Width + FrameStyleBox.Width + FrameEdgesBox.Width + 15 then
284   begin
285     FrameEdgesBox.AnchorSide[akTop].Control := S;
286     FrameEdgesBox.AnchorSide[akTop].Side := asrTop;
287     FrameEdgesBox.AnchorSide[akLeft].Control := S;
288     FrameEdgesBox.AnchorSide[akLeft].Side := asrBottom;
289     FrameEdgesBox.BorderSpacing.Top := 0;
290     FrameEdgesBox.BorderSpacing.Left := 6;
291   end
292   else begin
293     FrameEdgesBox.AnchorSide[akTop].Control := FrameColorBox;
294     FrameEdgesBox.AnchorSide[akTop].Side := asrBottom;
295     FrameEdgesBox.AnchorSide[akLeft].Control := FrameColorBox;
296     FrameEdgesBox.AnchorSide[akLeft].Side := asrTop;
297     FrameEdgesBox.BorderSpacing.Top := 3;
298     FrameEdgesBox.BorderSpacing.Left := 0;
299   end;
300 end;
301 
302 procedure TSynColorAttrEditor.FrameStyleBoxDrawItem(Control: TWinControl; Index: Integer; ARect: TRect;
303   State: TOwnerDrawState);
304 var
305   p: TPoint;
306 begin
307   if Index  < 0 then exit;;
308 
309   with TCustomComboBox(Control).Canvas do
310   begin
311     FillRect(ARect);
312     Pen.Width := 2;
313     pen.EndCap := pecFlat;
314     case Index of
315       0: Pen.Style := psSolid;
316       1: Pen.Style := psDash;
317       2: Pen.Style := psDot;
318       3: Pen.Style := psSolid;
319     end;
320     if Index = 3 then begin
321       MoveToEx(Handle, ARect.Left + 5, (ARect.Top + ARect.Bottom) div 2 - 2, @p);
322       WaveTo(Handle, ARect.Right - 5, (ARect.Top + ARect.Bottom) div 2 - 2, 4);
323     end else begin
324       MoveTo(ARect.Left + 5, (ARect.Top + ARect.Bottom) div 2);
325       LineTo(ARect.Right - 5, (ARect.Top + ARect.Bottom) div 2);
326     end;
327   end;
328 end;
329 
330 procedure TSynColorAttrEditor.GeneralCheckBoxOnChange(Sender: TObject);
331 var
332   TheColorBox: TColorBox;
333 begin
334   if FCurHighlightElement = nil then
335     exit;
336 
337   if UpdatingColor = False then begin
338     UpdatingColor := True;
339 
340     TheColorBox := nil;
341     if Sender = ForeGroundUseDefaultCheckBox then TheColorBox := ForegroundColorBox;
342     if Sender = BackGroundUseDefaultCheckBox then TheColorBox := BackGroundColorBox;
343     if Sender = FrameColorUseDefaultCheckBox then TheColorBox := FrameColorBox;
344     if Sender = MarkupFoldColorUseDefaultCheckBox then TheColorBox := MarkupFoldColorBox;
345     if Assigned(TheColorBox) then begin
346       if TCheckBox(Sender).Checked then begin
347         TheColorBox.Selected := TheColorBox.Tag;
348       end
349       else begin
350         TheColorBox.Tag := TheColorBox.Selected;
351         TheColorBox.Selected := clDefault;
352       end;
353 
354       if (Sender = ForeGroundUseDefaultCheckBox) and
355          (DefaultToNone(ForegroundColorBox.Selected) <> FCurHighlightElement.Foreground)
356       then begin
357         FCurHighlightElement.Foreground := DefaultToNone(ForegroundColorBox.Selected);
358         DoChanged;
359       end;
360       if (Sender = BackGroundUseDefaultCheckBox) and
361          (DefaultToNone(BackGroundColorBox.Selected) <> FCurHighlightElement.Background)
362       then begin
363         FCurHighlightElement.Background := DefaultToNone(BackGroundColorBox.Selected);
364         DoChanged;
365       end;
366       if (Sender = FrameColorUseDefaultCheckBox) and
367          (DefaultToNone(FrameColorBox.Selected) <> FCurHighlightElement.FrameColor)
368       then begin
369         FCurHighlightElement.FrameColor := DefaultToNone(FrameColorBox.Selected);
370         FrameEdgesBox.Enabled := TCheckBox(Sender).Checked;
371         FrameStyleBox.Enabled := TCheckBox(Sender).Checked;
372         DoChanged;
373       end;
374       if (Sender = MarkupFoldColorUseDefaultCheckBox) and
375          (DefaultToNone(MarkupFoldColorBox.Selected) <> FCurHighlightElement.MarkupFoldLineColor)
376       then begin
377         FCurHighlightElement.MarkupFoldLineColor := DefaultToNone(MarkupFoldColorBox.Selected);
378         MarkupFoldStyleBox.Enabled := MarkupFoldColorBox.Selected <> clDefault;
379       end;
380     end;
381 
382     UpdatingColor := False;
383   end;
384 
385   if Sender = TextBoldCheckBox then begin
386     if hafStyleMask in FCurHighlightElement.Features then
387       TextStyleRadioOnChange(Sender)
388     else
389     if TextBoldCheckBox.Checked xor (fsBold in FCurHighlightElement.Style) then
390     begin
391       if TextBoldCheckBox.Checked then
392         FCurHighlightElement.Style := FCurHighlightElement.Style + [fsBold]
393       else
394         FCurHighlightElement.Style := FCurHighlightElement.Style - [fsBold];
395       DoChanged;
396     end;
397   end;
398 
399   if Sender = TextItalicCheckBox then begin
400     if hafStyleMask in FCurHighlightElement.Features then
401       TextStyleRadioOnChange(Sender)
402     else
403     if TextItalicCheckBox.Checked xor (fsItalic in FCurHighlightElement.Style) then
404     begin
405       if TextItalicCheckBox.Checked then
406         FCurHighlightElement.Style := FCurHighlightElement.Style + [fsItalic]
407       else
408         FCurHighlightElement.Style := FCurHighlightElement.Style - [fsItalic];
409       DoChanged;
410     end;
411   end;
412 
413   if Sender = TextUnderlineCheckBox then begin
414     if hafStyleMask in FCurHighlightElement.Features then
415       TextStyleRadioOnChange(Sender)
416     else
417     if TextUnderlineCheckBox.Checked xor (fsUnderline in FCurHighlightElement.Style) then
418     begin
419       if TextUnderlineCheckBox.Checked then
420         FCurHighlightElement.Style := FCurHighlightElement.Style + [fsUnderline]
421       else
422         FCurHighlightElement.Style := FCurHighlightElement.Style - [fsUnderline];
423       DoChanged;
424     end;
425   end;
426 end;
427 
428 procedure TSynColorAttrEditor.pnlElementAttributesResize(Sender: TObject);
429 var
430   MinAnchor: TControl;
431   MinWidth: Integer;
432   S: TSpinEdit;
433 
434   procedure CheckControl(Other: TControl);
435   var w,h: Integer;
436   begin
437     if not Other.Visible then exit;
438     h:=0;
439     w:=0;
440     Other.GetPreferredSize(w,h);
441     if w <= MinWidth then exit;
442     MinAnchor := Other;
443     MinWidth := w;
444   end;
445 begin
446   MinWidth := -1;
447   MinAnchor := ForeGroundLabel;
448   CheckControl(ForeGroundLabel);
449   CheckControl(BackGroundLabel);
450   CheckControl(ForeGroundUseDefaultCheckBox);
451   CheckControl(BackGroundUseDefaultCheckBox);
452   CheckControl(FrameColorUseDefaultCheckBox);
453   CheckControl(MarkupFoldColorUseDefaultCheckBox);
454 
455   ColumnPosBevel.AnchorSide[akLeft].Control := MinAnchor;
456   Constraints.MinHeight := pnlItalic.Top + pnlItalic.Height;
457   S := BackPriorSpin;
458   if not S.Visible then
459     S := BackAlphaSpin;
460   Constraints.MinWidth := S.Left + S.Width;
461 end;
462 
463 procedure TSynColorAttrEditor.TextStyleRadioOnChange(Sender: TObject);
464   procedure CalcNewStyle(CheckBox: TCheckBox; RadioOn, RadioOff,
465                          RadioInvert: TRadioButton; fs : TFontStyle;
466                          Panel: TPanel);
467   begin
468     if CheckBox.Checked then
469     begin
470       Panel.Enabled := True;
471       if RadioInvert.Checked then
472       begin
473         FCurHighlightElement.Style     := FCurHighlightElement.Style + [fs];
474         FCurHighlightElement.StyleMask := FCurHighlightElement.StyleMask - [fs];
475       end
476       else
477       if RadioOn.Checked then
478       begin
479         FCurHighlightElement.Style     := FCurHighlightElement.Style + [fs];
480         FCurHighlightElement.StyleMask := FCurHighlightElement.StyleMask + [fs];
481       end
482       else
483       if RadioOff.Checked then
484       begin
485         FCurHighlightElement.Style     := FCurHighlightElement.Style - [fs];
486         FCurHighlightElement.StyleMask := FCurHighlightElement.StyleMask + [fs];
487       end
488     end
489     else
490     begin
491       Panel.Enabled := False;
492       FCurHighlightElement.Style     := FCurHighlightElement.Style - [fs];
493       FCurHighlightElement.StyleMask := FCurHighlightElement.StyleMask - [fs];
494     end;
495   end;
496 begin
497   if FCurHighlightElement = nil then
498     exit;
499   if UpdatingColor or not (hafStyleMask in FCurHighlightElement.Features) then
500     Exit;
501 
502   if (Sender = TextBoldCheckBox) or
503      (Sender = TextBoldRadioOn) or
504      (Sender = TextBoldRadioOff) or
505      (Sender = TextBoldRadioInvert) then
506     CalcNewStyle(TextBoldCheckBox, TextBoldRadioOn, TextBoldRadioOff,
507                     TextBoldRadioInvert, fsBold, TextBoldRadioPanel);
508 
509   if (Sender = TextItalicCheckBox) or
510      (Sender = TextItalicRadioOn) or
511      (Sender = TextItalicRadioOff) or
512      (Sender = TextItalicRadioInvert) then
513     CalcNewStyle(TextItalicCheckBox, TextItalicRadioOn, TextItalicRadioOff,
514                     TextItalicRadioInvert, fsItalic, TextItalicRadioPanel);
515 
516   if (Sender = TextUnderlineCheckBox) or
517      (Sender = TextUnderlineRadioOn) or
518      (Sender = TextUnderlineRadioOff) or
519      (Sender = TextUnderlineRadioInvert) then
520     CalcNewStyle(TextUnderlineCheckBox, TextUnderlineRadioOn, TextUnderlineRadioOff,
521                     TextUnderlineRadioInvert, fsUnderline, TextUnderlineRadioPanel);
522 
523 
524   DoChanged;
525 end;
526 
527 procedure TSynColorAttrEditor.UpdateAll;
IsAhaElementnull528   function IsAhaElement(Element: TColorSchemeAttribute; aha: TAdditionalHilightAttribute): Boolean;
529   begin
530     Result := (FCurrentColorScheme <> nil) and
531               (FCurrentColorScheme.AttributeByEnum[aha] <> nil) and
532               (Element.StoredName = FCurrentColorScheme.AttributeByEnum[aha].StoredName);
533   end;
534 begin
535   if (FCurHighlightElement = nil) or UpdatingColor then
536     Exit;
537   UpdatingColor := True;
538   DisableAlign;
539   try
540     // Adjust color captions
541     ForeGroundUseDefaultCheckBox.Caption := dlgForecolor;
542     BackGroundUseDefaultCheckBox.Caption := dlgBackColor;
543     FrameColorUseDefaultCheckBox.Caption := dlgFrameColor;
544     if FCurrentColorScheme <> nil then begin
545       if IsAhaElement(FCurHighlightElement, ahaModifiedLine) then begin
546         ForeGroundUseDefaultCheckBox.Caption := dlgSavedLineColor;
547         FrameColorUseDefaultCheckBox.Caption := dlgUnsavedLineColor;
548       end else
549       if IsAhaElement(FCurHighlightElement, ahaCodeFoldingTree) then begin
550         FrameColorUseDefaultCheckBox.Caption := dlgGutterCollapsedColor;
551       end else
552       if IsAhaElement(FCurHighlightElement, ahaCaretColor) then begin
553         ForeGroundUseDefaultCheckBox.Caption := dlgCaretForeColor;
554         BackGroundUseDefaultCheckBox.Caption := dlgCaretBackColor;
555       end else
556       if IsAhaElement(FCurHighlightElement, ahaOverviewGutter) then begin
557         ForeGroundUseDefaultCheckBox.Caption := dlgOverviewGutterBack1Color;
558         BackGroundUseDefaultCheckBox.Caption := dlgOverviewGutterBack2Color;
559         FrameColorUseDefaultCheckBox.Caption := dlgOverviewGutterPageColor;
560       end;
561     end;
562 
563     if FCurHighlightElement.Group = agnDefault then begin
564       ForegroundColorBox.Style := ForegroundColorBox.Style - [cbIncludeDefault];
565       BackGroundColorBox.Style := BackGroundColorBox.Style - [cbIncludeDefault];
566     end else begin
567       ForegroundColorBox.Style := ForegroundColorBox.Style + [cbIncludeDefault];
568       BackGroundColorBox.Style := BackGroundColorBox.Style + [cbIncludeDefault];
569     end;
570 
571     // Forground
572     ForeGroundLabel.Visible              := (hafForeColor in FCurHighlightElement.Features) and
573                                             (FCurHighlightElement.Group = agnDefault);
574     ForeGroundUseDefaultCheckBox.Visible := (hafForeColor in FCurHighlightElement.Features) and
575                                             not(FCurHighlightElement.Group = agnDefault);
576     ForegroundColorBox.Visible           := (hafForeColor in FCurHighlightElement.Features);
577 
578     ForegroundColorBox.Selected := NoneToDefault(FCurHighlightElement.Foreground);
579     if ForegroundColorBox.Selected = clDefault then
580       ForegroundColorBox.Tag := ForegroundColorBox.DefaultColorColor
581     else
582       ForegroundColorBox.Tag := ForegroundColorBox.Selected;
583     ForeGroundUseDefaultCheckBox.Checked := ForegroundColorBox.Selected <> clDefault;
584 
585     ForeAlphaSpin.Visible  := ForegroundColorBox.Visible and
586                              (hafAlpha in FCurHighlightElement.Features);
587     ForeAlphaLabel.Visible := ForeAlphaSpin.Visible;
588     if FCurHighlightElement.ForeAlpha = 0 then begin
589       ForeAlphaSpin.Value    := 256; // Off
590       Application.ProcessMessages;
591       ForeAlphaSpin.Caption  := dlgEdOff;
592     end
593     else
594       ForeAlphaSpin.Value    := FCurHighlightElement.ForeAlpha;
595 
596     ForePriorSpin.Visible  := ForegroundColorBox.Visible and FShowPrior and
597                              (hafPrior in FCurHighlightElement.Features);
598     ForePriorLabel.Visible := ForePriorSpin.Visible;
599     ForePriorSpin.Value    := FCurHighlightElement.ForePriority;
600 
601 
602     // BackGround
603     BackGroundLabel.Visible              := (hafBackColor in FCurHighlightElement.Features) and
604                                             (FCurHighlightElement.Group = agnDefault);
605     BackGroundUseDefaultCheckBox.Visible := (hafBackColor in FCurHighlightElement.Features) and
606                                             not(FCurHighlightElement.Group = agnDefault);
607     BackGroundColorBox.Visible           := (hafBackColor in FCurHighlightElement.Features);
608 
609     BackGroundColorBox.Selected := NoneToDefault(FCurHighlightElement.Background);
610     if BackGroundColorBox.Selected = clDefault then
611       BackGroundColorBox.Tag := BackGroundColorBox.DefaultColorColor
612     else
613       BackGroundColorBox.Tag := BackGroundColorBox.Selected;
614     BackGroundUseDefaultCheckBox.Checked := BackGroundColorBox.Selected <> clDefault;
615 
616     BackAlphaSpin.Visible := BackGroundColorBox.Visible and
617                              (hafAlpha in FCurHighlightElement.Features);
618     BackAlphaLabel.Visible := BackAlphaSpin.Visible;
619     if FCurHighlightElement.BackAlpha = 0 then begin
620       BackAlphaSpin.Value    := 256; // Off
621       BackAlphaSpin.Caption  := dlgEdOff;
622     end
623     else
624       BackAlphaSpin.Value    := FCurHighlightElement.BackAlpha;
625 
626     BackPriorSpin.Visible  := ForegroundColorBox.Visible and FShowPrior and
627                              (hafPrior in FCurHighlightElement.Features);
628     BackPriorLabel.Visible := BackPriorSpin.Visible;
629     BackPriorSpin.Value    := FCurHighlightElement.BackPriority;
630 
631     // Frame
632     FrameColorUseDefaultCheckBox.Visible := hafFrameColor in FCurHighlightElement.Features;
633     FrameColorBox.Visible                := hafFrameColor in FCurHighlightElement.Features;
634     FrameEdgesBox.Visible                := hafFrameEdges in FCurHighlightElement.Features;
635     FrameStyleBox.Visible                := hafFrameStyle in FCurHighlightElement.Features;
636 
637     FrameColorBox.Selected := NoneToDefault(FCurHighlightElement.FrameColor);
638     if FrameColorBox.Selected = clDefault then
639       FrameColorBox.Tag := FrameColorBox.DefaultColorColor
640     else
641       FrameColorBox.Tag := FrameColorBox.Selected;
642     FrameColorUseDefaultCheckBox.Checked := FrameColorBox.Selected <> clDefault;
643     FrameEdgesBox.ItemIndex := integer(FCurHighlightElement.FrameEdges);
644     FrameStyleBox.ItemIndex := integer(FCurHighlightElement.FrameStyle);
645     FrameEdgesBox.Enabled := FrameColorUseDefaultCheckBox.Checked;
646     FrameStyleBox.Enabled := FrameColorUseDefaultCheckBox.Checked;
647 
648     FrameAlphaSpin.Visible := FrameColorBox.Visible and
649                              (hafAlpha in FCurHighlightElement.Features);
650     FrameAlphaLabel.Visible := FrameAlphaSpin.Visible;
651     if FCurHighlightElement.FrameAlpha = 0 then begin
652       FrameAlphaSpin.Value    := 256; // Off
653       FrameAlphaSpin.Caption  := dlgEdOff;
654     end
655     else
656       FrameAlphaSpin.Value    := FCurHighlightElement.FrameAlpha;
657 
658     FramePriorSpin.Visible  := ForegroundColorBox.Visible and FShowPrior and
659                              (hafPrior in FCurHighlightElement.Features);
660     FramePriorLabel.Visible := FramePriorSpin.Visible;
661     FramePriorSpin.Value    := FCurHighlightElement.FramePriority;
662 
663     // Markup Fold
664     MarkupFoldColorUseDefaultCheckBox.Visible := hafMarkupFoldColor in FCurHighlightElement.Features;
665     MarkupFoldColorBox.Visible                := hafMarkupFoldColor in FCurHighlightElement.Features;
666     MarkupFoldAlphaLabel.Visible             := hafMarkupFoldColor in FCurHighlightElement.Features;
667     MarkupFoldAlphaSpin.Visible              := hafMarkupFoldColor in FCurHighlightElement.Features;
668     MarkupFoldStyleBox.Visible               := hafMarkupFoldColor in FCurHighlightElement.Features;
669 
670     MarkupFoldColorBox.Selected := NoneToDefault(FCurHighlightElement.MarkupFoldLineColor);
671     if MarkupFoldColorBox.Selected = clDefault then
672       MarkupFoldColorBox.Tag := MarkupFoldColorBox.DefaultColorColor
673     else
674       MarkupFoldColorBox.Tag := MarkupFoldColorBox.Selected;
675     MarkupFoldColorUseDefaultCheckBox.Checked := MarkupFoldColorBox.Selected <> clDefault;
676 
677     MarkupFoldStyleBox.ItemIndex := integer(FCurHighlightElement.MarkupFoldLineStyle);
678     MarkupFoldStyleBox.Enabled := MarkupFoldColorUseDefaultCheckBox.Checked;
679 
680     if FCurHighlightElement.MarkupFoldLineAlpha = 0 then begin
681       MarkupFoldAlphaSpin.Value    := 256; // Off
682       MarkupFoldAlphaSpin.Caption  := dlgEdOff;
683     end
684     else
685       MarkupFoldAlphaSpin.Value    := FCurHighlightElement.MarkupFoldLineAlpha;
686 
687     // Styles
688     TextBoldCheckBox.Visible      := hafStyle in FCurHighlightElement.Features;
689     TextItalicCheckBox.Visible    := hafStyle in FCurHighlightElement.Features;
690     TextUnderlineCheckBox.Visible := hafStyle in FCurHighlightElement.Features;
691 
692     TextBoldRadioPanel.Visible      := hafStyleMask in FCurHighlightElement.Features;
693     TextItalicRadioPanel.Visible    := hafStyleMask in FCurHighlightElement.Features;
694     TextUnderlineRadioPanel.Visible := hafStyleMask in FCurHighlightElement.Features;
695 
696     if hafStyleMask in FCurHighlightElement.Features then begin
697       TextBoldCheckBox.Checked   := (fsBold in FCurHighlightElement.Style) or
698                                     (fsBold in FCurHighlightElement.StyleMask);
699       TextBoldRadioPanel.Enabled := TextBoldCheckBox.Checked;
700 
701       if not(fsBold in FCurHighlightElement.StyleMask) then
702         TextBoldRadioInvert.Checked := True
703       else
704       if fsBold in FCurHighlightElement.Style then
705         TextBoldRadioOn.Checked := True
706       else
707         TextBoldRadioOff.Checked := True;
708 
709       TextItalicCheckBox.Checked   := (fsItalic in FCurHighlightElement.Style) or
710                                       (fsItalic in FCurHighlightElement.StyleMask);
711       TextItalicRadioPanel.Enabled := TextItalicCheckBox.Checked;
712 
713       if not(fsItalic in FCurHighlightElement.StyleMask) then
714         TextItalicRadioInvert.Checked := True
715       else
716       if fsItalic in FCurHighlightElement.Style then
717         TextItalicRadioOn.Checked := True
718       else
719         TextItalicRadioOff.Checked := True;
720 
721       TextUnderlineCheckBox.Checked := (fsUnderline in FCurHighlightElement.Style) or
722                                   (fsUnderline in FCurHighlightElement.StyleMask);
723       TextUnderlineRadioPanel.Enabled := TextUnderlineCheckBox.Checked;
724 
725       if not(fsUnderline in FCurHighlightElement.StyleMask) then
726         TextUnderlineRadioInvert.Checked := True
727       else
728       if fsUnderline in FCurHighlightElement.Style then
729         TextUnderlineRadioOn.Checked := True
730       else
731         TextUnderlineRadioOff.Checked := True;
732     end
733     else
734     begin
735       TextBoldCheckBox.Checked      := fsBold in FCurHighlightElement.Style;
736       TextItalicCheckBox.Checked    := fsItalic in FCurHighlightElement.Style;
737       TextUnderlineCheckBox.Checked := fsUnderline in FCurHighlightElement.Style;
738     end;
739 
740     UpdatingColor := False;
741   finally
742     EnableAlign;
743   end;
744   pnlElementAttributesResize(nil);
745 end;
746 
747 procedure TSynColorAttrEditor.SetCurHighlightElement(AValue: TColorSchemeAttribute);
748 begin
749   if FCurHighlightElement = AValue then Exit;
750   FCurHighlightElement := AValue;
751   UpdateAll;
752 end;
753 
754 procedure TSynColorAttrEditor.DoChanged;
755 begin
756   if Assigned(FOnChanged) then
757     FOnChanged(Self);
758 end;
759 
760 procedure TSynColorAttrEditor.SetShowPrior(AValue: Boolean);
761 begin
762   if FShowPrior = AValue then Exit;
763   FShowPrior := AValue;
764   UpdateAll;
765 end;
766 
767 constructor TSynColorAttrEditor.Create(TheOwner: TComponent);
768 begin
769   inherited Create(TheOwner);
770   FShowPrior := False;
771   ForegroundColorBox.DropDownCount := EnvironmentOptions.DropDownCount;
772   BackGroundColorBox.DropDownCount := EnvironmentOptions.DropDownCount;
773   FrameColorBox.DropDownCount := EnvironmentOptions.DropDownCount;
774   FrameEdgesBox.DropDownCount := EnvironmentOptions.DropDownCount;
775   FrameStyleBox.DropDownCount := EnvironmentOptions.DropDownCount;
776   MarkupFoldColorBox.DropDownCount := EnvironmentOptions.DropDownCount;
777   MarkupFoldStyleBox.DropDownCount := EnvironmentOptions.DropDownCount;
778 end;
779 
780 procedure TSynColorAttrEditor.Setup;
781 begin
782   UpdatingColor := False;
783   ColumnPosBevel.Height := 1;
784   ForeGroundLabel.Caption := dlgForecolor;
785   BackGroundLabel.Caption := dlgBackColor;
786   ForeGroundUseDefaultCheckBox.Caption := dlgForecolor;
787   BackGroundUseDefaultCheckBox.Caption := dlgBackColor;
788   FrameColorUseDefaultCheckBox.Caption := dlgFrameColor;
789   MarkupFoldColorUseDefaultCheckBox.Caption := dlgMarkupFoldColor;
790   ForeAlphaLabel.Caption := lisAlpha;
791   BackAlphaLabel.Caption := lisAlpha;
792   FrameAlphaLabel.Caption := lisAlpha;
793   MarkupFoldAlphaLabel.Caption := lisAlpha;
794   ForePriorLabel.Caption := lisPriority;
795   BackPriorLabel.Caption := lisPriority;
796   FramePriorLabel.Caption := lisPriority;
797 
798   TextBoldCheckBox.Caption := dlgEdBold;
799   TextBoldRadioOn.Caption := dlgEdOn;
800   TextBoldRadioOff.Caption := dlgEdOff;
801   TextBoldRadioInvert.Caption := dlgEdInvert;
802 
803   TextItalicCheckBox.Caption := dlgEdItal;
804   TextItalicRadioOn.Caption := dlgEdOn;
805   TextItalicRadioOff.Caption := dlgEdOff;
806   TextItalicRadioInvert.Caption := dlgEdInvert;
807 
808   TextUnderlineCheckBox.Caption := dlgEdUnder;
809   TextUnderlineRadioOn.Caption := dlgEdOn;
810   TextUnderlineRadioOff.Caption := dlgEdOff;
811   TextUnderlineRadioInvert.Caption := dlgEdInvert;
812 
813   Constraints.MinHeight := max(Constraints.MinHeight,
814                                pnlUnderline.Top + pnlUnderline.Height +
815                                Max(pnlUnderline.BorderSpacing.Around,
816                                    pnlUnderline.BorderSpacing.Bottom)
817                               );
818 end;
819 
820 end.
821 
822