XP Style Glyph annoyance in ActionBars
Asked Answered
R

2

4

I dont like to ask too many questions in relation to the appearance of components, but these days appearance in Applications seems just as important.

Anyway, please see the below images:

enter image description here

Both are using the TActionManager and TActionMainMenuBar to create my main menu. The menu in the left of the image is using the Platform Default Style, the menu on the right is using the XP style defined by my TActionManager.

Notice how when the left menu is highlighted, the glyph remains the same which is perfect.

Now look at the XP style menu on the right, the glyph draws a drop shadow, pops out slightly and you can see the transparency makes the glyph appear slightly odd.

I want to enable the XP style for my UI, but the way the glyphs are painted I do not like. I also want to change my TToolbar to a TActionToolBar and apply the same XP style, but this will render the glyphs the same too.

How can I make the XP style menu defined in the TActionManager, not render the glyphs like this?

Thanks.

EDIT

This is now the result, having applied some of the techniques from the answers below:

enter image description here

Craig.

Racism answered 14/5, 2011 at 19:58 Comment(0)
Q
6

Here is some sample code that overrides the XP STYLE, creating a derived class that you can tweak as you like. First step here is to substitute your own derived menu item class, and change its DrawGlyph code, as David told you. I figured you could maybe use some sample code.

This is just a quick demo. It doesn't draw a box around checked items with glyphs, so this custom style is not compatible with Checked items, unless they have no glyphs. You would have to figure out how you want to draw the checked-glyph items (Where I wrote the DrawGlyphFrame would be a good place to add something to draw a checked-state rectangle around a glyph if the Action.Checked property is set).

unit MyActionControlStyle;

// Using this unit: Add it to your project. In your project set your
// style at runtime, add the unit to your uses clause and then set the style
// in that form's formcreate event:
//   ActionManager1.Style := MyActionControlStyle.MyStyle;

interface

uses Forms,
     Types,
     Controls,
     XPActnCtrls,
     XPStyleActnCtrls,
     ActnMan,
     ActnList,
     ActnMenus,
     ActnCtrls;

type

 TMyStyleMenuItem = class(TXPStyleMenuItem)
  protected
      procedure DrawGlyph(const Location: TPoint); override;

//      procedure DrawGlyphFrame(const Location:TPoint);

 end;
 TMyStyleMenuButton = class(TXPStyleMenuButton)
 end;

 TMyStyleActionBars = class(TXPStyleActionBars)
   // override the stuff that I want different than XP Style:
    function GetControlClass(ActionBar: TCustomActionBar;
      AnItem: TActionClientItem): TCustomActionControlClass; override;

 end;

var
 MyStyle:TMyStyleActionBars;

implementation


uses ToolWin, Classes, Windows, Graphics, GraphUtil, ImgList;
{ TMyStyleActionBars }

function TMyStyleActionBars.GetControlClass(ActionBar: TCustomActionBar;
  AnItem: TActionClientItem): TCustomActionControlClass;
begin
 if ActionBar is TCustomActionPopupMenu then
    Result := TMyStyleMenuItem
  else
  if ActionBar is TCustomActionMainMenuBar then
    Result := TMyStyleMenuButton
  else
    Result := inherited GetControlClass(ActionBar,AnItem);

end;

{ TMyStyleMenuItem }

procedure TMyStyleMenuItem.DrawGlyph(const Location: TPoint);
var
  ImageList: TCustomImageList;
  DrawEnabled: Boolean;
begin
//  DrawGlyphFrame(Location);
  if not HasGlyph and IsChecked then
  begin
    Canvas.Pen.Color := ActionBar.ColorMap.FontColor;
    DrawCheck(Canvas, Point((TextBounds.Left - 5) div 2, Height div 2), 2);
  end;

  if not HasGlyph then exit;
  if Assigned(Action) then
    ImageList := ActionClient.Action.ActionList.Images
  else
    ImageList := ActionClient.OwningCollection.ActionManager.Images;
  if not Assigned(ImageList) then exit;
  DrawEnabled := Enabled and (ActionClient.ImageIndex <> -1) or
    (csDesigning in ComponentState);
  ImageList.Draw(Canvas, Location.X, Location.Y, ActionClient.ImageIndex,
    dsTransparent, itImage, DrawEnabled);

end;

initialization
  MyStyle := TMyStyleActionBars.Create;
  RegisterActnBarStyle(MyStyle);
finalization
  UnregisterActnBarStyle(MyStyle);
  MyStyle.Free;
end.
Quechua answered 15/5, 2011 at 2:50 Comment(3)
Thanks, this does the job perfect. As for the checkboxes I am sure I can adapt if needed with the advice you have given. Can you share an answer on this website? If possible I would accept David's and your Answer together.Racism
@Craig No you need to pick one!Staurolite
thats a shame, because in another question too you helped me with, someone else also helped and I dont like to choose one over the other as both posts were helpful. I will accept Warrens answer in this situation however, as he provided a code example. your answer is equally as important however.Racism
S
1

This is done by design in the VCL code. The pertinent code is TXPStyleMenuItem.DrawGlyph() in XPActnCtrls.pas.

The easiest way to change the behaviour is to register your own version of the XP action bar style based on TXPStyleActionBars. There are plenty of hooks that would allow you to override TXPStyleMenuItem.DrawGlyph().

Staurolite answered 14/5, 2011 at 21:52 Comment(4)
thanks for the information. It seems that the way Delphi does the drawing for menus and toolbars is not the best, well visually anyway. I am not sure how I could do any of the reccomended options you posted however. I have only been using Delphi for a few years now and am still learning some things, so excuse me if I come across as ignorant to some of the questions/answers.Racism
do you have the vcl source with your delphi version?Staurolite
yes, if I press Ctrl+click on a unit in the uses clause it opens the source.Racism
warren has given some more details of what I suggest. Use that and the vcl source code and you should be able to piece it together.Staurolite

© 2022 - 2024 — McMap. All rights reserved.