AmiBroker 6.25.0 BETA released


#46

Ed, as far as persistent panel is concerned, I don’t think it can get much simpler since the code uses loops already to ensure simplicity. And it works nicely so far.

See panel function below. For static var name now I have added GetchartID.

procedure GuiPersistentRadioPanel( txt, startid, numids, defaultnum, x, y, width, height, bkcolor, notifyflag, resettrigger, persist ) {
	// by fxshrat, July 2017, vrs. 1.0
	local id, event, clickevent, default_id, endid, i, n, resetcond, staticradioname, sumid;

	GfxSelectSolidBrush( bkcolor );
	GfxRoundRect( x-7, y-3, x + GfxGetTextWidth(StrExtract(txt, 0))+25, y+numids*height+3, 5, 5 );
	
	id = GuiGetEvent( 0, 0 );
	event = GuiGetEvent( 0, 1 );	
	clickevent = event == 1;	
	endid = startid + numids - 1;
	default_id = Min( endid, startid + defaultnum );
	
	sumid = n = 0;
	staticradioname = "GuiRadio_Check_" + GetChartID();
	// check whether any radio button is selected
	for( i = startid; i <= endid; i++ ) { 	
		GuiRadio( StrExtract(txt, n), i, x, y+n*height, width, height, notifyflag );
		GuiSetCheck( i, 0 );// uncheck all radio buttons before setting new one
		sumid += Nz(StaticVarGet( staticradioname + i ));
		n++;
	}

	// radio button toggle
	resetcond = resettrigger || sumid == 0;	
	if( clickevent && id >= startid && id <= endid || resetcond ) {	
		StaticVarRemove( staticradioname + "*" );
		if( resetcond ) {// if resetting or no radio button selected
			StaticVarSet( staticradioname + default_id, 1, persist );	
		} else // if setting new radio button		
			StaticVarSet( staticradioname + id, 1, persist );	
	}

	// set radio button
	for( i = startid; i <= endid; i++ ) {		
		if( ! IsNull( StaticVarGet( staticradioname + i ) ) ) {
			GuiSetCheck( i, 1 ); // set radio button					
			break;
		}
	}	
}

How to apply upper panel function?

For example,

txt = "Radio 1,Radio 2,Radio 3,Radio 4,Radio 5";// 1st substring of txt controls background width (adjustment)
// txt = "Radio 1          ,Radio 2,RadioButton 3,Radio 4,Radio 5";
numids = 3;// set number of radio buttons of the panel, here in example set from 1 to 5
startid = 40;// set start ID	

GuiPersistentRadioPanel( txt, startid, numids, defaultnum = 0, x = 10, y = 30, width = 100, height = 18, colorLightYellow, notifyflag = 1, reset = 0, persist = 0 );

Full Example below. As you can see for text I’m using different button descriptions for button 3 there. So the lengths of substring differ. Now in such cases where substrings have different name length (excl. numbering) in order to adjust background field width you simply add spaces at the end of 1st substring of whole string. See code line 66.

You can set default radio button in line 72, see defaultnum = 0. It goes from 0 to numids-1 (similar to Param…() functions). So here in example you may set it from 0 to 4. I think all the rest is self-expalining.

Here is short animation (watch how I control the background width via adding spaces to first substring of txt variable at second 53 of the video if you have different text lengths).

http://www.fastswf.com/z6tQU_Y

/// @link http://forum.amibroker.com/t/amibroker-6-25-0-beta-released/1362/46
// Persistent Radio Buttons
// by empottasch & fxshrat
// version 1.4

Version( 6.25 );
RequestTimedRefresh(1);

function calculateSineFunction( per ) {
    ff = sin( 2 * ( 4 * atan( 1 ) ) * Cum( 1 ) / per );
    return ff;
}

