cancel
Showing results for 
Search instead for 
Did you mean: 

Not sure how to iterate through a list of child controls.

JimFouch
Associate III

I'm somewhat new to c/c++ programming. Come from 20+ years of experience with VB/VB.net and have mostly been spoon feed...lol

Anyway. I have a custom container that has a container with 19 children shapes. I need to interact with them at run-time.

the container is called ticks, and all the children widgets are of the shape type.

I see where I can use the forEachChild to iterate through all children.

Only problem is I have no idea how to use this and it returns an object of Drawable type that does not allow access to the shape's specific methods like setShape.

Does anyone have an example of how to use forEachChild?

7 REPLIES 7
JimFouch
Associate III

I was able to get some code to iterate through the collection of shape widgets. This code will work because all my child widgets are of the shape type.

I was still not able to access the color of the shape as it is a different object of a painter.

But this is a step in the right direction...

  // define tick shape...
  touchgfx::AbstractShape::ShapePoint<float> tickPoints[4] =
  { { radius, -tickWidth / 2 }, { radius - tickLength , -tickWidth / 2 },
  { radius - tickLength , tickWidth / 2 }, { radius, tickWidth / 2 } };
 
  Drawable* component; // place holder for whatever componet we're looking at
  Shape<4>* Tick;
 
  component = ticks.getFirstChild();
  while (component)
  {
    Tick = (Shape<4>*)component;
    Tick->setShape(tickPoints);
    Tick->setOrigin(center, center);
    Tick->setPosition(0, 0, value, value);
    Tick->setAngle(((float)currentRPM / scale) + 90.0f);
    currentRPM += 1000;
    component = Tick->getNextSibling();
  }
 
  tick0Painter.setColor(tickColor);
  tick1Painter.setColor(tickColor);
  tick2Painter.setColor(tickColor);
  tick3Painter.setColor(tickColor);
  tick4Painter.setColor(tickColor);
  tick5Painter.setColor(tickColor);
  tick6Painter.setColor(tickColor);
  tick7Painter.setColor(tickColor);
  tick8Painter.setColor(tickColor);
  tick9Painter.setColor(tickColor);
  tick10Painter.setColor(tickColor);
  tick11Painter.setColor(tickColor);
  tick12Painter.setColor(tickColor);
  tick13Painter.setColor(tickColor);
  tick14Painter.setColor(tickColor);
  tick15Painter.setColor(tickColor);
  tick16Painter.setColor(tickColor);
  tick17Painter.setColor(tickColor);
  tick18Painter.setColor(tickColor);
  tick19Painter.setColor(tickColor);

I've included what the widget (gauge) looks like at run-time.

I'm shooting for a dynamic widget that the user can set the size of the gauge at run-time. They also need to set the max limit of the gauge, hence the ability to control the ticks.

JimFouch
Associate III

Here's a video of what I got working.

I'm really impressed with TouchGFX. I've only been using it about 1-1/2 months and am finding it very powerful and flexible. Sure, it's not as straight forward or easy as desktop development in Visual Studio, but for something that is running on like 1/1000 of the hardware of a modern PC, it's pretty amazing.

 https://youtu.be/nkRsAZnrG_E

My goal is to have a UI where the end user can configure my device to work with their setup. I was going to have a PC app that connected to my device and have that application give them an interface to make changes. With the power of TouchGFX, I think I'm going to be able to pull this off completely on the device. That's a big deal as my market is not a technical market and th emore simple I can make it, the better.

Bob Bailey
Senior

The video looks nice, have you tried any of that on the 746-disco hardware, or your target? I am trying to determine if the F746 has enough capability to handle 800x480 for my project. It is difficult to really know without just coding it up and trying it.

I managed to get the CPU load calculation working, which is very revealing. The next step is to try some things to optimize the code and configuration.

Bob Bailey

I have not. I have both a 747 disco w/ a 800x480 and 746 Disco w/ a 480x272. My target will be an H743 running at 480Mhz.

I'm also interested to see how it performs. I have quite a few widgets I will need to run. I'm not sure if TouchGFX take full advantage of the the M4 or not. The H743 is a single core, so I hope it doesn't drop too much in performance.

Either way, I'm pretty much stuck with the H743 as my target for now. That may change as my product matures.

Was it hard to get the CPU meter working? I need to do that to keep things in check as I develop my application.

The load calculator logic looked to be complete. Based on the comments and errors it looks like it was switched from TIM2 to TIM1 at some point. I switched it back to TIM2 and used the initialization that Martin posted last summer. It works now and is *probably* accurate. I send the load calculation info out over CAN so I can watch it in real time while the screens are transitioning. Loading a PWM with it would also work for watching on a scope or logic analyzer.

this is the only change required to make it work :

void STM32F7Instrumentation::init()
{
    RCC_ClkInitTypeDef clkconfig;
    uint32_t uwTimclock, uwAPB1Prescaler = 0U;
    uint32_t pFLatency;
 
    // TIM2 initialization per an old post by Martin,
    // leaving the static struct named htim1 to minimize edits.  Points to TIM2
    __TIM2_CLK_ENABLE();
    htim1.Instance = TIM2;
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 0xFFFFFFFF;
    htim1.Init.Prescaler = 0;
    htim1.Init.RepetitionCounter = 1;
    HAL_TIM_Base_Init(&htim1);
 
    /* Get clock configuration */
    HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
 
    /* TIM2 is on APB1 bus */
    uwAPB1Prescaler = clkconfig.APB1CLKDivider;
 
    if (uwAPB1Prescaler == RCC_HCLK_DIV1)
        uwTimclock = HAL_RCC_GetPCLK1Freq();
    else
        uwTimclock = 2 * HAL_RCC_GetPCLK1Freq();
 
    m_sysclkRatio = HAL_RCC_GetHCLKFreq() / uwTimclock;
 
    HAL_TIM_Base_Start(&htim1);
}

I haven't double checked the clock source and ratio stuff.

ferro
Senior

Hi,

Step 1

class DoThisToEveryChild : public GenericCallback< Drawable & >
{
	virtual void execute ( Drawable & d ) final
	{
		// user code here e.g.
		// d.setVisible ( false );
	}
	
	virtual bool isValid () const final
	{
		return true;
	}
};

Step 2

DoThisToEveryChild doThis {};
 
// now 'DoThisToEveryChild::execute ()' will be called for every child in 'ticks' container
ticks.forEachChild ( & doThis );