From 3d74bffa3b2e69793dcb6a5d870155ebe2a0636a Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Sat, 20 Jun 2015 11:34:37 +0200 Subject: [PATCH] messages, custom drawn, fixes - horz scroll bar pos was not handled - reset horz scroll bar to 0 when new messages are emitted - constrain color value to make sure selected color <> background color --- src/ce_messages.pas | 65 ++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/ce_messages.pas b/src/ce_messages.pas index 79a203f1..04ae8003 100644 --- a/src/ce_messages.pas +++ b/src/ce_messages.pas @@ -7,7 +7,7 @@ interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, ComCtrls, lcltype, ce_widget, ActnList, Menus, clipbrd, AnchorDocking, TreeFilterEdit, - Buttons, ce_writableComponent, ce_common, ce_project, ce_synmemo, GraphType, + Buttons, math,ce_writableComponent, ce_common, ce_project, ce_synmemo, GraphType, ce_dlangutils, ce_interfaces, ce_observer; type @@ -48,6 +48,10 @@ type procedure AssignTo(Dest: TPersistent); override; end; + // grants access to some protected fields that should be actually public (scoll position needed for custom draw !) + TTreeHack = class(TTreeView) + end; + { TCEMessagesWidget } TCEMessagesWidget = class(TCEWidget, ICEEditableOptions, ICEMultiDocObserver, ICEProjectObserver, ICEMessagesDisplay) @@ -131,6 +135,7 @@ type procedure message(const aValue: string; aData: Pointer; aCtxt: TCEAppMessageCtxt; aKind: TCEAppMessageKind); procedure clearbyContext(aCtxt: TCEAppMessageCtxt); procedure clearbyData(aData: Pointer); + procedure scrollToBack; protected procedure updateLoop; override; // @@ -138,20 +143,18 @@ type function contextActionCount: integer; override; function contextAction(index: integer): TAction; override; // - property maxMessageCount: Integer read fMaxMessCnt write setMaxMessageCount; - property autoSelectCategory: boolean read fAutoSelect write setAutoSelectCategory; - property singleMessageClick: boolean read fSingleClick write setSingleMessageClick; + property maxMessageCount: Integer read fMaxMessCnt write setMaxMessageCount; + property autoSelectCategory: boolean read fAutoSelect write setAutoSelectCategory; + property singleMessageClick: boolean read fSingleClick write setSingleMessageClick; // - property colorBuble: TColor read fMsgColors[amkBub] write setColorBuble; - property colorInfo: TColor read fMsgColors[amkInf] write setColorInfo; - property colorHint: TColor read fMsgColors[amkHint] write setColorHint; - property colorWarning: TColor read fMsgColors[amkWarn] write setColorWarning; - property colorError: TColor read fMsgColors[amkErr] write setColorError; + property colorBuble: TColor read fMsgColors[amkBub] write setColorBuble; + property colorInfo: TColor read fMsgColors[amkInf] write setColorInfo; + property colorHint: TColor read fMsgColors[amkHint] write setColorHint; + property colorWarning: TColor read fMsgColors[amkWarn] write setColorWarning; + property colorError: TColor read fMsgColors[amkErr] write setColorError; public constructor create(aOwner: TComponent); override; destructor destroy; override; - // - procedure scrollToBack; end; function guessMessageKind(const aMessg: string): TCEAppMessageKind; @@ -163,6 +166,7 @@ implementation const optname = 'messages.txt'; + minColor = $232323; {$REGION TCEMessagesOptions ----------------------------------------------------} constructor TCEMessagesOptions.Create(AOwner: TComponent); @@ -400,25 +404,25 @@ end; procedure TCEMessagesWidget.setColorError(aValue: TColor); begin - fMsgColors[amkErr] := aValue; + fMsgColors[amkErr] := max(aValue, minColor); List.Invalidate; end; procedure TCEMessagesWidget.setColorInfo(aValue: TColor); begin - fMsgColors[amkInf] := aValue; + fMsgColors[amkInf] := max(aValue, minColor); List.Invalidate; end; procedure TCEMessagesWidget.setColorHint(aValue: TColor); begin - fMsgColors[amkHint] := aValue; + fMsgColors[amkHint] := max(aValue, minColor); List.Invalidate; end; procedure TCEMessagesWidget.setColorBuble(aValue: TColor); begin - fMsgColors[amkBub] := aValue; + fMsgColors[amkBub] := max(aValue, minColor); List.Invalidate; end; @@ -431,25 +435,24 @@ end; procedure TCEMessagesWidget.ListCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean); var + x: integer; rc: TRect; - customdraw: Boolean; begin - customdraw := fMsgColors[TCEAppMessageKind(node.ImageIndex + 1)] <> clDefault; - if customdraw then + rc := node.DisplayRect(false); + x := rc.Left + 2 - TTreeHack(list).ScrolledLeft; + // warning: the cast may become wrong if the enum is modified. + Sender.Canvas.Brush.Color := fMsgColors[TCEAppMessageKind(node.ImageIndex + 1)]; + if node.Selected then begin - rc := node.DisplayRect(false); - Sender.Canvas.Brush.Color := fMsgColors[TCEAppMessageKind(node.ImageIndex + 1)]; - if node.Selected then - begin - Sender.Canvas.DrawFocusRect(rc); - Sender.Canvas.Brush.Color := Sender.Canvas.Brush.Color - $232323; - end; - Sender.Canvas.FillRect(rc); - Sender.Canvas.TextOut(rc.Left + 30, rc.Top, node.Text); - list.Images.Draw(sender.Canvas, rc.Left + 1, (rc.Top + rc.Bottom - list.Images.Height) div 2, - node.ImageIndex, Node.NodeEffect); + Sender.Canvas.DrawFocusRect(rc); + Sender.Canvas.Brush.Color := Sender.Canvas.Brush.Color - minColor; end; - DefaultDraw := not customdraw; + Sender.Canvas.FillRect(rc); + list.Images.Draw(sender.Canvas, x, (rc.Top + rc.Bottom - list.Images.Height) div 2, + node.ImageIndex, Node.NodeEffect); + x += list.Images.Width + 5; + Sender.Canvas.TextOut(x, rc.Top, node.Text); + DefaultDraw := false; end; {$ENDREGION} @@ -669,9 +672,9 @@ begin item.SelectedIndex := item.ImageIndex; if not fastDisplay then begin - //TODO-cfeature: reset horz scroll bar to the left clearOutOfRangeMessg; scrollToBack; + TTreeHack(list).scrolledLeft := 0; Application.ProcessMessages; filterMessages(fCtxt); end;