procedure GuiPersistentRadioPanel( txt, startid, numids, defaultnum, x, y, width, height, bkcolor, notifyflag, resettrigger, persist ) {
	// by fxshrat, July 2017, vrs. 1.0
	local id, event, clickevent, default_id, endid, i, n, resetcond, staticradioname, sumid;

	GfxSelectSolidBrush( bkcolor );
	GfxRoundRect( x-7, y-3, x + GfxGetTextWidth(StrExtract(txt, 0))+25, y+numids*height+3, 5, 5 );
	
	id = GuiGetEvent( 0, 0 );
	event = GuiGetEvent( 0, 1 );	
	clickevent = event == 1;	
	endid = startid + numids - 1;
	default_id = Min( endid, startid + defaultnum );
	
	sumid = n = 0;
	staticradioname = "GuiRadio_Check_" + GetChartID();
	// check whether any radio button is selected
	for( i = startid; i <= endid; i++ ) { 	
		GuiRadio( StrExtract(txt, n), i, x, y+n*height, width, height, notifyflag );
		GuiSetCheck( i, 0 );// uncheck all radio buttons before setting new one
		sumid += Nz(StaticVarGet( staticradioname + i ));
		n++;
	}

	// radio button toggle
	resetcond = resettrigger || sumid == 0;	
	if( clickevent && id >= startid && id <= endid || resetcond ) {	
		StaticVarRemove( staticradioname + "*" );
		if( resetcond ) {// if resetting or no radio button selected
			StaticVarSet( staticradioname + default_id, 1, persist );	
		} else // if setting new radio button		
			StaticVarSet( staticradioname + id, 1, persist );	
	}

	// set radio button
	for( i = startid; i <= endid; i++ ) {		
		if( ! IsNull( StaticVarGet( staticradioname + i ) ) ) {
			GuiSetCheck( i, 1 ); // set radio button					
			break;
		}
	}	
}

persist = 0;// 0 (false) or 1 (true) for persistent radio button
per1 = Param( "Period 1", 20, 1, 500, 1 );
per2 = Param( "Period 2", 80, 1, 500, 1 );
per3 = Param( "Period 3", 150, 1, 500, 1 );
per4 = Param( "Period 4", 200, 1, 500, 1 );
per5 = Param( "Period 5", 300, 1, 500, 1 );
reset = ParamTrigger( "Reset", "Press Here" );
numids = Param( "Number of Radio buttons", 3, 2, 5, 1 );

startid = 40;	
txt = "Radio 1           ,Radio 2,RadioButton 3,Radio 4,Radio 5";// 1st substring of txt controls background width (adjustment)

GfxSetZOrder( 0 );// background area z-shift

GuiSetFont( fnt = "Arial", size = 9 );
GfxSelectFont( fnt, size ); // if using GuiSetFont then also use GfxSelectFont for background width calculation
GuiPersistentRadioPanel( txt, startid, numids, defaultnum = 0, x = 10, y = 30, width = 200, height = 2*size, colorLightYellow, 1, reset, persist );

n = 1;
per = Null;
// execute activated radio button at each refresh
for( i = startid; i < (startid+numids); i++ ) {
	if( GuiGetCheck( i ) == 1 ) per = VarGet( "per" + n ); 
	n++;
}

rsine = calculateSineFunction( per );

GraphXSpace = 5;
SetChartBkColor( colorBlack );
Plot( rsine, "", colorBlue, styleLine, Null, Null, 0, 0, 2 );
Title = "Radio Panel Test";

BTW you can avoid background area by setting first argument of GuiRadio or GuiCheckBox to “” and creating text incl. text color via Gfx.


#47

hi fx,

thanks for that, will study it a bit in detail later.

The big difference between your code and mine is that you set GuiSetCheck() on every refresh. I set GuiSetCheck() only at the startup and when I toggle the radio button. But in my opinion this should also work. So when at the startup I set GuiSetCheck(40,1). Then when I ask for it, GuiGetCheck(40), then it should return 1. And I should not have to set it again on every refresh. I am no expert on radio buttons but this is what I intuitively would think how it should work.

