ASE Home Page Products Download Purchase Support About ASE
ChartDirector General
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Scrolling a chart on a panel with an image background in Windows
Posted by Rand on Mar-12-2020 04:27
First, a little background.  I generally develop for lab/industrial applications which have simple user interfaces and  intricate backends for data collection/storage in DB/flat file formats (usually both).  I know instrument and PLC communication protocols, database store, flat file formats, and etc. Until six months ago I had never drawn to a device context or had any knowledge of the specifics of any image formats.  In short, if I am doing something horribly wrong please let me know.

This application uses a background image for all panels and custom bitmaps for all controls.  In order to display any non-rectangualr controls I have to get the subbitmap that corresponds to the area of the background image behind the control and then draw that to a DC before drawing the custom bitmap of the control on top.  This seems to work well (scrolling is smooth).

When I use a nonrectangular ChartDirector object and set the background color transparent then the background is the default background color of the panel that the object is displayed on rather than showing through the background image.  That is the behavior of all of the other nonrectangualr widgets in this application so not surprising.  The meters are in viewports which should be roughly equivalent to CViewPortControl (I am using wxWidgets and wxChartDir wrapper from https://utelle.github.io/wxchartdir/ ).

Below is some pseudo code for creating the meter and later changing the meter background image in a scroll event.  The background image size and chart size never change after instantiation (full screen app which cannot be resized).  Is this a good approach or is there a more efficient way?  If the procedure takes too long users will notice stutter while scrolling.

const size_t width = 240;
const size_t height = 240;
struct PngImage
{
    char const* image;
    const size_t size;
    void Replace( char* new_img )
    {
        memcpy( image, new_img, size );
        delete[] new_img;
    }
    PngImage( char* buffer, size_t sz ) : image(buffer),size(sz){/*EMPTY*/}
};
// PngImage m_image_struct member initialized in ctor with buffer size of (width*height)
// Called in constructor after m_image_struct is initialized
MemBlock mem_block( m_image_struct.image, m_image_struct.size );
// Called from constructor
void CreateChart( MemBlock mem_block )
{
    m_meter = new AngularMeter( width, height, Chart::Transparent );
    char* img = GetBackgroundSubBitmap( chart_position );
    m_image_struct.Replace( img );
    m_meter->setResource( "background", mem_block );
    m_meter->setBackground( "@/background" );
    // ... do other chart setup
    ShowChart( m_meter->makeChart() );
}
void ScrollEvent()
{
    char* img = GetBackgroundSubBitmap( chart_position );
    img_struct.Replace( img2 );
    // Does the entire chart need to be redrawn or will the following work
    m_meter->setBackground( "@/background" ); // or have to redraw the entire chart?
    ShowChart( m_meter->makeChart() );
}

  Re: Scrolling a chart on a panel with an image background in Windows
Posted by Peter Kwan on Mar-12-2020 16:01
Hi Rand,

I am not familiar with wxWidgets myself. The following is a general method for any GUI framework.

First, please check if wxWidgets can support transparent images. You can test it by displaying a transparent PNG test image (just download a random one from the web) using the standard "image control". (Most GUI framework would have a control that can display static PNG images.) If it works, you can use that control to display the chart.

If the wxWidgets do not support transparency, the "copy background" method should be workable. Our own "Zooming and Scrolling" sample code achieves the scrolling just by redrawing the chart rapidly and it works OK. The most important thing is to manage the update frequency.

For your case, the code in the ScrollEvent is not necessary. It just need to call CreateChart to scroll.

For "managing the update frequency", see:

https://www.advsofteng.com/doc/cdcpp.htm#CChartViewer.setUpdateInterval.htm

If the above mechanism is also ported to wxChartViewer, you may try to use that mechanism to update the chart. (That is, the ScrollEvent can call "wxChartViewer::updateViewPort", and the chart is updated in the ViewPortChanged event handler.)

Hope this can help.

Regards
Peter Kwan