How to aligment right and left,

Dear AFL Experts!

I am currently learning AFL (AmiBroker Formula Language) and have successfully integrated Gemini into AmiBroker. That is absolutely wonderful!

I am trying to write a code to create a "top panel" to display essential market information. My biggest hurdle is the alignment of text.

I would be very grateful if you could help me with the following layout requirements:

  1. "Left Alignment" : Align the basic price and volume information to the left, including of Open Price, Low Price, High Price, Close Price, and Volume.
  2. Right Alignment: Align the Moving Average indicators (such as MA20, MA50, MA100, etc.) to the right.

I would be highly appreciative if someone could review and assist me with the code correction.
Wishing you all a happy weekend with your families.
(My code as bellow)

_SECTION_BEGIN("Top Panel");

GfxSetZOrder(5);
pxwidth = Status("pxwidth");
pxheight = Status("pxheight");

PanelHeight = pxheight / 5; 
GfxGradientRect(0, 0, pxwidth, PanelHeight, ColorRGB( 40, 40, 40 ), ColorRGB( 10, 10, 10 )); 

GfxSetTextColor( ColorRGB( 25, 225, 2 ) ); 
GfxSelectFont("UVN But Long 1", PanelHeight / 8, 700 ); 
GfxSetTextAlign( 6 );
GfxTextOut( "SECURITIES INVESTMENT SYSTEM - " + Name() + " (" + Interval( 1 ) + ")", pxwidth / 2, PanelHeight / 20 );

GfxSetTextColor( colorWhite );
GfxSelectFont("Arial", 10, 400 );
GfxSetBkMode( 1 ); 

LeftMargin = 15;
RowSpacing = PanelHeight / 5;
CurrentY = PanelHeight / 4; 

GfxSetTextAlign( 1 ); 

GfxTextOut( "OPEN:", LeftMargin, CurrentY );
GfxSetTextColor( ColorRGB( 100, 255, 100 ) ); 
GfxTextOut( WriteVal( O, 1.2 ), LeftMargin + 70, CurrentY );
CurrentY = CurrentY + RowSpacing;

GfxSetTextColor( colorWhite );
GfxTextOut( "HIGH:", LeftMargin, CurrentY );
GfxSetTextColor( ColorRGB( 100, 255, 100 ) );
GfxTextOut( WriteVal( H, 1.2 ), LeftMargin + 70, CurrentY );
CurrentY = CurrentY + RowSpacing;

GfxSetTextColor( colorWhite );
GfxTextOut( "LOW:", LeftMargin, CurrentY );
GfxSetTextColor( ColorRGB( 255, 100, 100 ) ); 
GfxTextOut( WriteVal( L, 1.2 ), LeftMargin + 70, CurrentY );
CurrentY = CurrentY + RowSpacing;

PercentChange = ( C / Ref( C, -1 ) - 1 ) * 100;
ColorChange = IIf( PercentChange >= 0, ColorRGB( 100, 255, 100 ), ColorRGB( 255, 100, 100 ) );
GfxSetTextColor( colorWhite );
GfxTextOut( "CLOSE:", LeftMargin, CurrentY );
GfxSetTextColor( LastValue( ColorChange ) );
GfxTextOut( WriteVal( C, 1.2 ) + " (" + WriteVal( PercentChange, 1.2 ) + "%)", LeftMargin + 70, CurrentY );

GfxSetTextColor( colorWhite ); 

//GEMINI CREAT RIGHT Alig

RightMargin = pxwidth - 15;
CurrentY = PanelHeight / 4; 
GapFromRight = 150; 

MA_Periods[ 0 ] = 10;
MA_Periods[ 1 ] = 20;
MA_Periods[ 2 ] = 50;
MA_Periods[ 3 ] = 100;
MA_Periods[ 4 ] = 200;

for ( i = 0; i < 5; i = i + 1 )
{

    CurrentMA = MA( C, MA_Periods[ i ] ); 
    label_str = "";
    switch( i )
    {
        case 0: label_str = "MA 10"; break;
        case 1: label_str = "MA 20"; break;
        case 2: label_str = "MA 50"; break;
        case 3: label_str = "MA 100"; break;
        case 4: label_str = "MA 200"; break;
    }
    

    MASignal = IIf( C > CurrentMA, 1, 0 );

    GfxSetTextAlign( 3 ); 
    GfxTextOut( "Bull", RightMargin, CurrentY );
   
    GfxSetTextColor( colorWhite );
    GfxTextOut( label_str + ": " + WriteVal( CurrentMA, 1.2 ), RightMargin - GapFromRight, CurrentY );
    CurrentY = CurrentY + RowSpacing;
}
_SECTION_END();

@Huynq99, here's a modified version of your code that shows how to align text.
You can definitely improve it from there!
I've also added an example function to show how to simplify some repetitive tasks.

While Gemini is useful, I recommend spending more time reading the manual and examples provided on this page (or feeding them to the AI ​​to help the model understand how to write the correct code—by the way, double-check that this code actually does the right things! I spent most of my time demonstrating how to align things).
Specifically, on that page, take a look at "Example 2. Example of formatted (table-like) output using low-level graphing functions"

pxwidth = Status( "pxwidth" );
pxheight = Status( "pxheight" );

GfxSetCoordsMode( 0 );
GfxGradientRect( 0, 0, pxWidth, pxHeight, ColorRGB( 40, 40, 40 ), ColorRGB( 10, 10, 10 ) );
GfxSetBkMode( 1 );

GfxSelectFont( "Arial", 20 );
GfxSetTextColor( ColorRGB( 25, 225, 2 ) );
GfxSetTextAlign( 6 | 24 );
GfxTextOut( "SECURITIES INVESTMENT SYSTEM - " + Name() + " (" + Interval( 1 ) + ")", pxwidth / 2, 30 );