But now if I ask for it, GuiGetCheck(40) I get return value -1, meaning that the value did not change. I also think Tomasz has confirmed that GuiGetCheck(40) should return 1 in this case. It would be a bit silly if I set the value to 1 and then I ask for what the value is and I get the answer: the value has not changed :slight_smile:

But if I am not correct and I need to set the checkboxes at every refresh, then thats what I will do :slight_smile: since when you set them on every refresh this problem does not seem to exist.

this is how I toggle:

// radio toggle
if( clickevent )
{
    for( i = id_1; i <= id_3; i++ )
    {
        if( i == id0 ) GuiSetCheck( i, 1 );
        else GuiSetCheck( i, 0 );
    }
}

so it sets the radio buttons only when I toggle, not at every refresh


#48

I think let’s just wait for the fix mentioned by TJ related to the check functions.
I can not use clickevent + ID check because of the “-1” issue, as it seems.
But function works so far without fix.

Anyway I simplified the function a bit more. The last loop of the function is actually not required. I figured that staticname can be written without adding ID to it.

Will post an update once fix will have been released.

procedure GuiPersistentRadioPanel( txt, startid, numids, defaultnum, x, y, width, height, bkcolor, notifyflag, resettrigger, persist ) {
	// by fxshrat, July 2017, vrs. 1.1
	local id, event, clickevent, default_id, endid, i, n, resetcond, staticradioname, sumid;
	
	GfxSelectSolidBrush( bkcolor );	
	GfxRoundRect( x-7, y-3, x + GfxGetTextWidth(StrExtract(txt, 0))+25, y+numids*height+3, 5, 5 );
	
	id = GuiGetEvent( 0, 0 );
	event = GuiGetEvent( 0, 1 );	
	clickevent = event == 1;	
	endid = startid + numids - 1;
	default_id = Min( endid, startid + defaultnum );	

	// radio button toggle
	staticradioname = "GuiRadio_Check_" + GetChartID();	
	resetcond = resettrigger || Nz(StaticVarGet( staticradioname )) == 0;	
	if( clickevent && id >= startid && id <= endid || resetcond ) {	
		StaticVarRemove( staticradioname + "*" );
		if( resetcond ) {// if resetting or no radio button selected
			StaticVarSet( staticradioname, default_id, persist );	
		} else // if setting new radio button		
			StaticVarSet( staticradioname, id, persist );	
	}

	n = 0;	
	staticID = StaticVarGet( staticradioname );
	// set button panel
	for( i = startid; i <= endid; i++ ) { 	
		GuiRadio( StrExtract(txt, n), i, x, y+n*height, width, height, notifyflag );
		GuiSetCheck( i, 0 );// uncheck all radio buttons before setting new one		
		n++;
	}
	
	// set radio button
	if( ! IsNull( staticID ) )	GuiSetCheck( staticID, 1 ); 
}

#49

hi fx,

will check it out later but I think indeed best to wait for next beta. But you are right you showed it can work even now

at the moment I have got some other responsibilities =>

a new beer. La Chouffe is too sweet. Lets see how this one turns out.

3 different grains in here, I can skip lunch tomorrow


Trendline Flickers when used with GUI Buttons
#50

I also have GUI buttons and I cant delete a trendline via the keyboard in version 6.25. I can delete a trendline via the keyboard in version 6.22 though.

Moderator comment: scroll up in this thread for the detailed info


#51

Hi

I just upgraded to 6.25 64bit. The splash screen never goes away. The last message displayed is:
“Preparing User Interface…”

I tried to remove all the plugins and the problem is the same.

I use windows 7 64bit.

Any help please? Is ther any error-log I can post?


#52

Most likely you are using some of those “High Contrast” schemes in Windows. Turn this off, i.e. select regular, NON-high contrast scheme in Windows. “High contrast” schemes turn off visual style support in Windows and is incompatible.


