TrzButton is vertical text possible?

Home Forums Konopka Signature VCL Controls (formerly Raize Components) TrzButton is vertical text possible?

Viewing 3 reply threads
  • Author
    Posts
    • #1732

      I’m looking to use a TrzButton and it would be a big help if I could get the text to be vertical; I see that a TrzLabel component has an “Angle” property that allows you to make a label with vertical text but the button component does not have a similar property. Am I overlooking something? Is there a way to accomplish this?

    • #1733
      Ray Konopka
      Keymaster

        Hi,
        Unfortunately, the TRzButton does not support the same display capabilities as the TRzLabel. The TRzButton class does have a Draw3DText method that is virtual that does all the drawing of the text of the button. And the TRzLabel also has a Draw3DText method. So, in theory you should be able to override the Draw3DText method of TRzButton with the one from TRzLabel. Well, I decided to try that for fun. Turns out you can indeed do that, but there are several properties that are in TRzLabel that do not exist in TRzButton. So, I ended up making several assumptions to eliminate a lot of code. For example, I eliminated the 3D text features. I also removed the CenterPoint property from TRzLabel as well as the Rotation property, which controls whether the text is rotated flat or on a curve. The TRzLabelButton below just supports the flat rotation.
        The code below is for a form unit. Just create a new empty VCL project and then create a FormCreate event handler. Then simply copy the code from below into your form unit. You should then be able to run the program and see a button with rotated text.
        Ray

        
        unit Unit5;
        
        interface
        
        uses
          Winapi.Windows,
          Winapi.Messages,
          System.SysUtils,
          System.Variants,
          System.Classes,
          Vcl.Graphics,
          Vcl.Controls,
          Vcl.Forms,
          Vcl.Dialogs,
          Vcl.StdCtrls,
          RzButton,
          RzLabel;
        
        type
          TRzLabelButton = class( TRzButton )
          private
            FAngle: Integer;
            procedure SetAngle( Value: Integer );
          protected
            procedure Draw3DText( Canvas: TCanvas; R: TRect; Flags: DWord ); override;
          published
            property Angle: Integer
              read FAngle
              write SetAngle;
          end;
        
          TForm5 = class(TForm)
            procedure FormCreate(Sender: TObject);
          private
            B: TRzLabelButton;
          public
          end;
        
        var
          Form5: TForm5;
        
        implementation
        
        {$R *.dfm}
        
        uses
          Vcl.Themes,
          RzCommon;
        
        procedure TRzLabelButton.SetAngle( Value: Integer );
        begin
          if FAngle <> Value then
          begin
            if Value < 0 then
              FAngle := 360 - Abs( Value )
            else
              FAngle := Value mod 360;
        
            if not ( csLoading in ComponentState ) and
               ( Value <> 0 ) and
               not IsTrueTypeFont( Font ) then
            begin
              Font.Name := 'Verdana';  { Switch to Verdana if current font is not TrueType }
            end;
        
        //    if ( Angle <> 0 ) and ( FRotation = roNone ) then
        //      FRotation := roFlat;
        //    AdjustBounds;
            Repaint;
          end;
        end;
        
        procedure TRzLabelButton.Draw3DText( Canvas: TCanvas; R: TRect; Flags: DWord );
        const
          FShadowDepth = 2;
          WordWrap = False;
          ShowAccelChar = False;
        var
          TempRct: TRect;
          ULColor, LRColor: TColor;
          Center: TPoint;
          Radius, Rad: Extended;
          H, W: Integer;
          HalfShadow, ShadowOffset: Integer;
          TempAlignment: TAlignment;
        
          function TextAligned( A: DWord ): Boolean;
          begin
            Result := ( Flags and A ) = A;
          end;
        
        begin
          Canvas.Brush.Style := bsClear;
        
          HalfShadow := FShadowDepth div 2;
        
        //  FixClientRect( R, True );
        //  InflateRect( R, -FTextMargin, -FTextMargin );
        
          TempAlignment := Alignment;
          if UseRightToLeftAlignment then
            ChangeBiDiModeAlignment( TempAlignment );
        
          Flags := dt_ExpandTabs or DrawTextAlignments[ TempAlignment ];
        
          if TempAlignment = taRightJustify then
            Flags := Flags or dt_Right;
        
          if UseRightToLeftAlignment then
            Flags := Flags or dt_RtlReading;
        
          if WordWrap then
            Flags := Flags or dt_WordBreak;
        
          if not ShowAccelChar then
            Flags := Flags or dt_NoPrefix;
        
          Canvas.Font := Self.Font;
        
          Center := Point( Width div 2, Height div 2 );
        
          Rad := ( FAngle * Pi / 180 ) + ( Pi / 2 );
          Radius := Canvas.TextHeight( 'Pp' ) / 4;
        
          W := Canvas.TextWidth( Caption );
          H := Canvas.TextHeight( 'Pp' );
          ShadowOffset := 0;
        
          W := W + ShadowOffset;
          H := H + ShadowOffset;
        
          case FAngle of
            0, 360:
            begin
              if TextAligned( dt_Center ) then
                SetTextAlign( Canvas.Handle, ta_Center )
              else if TextAligned( dt_Right ) then
                Center.X := R.Right - W - ShadowOffset
              else
                Center.X := R.Left + ShadowOffset;
              Center.Y := Center.Y - H div 2;
            end;
        
            90:
            begin
              Center.X := Center.X - Round( Radius * Cos( Rad ) );
              if TextAligned( dt_Center ) then
                Center.Y := R.Bottom - ( R.Bottom - W ) div 2
              else if TextAligned( dt_Right ) then
                Center.Y := R.Top + W + ShadowOffset
              else
                Center.Y := R.Bottom - ShadowOffset;
              SetTextAlign( Canvas.Handle, ta_Left or ta_Baseline );
            end;
        
            180:
            begin
              if TextAligned( dt_Center ) then
                Center.X := R.Right - ( R.Right - W ) div 2
              else if TextAligned( dt_Right ) then
                Center.X := R.Left + W
              else
                Center.X := R.Right - ShadowOffset;
              Center.Y := Center.Y - ( H div 4 );
              SetTextAlign( Canvas.Handle, ta_Left or ta_Baseline );
            end;
        
            270:
            begin
              Center.X := Center.X - Round( Radius * Cos( Rad ) );
              if TextAligned( dt_Center ) then
                Center.Y := ( R.Bottom - W ) div 2
              else if TextAligned( dt_Right ) then
                Center.Y := R.Bottom - W - ShadowOffset
              else
                Center.Y := R.Left + ShadowOffset;
              SetTextAlign( Canvas.Handle, ta_Left or ta_Baseline );
            end;
        
            else
            begin
              Center.X := Center.X - Round( Radius * Cos( Rad ) );
              Center.Y := Center.Y + Round( Radius * Sin( Rad ) );
              SetTextAlign( Canvas.Handle, ta_Center or ta_Baseline );
            end;
          end; { case }
        
          Canvas.Font.Handle := RotateFont( Self.Font, FAngle );
        
          TempRct := R;
          if Enabled then
          begin
            if ActiveStyleServicesEnabled and not UsingSystemStyle then
              Canvas.Font.Color := ActiveStyleFontColor( sfTextLabelNormal )
            else
              Canvas.Font.Color := Font.Color;
        
            Canvas.TextRect( TempRct, Center.X, Center.Y, Caption )
        
          end
          else { if not Enabled }
          begin
            if UsingSystemStyle then
              Canvas.Font.Color := clGrayText
            else
              Canvas.Font.Color := ActiveStyleFontColor( sfWindowTextDisabled );
        
            Canvas.TextRect( TempRct, Center.X, Center.Y, Caption );
          end;
        end;
        
        procedure TForm5.FormCreate(Sender: TObject);
        begin
          B := TRzLabelButton.Create( Self );
          B.Parent := Self;
          B.SetBounds( 50, 50, 50, 200 );
          B.Angle := 90;
          B.Caption := 'Rotated Text';
        end;
        
        end.
      • #1734
        Ray Konopka
        Keymaster

          Here is a screen shot of the button.

        • #1736

          Looks great, thanks so much!

      Viewing 3 reply threads
      • You must be logged in to reply to this topic.