// Function to display a label-value pair
function DrawLabelValue( label, value, leftMargin, yPosition, priceSpace, valueColor )
{
    // this shows how to aling using the baseline (using 2 different font sizes)
    GfxSelectFont( "Arial", 14 );
    GfxSetTextColor( colorWhite );
    GfxSetTextAlign( 0 | 24 );
    GfxTextOut( label, leftMargin, yPosition );

    if( SelectedValue( value ) )
    {
        GfxSelectFont( "Arial", 18, 700 );
        GfxSetTextColor( valueColor );
        GfxSetTextAlign( 2 | 24 );
        GfxTextOut( WriteVal( SelectedValue( value ), 1.2 ), leftMargin + priceSpace, yPosition );
    }
}

// General
ColorValues = ColorRGB( 100, 255, 100 );
ColorAlert = ColorRGB( 255, 80, 80 );
// ColorLabels = ColorWhite....

PercentChange = ( C / Ref( C, -1 ) - 1 ) * 100;
ColorChange = IIf( SelectedValue( PercentChange ) >= 0, ColorValues, ColorAlert );

// LEFT AREA
// setup
LeftMargin = 16;
TopY = CurrentY = 60;
RowSpacing = 28;
PriceSpace = 240;


// Draw OHLC data
DrawLabelValue( "OPEN:", O, LeftMargin, CurrentY, PriceSpace, ColorValues );
CurrentY = CurrentY + RowSpacing;

DrawLabelValue( "HIGH:", H, LeftMargin, CurrentY, PriceSpace, ColorValues );
CurrentY = CurrentY + RowSpacing;

DrawLabelValue( "LOW:", L, LeftMargin, CurrentY, PriceSpace, ColorValues );
CurrentY = CurrentY + RowSpacing;

// some other text on the same baseline
DrawLabelValue( "CLOSE:", C, LeftMargin, CurrentY, PriceSpace, ColorChange );
GfxSetTextColor( colorChange );
GfxSetTextAlign( 0 | 24 );
GfxTextOut( "(" + WriteVal( PercentChange, 1.2 ) + "%)", LeftMargin + PriceSpace + 20, CurrentY );
CurrentY = CurrentY + RowSpacing;

DrawLabelValue( "VOLUME (k):", V / 1000, LeftMargin, CurrentY, PriceSpace, colorChange );
CurrentY = CurrentY + RowSpacing;


// RIGHT AREA - similar to orignial code
// setup
RightMargin = pxwidth - 16;
GapFromRight = 160;
PriceSpace = 100;
CurrentY = TopY; // reset first line Y
MA_Periods = Matrix( 5, 1 ); // use a matrix intead of an array to handel chart with few
MA_Periods[ 0][ 0 ] = 20;
MA_Periods[ 1][ 0 ] = 20;
MA_Periods[ 2] [ 0 ] = 50;
MA_Periods[ 3] [ 0 ] = 100;
MA_Periods[ 4] [ 0 ] = 200;

for( i = 0; i < Min( BarCount, 5 ); i = i + 1 )
{

    CurrentMA = MA( C, MA_Periods[ i ][ 0 ] );
    label_str = "";

    switch( i )
    {
        case 0:
            label_str = "MA 10";
            break;

        case 1:
            label_str = "MA 20";
            break;

        case 2:
            label_str = "MA 50";
            break;

        case 3:
            label_str = "MA 100";
            break;

        case 4:
            label_str = "MA 200";
            break;
    }

    MASignal = IIf( isNull( CurrentMA ), 0, iif( C > CurrentMA, 1, -1 ) );
    GfxSelectFont( "Arial", 14 );
    GfxSetTextColor( colorWhite );
    GfxSetTextAlign( 2 | 24 );
    GfxTextOut( label_str + ":",  RightMargin - GapFromRight, CurrentY );
    GfxSelectFont( "Arial", 18, 700 );
    GfxSetTextAlign( 2 | 24 );
    GfxSetTextColor( ColorValues );

    if( SelectedValue( CurrentMA ) )
        GfxTextOut( WriteVal( CurrentMA, 1.2 ), RightMargin - GapFromRight + PriceSpace, CurrentY );

    GfxSelectFont( "Arial", 14 );

    if( SelectedValue( MAsignal ) == 1 )
    {
        GfxSetTextColor( ColorValues );
        GfxTextOut( "Bull", RightMargin, CurrentY );
    }

    if( SelectedValue( MAsignal ) == -1 )
    {
        GfxSetTextColor( ColorAlert );
        GfxTextOut( "Bear", RightMargin, CurrentY );
    }

    CurrentY = CurrentY + RowSpacing;
}

Note: In my example code, I don't scale fonts, line spacing, etc. in relation to the panel height—I prefer to use constant values ​​based on the screen size configuration.

Finally, carefully read the description in the help about the gfxSetTextAlign() function to discover other text alignment options.

In particular, note how I used the value 24 (TA_BASELINE = 24) in combination (binary OR) with the base values ​​of the left and right alignment (TA_LEFT = 0, TA_CENTER = 6, TA_RIGHT = 2) to align the "baseline" of 2 different font sizes.

Note: TA_ constants come from Windows API, they are given for reference only they are not predefined in AmiBroker, so you need to use numerical values.

4 Likes

Dear My Idol peppe,

Thanks you for your reply and your advice.
My goal is to study and try both on the library and on the forum. I have no intention of buying or selling because I haven't found a method yet. Currently I'm also learning more about program debugging.

Best regards.