#53

Hello Tomasz

Thank God you are right (again).

I always setup my pcs for best performance (control panel -> Performance Information and Tools -> Adjust Visual Effects -> Adjust for Best Performance). It was working fine up to Amibroker version 6.22 64bit.

I have now selected the default windows 7 theme and now AB starts.


#54

GetCursorMouseButtons(); does not work in the area of the new GUI buttons but I guess that is supposed to be like that.

I was playing around today making the new GUI buttons “draggable”. However, because the mouse does not responds to the GetCursorMouseButtons() function (in the area of the new GUI buts) I created an area around the GUI button pack.

below the code. Works OK, but one can not drag it with too much speed. Who can make the dragging work more smoothly ? :smiley:

// Test Code: Move GUI Button-Pack using mouse, E.M.Pottasch, 8/10/2017
// Button pack can be dragged smoothly with the left mouse button pushed 
// down in the border area, but will finally settle in nearest Row and 
// Column once the left mouse button is lifted 

Version( 6.25 );
GfxSetCoordsMode( 0 );
RequestMouseMoveRefresh();
GfxSetZOrder( 0 );
reset = ParamTrigger( "Reset Button Pack Position", "Press Here" );
CellHeight = Param( "Cell Height (Pixels)", 20, 5, 200, 1 );
CellWidth = Param( "Cell Width (Pixels)", 95, 5, 200, 1 );
CellXSpace = Param( "Space Between Buttons X Direction (Pixels)", 0, 0, 50, 1 );
CellYSpace = Param( "Space Between Buttons Y Direction (Pixels)", 0, 0, 50, 1 );
transx = Param( "Small Move Button Pack along X-Axis (Pixels)", 0, 0, 2000, 1 );
transy = Param( "Small Move Button Pack along Y-Axis (Pixels)", 0, 0, 2000, 1 );
BorderWidth = Param( "Border Width (Pixels)", 50, 0, 100, 1 );
rm = RadioButtonLeftMargin = Param( "Radion Button Left Margin (Pixels)", 2, 0, 10, 1 );
FontPointsize = Param( "Font Pointsize", 10, 1, 50, 1 );
FontType = ParamList( "Font Type", "Segoe UI|Tahoma|Arial|Arial Black|Verdana|Courier New|Times New Roman|Lucida Sans Unicode|Trebuchet MS|Lucida Console", 3 );
ButtonclrBack = ParamColor( "Button Back Color", ColorRGB( 254, 254, 0 ) );
per1 = Param( "Period id_1 => 40", 20, 1, 500, 1 );
per2 = Param( "Period id_2 => 41", 80, 1, 500, 1 );
per3 = Param( "Period id_3 => 42", 110, 1, 500, 1 );
per4 = Param( "Period id_4 => 43", 150, 1, 500, 1 );
per5 = Param( "Period id_5 => 44", 210, 1, 500, 1 );

cid = NumToStr( GetChartID() ) + "ProgramName";

id_1 = 40;
id_2 = 41;
id_3 = 42;
id_4 = 43;
id_5 = 44;
GuiSetFont( FontType, FontPointsize );

id0 = GuiGetEvent( 0, 0 );
id1 = GuiGetEvent( 0, 1 ); // returns notify flag (1 ==> click event)
clickevent = id1 == 1;

x0 = transx;
y0 = transy;
GfxSelectSolidBrush( ButtonclrBack );
pp = 0;
nn = 1;

for( i = id_1; i <= id_5; i++ )
{
    GuiRadio( "Radio " + i, i, x0 + ( CellWidth + CellXSpace ) * ( Nz( StaticVarGet( "Column" + cid ) ) + 0 ), y0 + ( CellHeight + CellYSpace ) * ( Nz( StaticVarGet( "Row" + cid ) ) + nn ), CellWidth, CellHeight, 1 );
    x1 = x0 + ( CellWidth + CellXSpace ) * ( Nz( StaticVarGet( "Column" + cid ) ) + 0 ) - rm;
    y1 = y0 + ( CellHeight + CellYSpace ) * ( Nz( StaticVarGet( "Row" + cid ) ) + nn ) - ( CellYSpace + 0 );
    x2 = x1 + CellWidth + rm;
    y2 = y1 + CellHeight + ( CellYSpace + 0 );
    x3 = 0;
    y3 = 0;
    GfxRoundRect( x1, y1, x2, y2, x3, y3 );

    if( i == id_1 )
    {
        xmin = x1 - BorderWidth;
        ymin = y1 - BorderWidth;
    }

    if( i == id_5 )
    {
        xmax = x2 + BorderWidth;
        ymax = y2 + BorderWidth;
    }

    nn++;
}

// at startup or reset
if( Nz( StaticVarGet( "startval" ) ) == 0 )
{
    prevcheck = 0;

    for( i = id_1; i <= id_5; i++ )
    {
        if( Nz( StaticVarGet( "StaticGuiGetCheck" + cid + i ) ) == 1 )
        {
            GuiSetCheck( i, 1 );
            prevcheck = 1;
        }
        else
        {
            GuiSetCheck( i, 1 );
        }
    }

    if( prevcheck == 0 )
    {
        GuiSetCheck( id_1, 1 );
        StaticVarSet( "StaticGuiGetCheck" + cid + id_1, 1, 1 );
    }

    Say( "startup" );

    StaticVarSet( "startval", 1 );

    // if column and row not already set at startup then set both to 0
    if( Nz( StaticVarGet( "Column" + cid ) ) == 0 )
    {
        StaticVarSet( "Column" + cid, 0, 1 );
    }

    if( Nz( StaticVarGet( "Row" + cid ) ) == 0 )
    {
        StaticVarSet( "Row" + cid, 0, 1 );
    }
}

if( reset == 1 )
{
    StaticVarSet( "Column" + cid, 0, 1 );
    StaticVarSet( "Row" + cid, 0, 1 );

    Say( "Reset Button Pack Position" );
    RequestTimedRefresh( 0.1 ); // force chart refresh
}

// radio button toggle
if( clickevent )
{
    for( i = id_1; i <= id_5; i++ )
    {
        if( i == id0 )
        {
            GuiSetCheck( i, 1 );
            StaticVarSet( "StaticGuiGetCheck" + cid + i, 1, 1 );
            Say( "set radio button number" + i );
        }
        else
        {
            GuiSetCheck( i, 0 );
            StaticVarSet( "StaticGuiGetCheck" + cid + i, 0, 1 );
        }
    }
}

// set radio button at each refresh (possibly no longer needed in next beta)
for( i = id_1; i <= id_5; i++ )
{
    GuiSetCheck( i, Nz( StaticVarGet( "StaticGuiGetCheck" + cid + i ) ) );
}

function OnLMouseButton( px, py )
{
    //Say( "set initial px and py" );
    StaticVarSet( "startpx" + cid, px );
    StaticVarSet( "startpy" + cid, py );
}

function OnLButtonIsDown( px, py )
{
    Col0 = StaticVarGet( "Column" + cid );
    Row0 = StaticVarGet( "Row" + cid );

    spx = StaticVarGet( "startpx" + cid );
    spy = StaticVarGet( "startpy" + cid );

    dpx = ( px - spx );
    dpy = ( py - spy );

    dCol = ( dpx / CellWidth );
    dRow = ( dpy / CellHeight );

    StaticVarSet( "Column" + cid,  Max( 0, ( dCol + Col0 ) ), 1 );
    StaticVarSet( "Row" + cid, Max( 0, ( dRow + Row0 ) ), 1 );

    StaticVarSet( "startpx" + cid, px );
    StaticVarSet( "startpy" + cid, py );

    GfxSetZOrder( -5 );
    GfxSelectSolidBrush( ColorRGB( 20, 20, 50 ) );
    GfxRoundRect( xmin, ymin, xmax, ymax, 0, 0 );
    GfxSelectPen( colorLightBlue, 2 );
    GfxPolyline( xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin );
    GfxSetZOrder( 0 );
}

function OnHoverMouse( px, py )
{
    GfxSetZOrder( -5 );
    GfxSelectSolidBrush( ColorRGB( 10, 15, 10 ) );
    GfxRoundRect( xmin, ymin, xmax, ymax, 0, 0 );
    GfxSelectPen( colorGreen, 2 );
    GfxPolyline( xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin );
    GfxSetZOrder( 0 );
}

function EventHandler()
{
    b = GetCursorMouseButtons();
    px = GetCursorXPosition( 1 );
    py = GetCursorYPosition( 1 );

    if( px > xmin AND px < xmax AND py > ymin AND py < ymax )
    {
        if( b & 8 )
        {
            if( b & 1 ) OnLMouseButton( px, py );
        }
        else
        {
            if( b == 0 )
            {
                OnHoverMouse( px, py );

                // settle button pack to the nearest Row and Column
                StaticVarSet( "Column" + cid, round( StaticVarGet( "Column" + cid ) ), 1 );
                StaticVarSet( "Row" + cid, round( StaticVarGet( "Row" + cid ) ), 1 );
                //_TRACE("px: " + px + " py: " + py );
            }

            if( b == 1 ) OnLButtonIsDown( px, py );
        }
    }
}

EventHandler();

GraphXSpace = 5;
SetChartBkColor( ColorBlack );
SetChartOptions( 0, chartShowDates );
SetBarFillColor( IIf( C > O, ColorRGB( 0, 75, 0 ), IIf( C <= O, ColorRGB( 75, 0, 0 ), colorLightGrey ) ) );
Plot( C, "", IIf( C > O, ColorRGB( 0, 250, 0 ), IIf( C <= O, ColorRGB( 250, 0, 0 ), colorLightGrey ) ), 64, Null, Null, 0, 0, 1 );

for( i = id_1; i <= id_5; i++ )
{
    gc = GuiGetCheck( i );

    if( gc == 1 AND i == 40 )
    {
        pp = per1;
    }

    if( gc == 1 AND i == 41 )
    {
        pp = per2;
    }

    if( gc == 1 AND i == 42 )
    {
        pp = per3;
    }

    if( gc == 1 AND i == 43 )
    {
        pp = per4;
    }

    if( gc == 1 AND i == 44 )
    {
        pp = per5;
    }
}

if( pp > 0 )
    Plot( MA( C, pp ), "", colorYellow, styleLine | styleNoRescale, Null, Null, 0, 0, 1 );

Title = "Test Code [ Move Button Pack ]";

#55

Tomasz or anybody else

Would you please provide a real life example of the following new feature. I am sure you had something in mind when you added this feature.

AFL: New feature: Passing arguments as reference (allows modification of arguments passed - easy way to return multiple values), to pass by reference use & (address-of) operator before variable identifier
Reference is actually a pointer to (address of) the variable. If it is passed to function it allows original variable to be modified.
The difference between AFL and C language is that while you are using address-of operator when you call function,
you don’t need any special syntax in the function itself. This has advantage that same function can be called with arguments passed by value and by reference
and which one is used is just directed by the way you call the function. AFL automatically and transparently knows that it needs to dereference addresses when
references are used in aritmetic operations, function calls or assignments.


#56

Examples are upper in this thread.


#57

I have seen them, I was hoping for an example that applies to trading. I am trying to see how I can take advantage of this feature. Sort of before & after example.


#58

The advantage is: possible better organization of your code. There is also other thing that I had in mind but this is left for the future.