Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Highlighted
Developer
Posts: 163
Registered: ‎12-06-2012
My Device: Z10, Q10
My Carrier: BlackBerry

How to implement GRID/TILED Image View with scrolling in BB10

I want to implement GRID/TILED Image View where tile images will be drawn on the fly after being downloaded. I want to be able to do pinch/zoom and other touch actions in it. Say, If I pan the view, new tiles will be loaded and drawn on the view fully or partially. I couldn't find a way to do it with any existing UI control. Also those existing UI controls can not be subclassed and do not have any paint()/onDraw method (like view/canvas in android) to override. May be imageView with scrollview can solve the problem. The other option might be using foreign Window. In both cases I am not sure how they can be implemented or how gestures will be handled in those cases.Or if there any other way to do it. Please give me some insights to solve it.

Developer
Posts: 44
Registered: ‎05-22-2013
My Device: Blackberry 10
My Carrier: 02

Re: How to implement GRID/TILED Image View with scrolling in BB10

Hi,

 

I want to develop the same idera for an application.  I see you got a solution from stackoverflow; http://stackoverflow.com/questions/14009707/how-to-implement-grid-tiled-image-view-with-scrolling-in...

 

I am trying to follow it but having some problems. Please can you share the full source code, especially the header(.hpp) files.

 

Thank you.

 

Developer
Posts: 163
Registered: ‎12-06-2012
My Device: Z10, Q10
My Carrier: BlackBerry

Re: How to implement GRID/TILED Image View with scrolling in BB10

Hi.

I used opengl to draw the tiled images. I drew them on foreignwindow control. I modified the source code of GoodCitizenCascade sample project. The solution which was provided on stackoverflow was also a modified version of that sample project. You can try to understand it and modify it as you want. The source code that I modified is in here. Hope this helps you.

Developer
Posts: 889
Registered: ‎08-31-2009
My Device: 9530, 9630, 9800, 8530, 9900, 9810, 9930, PlayBook, Dev Alpha
My Carrier: Verizon

Re: How to implement GRID/TILED Image View with scrolling in BB10

First start with a ScrollView, then inside the ScrollView's contaier place another contair with a left to right layout for each row in the grid. Then add the containers that will hold the images. If you want to size the containers before the images are downloaded, just give them a minimum width and height. In order to add pinch to zoom support, and a PinchHandler as a getstureHandler control, and update the view whenever you get an event.

 

Also, just because there is no paint method doesn't mean that you can't subclass controls in Cascades. See details at https://developer.blackberry.com/cascades/documentation/ui/custom_components/


Read my thoughts on BlackBerry Development at news.ebscer.com
Developer
Posts: 44
Registered: ‎05-22-2013
My Device: Blackberry 10
My Carrier: 02

Re: How to implement GRID/TILED Image View with scrolling in BB10

Thank you for the quick response.

 

I feel openGL is too much for what I want. I want to implement a custom mapView(I have my own images for the map.),  where one can pinch to zoom in and out and also scroll as well.

 

In the link you included in your post. I downloaded the source and there is a class called MapTile but it is empty. Pls do you have the implementation or inside on how I can implement it..

Developer
Posts: 163
Registered: ‎12-06-2012
My Device: Z10, Q10
My Carrier: BlackBerry

Re: How to implement GRID/TILED Image View with scrolling in BB10

[ Edited ]

That class represents a single tile of the map. It contains all the infos about a single tile. It has the code for http request to download the image. It includes the render() method you see on GoodCitizen class to draw the downloaded image. Thats all it has in it Smiley Happy

Developer
Posts: 44
Registered: ‎05-22-2013
My Device: Blackberry 10
My Carrier: 02

Re: How to implement GRID/TILED Image View with scrolling in BB10

Thank you, I wil try implementing it. If I face any problems, I will get back to you. Smiley Happy

Developer
Posts: 44
Registered: ‎05-22-2013
My Device: Blackberry 10
My Carrier: 02

Re: How to implement GRID/TILED Image View with scrolling in BB10

I have develop and build my app. When I launch the app on my device, I get a black screen with BB logo. Pls any help will do.

 

 

i am having the above debug device log when i debug my app. pls any idea on how to go about this

 

source code below.

 

// Default empty project template
#include "applicationui.hpp"

#include "CustomMapView.hpp"
#include "CustomMapViewProvider.hpp"

#include <bb/cascades/QmlDocument>
#include <bb/cascades/Page>

//#include <bb/cascades/Application>
//#include <bb/cascades/QmlDocument>
//#include <bb/cascades/AbstractPane>

using namespace bb::cascades;

ApplicationUI::ApplicationUI(bb::cascades::Application *app)
: QObject(app)
{
    // create scene document from main.qml asset
    // set parent to created document to ensure it exists for the whole application lifetime
	qmlRegisterType < CustomMapView > ("my.library", 1, 0, "CustomMapView");
	qmlRegisterType < CustomMapViewProvider > ("my.library", 1, 0, "CustomMapViewProvider");
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);

    // create root object for the UI
    if (!qml->hasErrors()) {

        // Create the application Page from QMLDocument.
        Page *appPage = qml->createRootObject<Page>();

        if (appPage) {
            // Set the main scene for the application to the Page.
            Application::instance()->setScene(appPage);
        }
    }
}

 CustomMapView.cpp

 

#include "CustomMapView.hpp"
#include "WebServiceRequest.hpp"

#include <bb/cascades/AbsoluteLayout>
#include <bb/cascades/Container>
#include <bb/cascades/DockLayout>
#include <bb/cascades/ImageView>
#include <bb/cascades/TouchEvent>

using namespace bb::cascades;


CustomMapView::CustomMapView(Container *parent) :
		CustomControl(parent)
{
	// create the root container for our map
	m_rootContainer =  new Container();
	m_rootContainer->setLayout(new DockLayout);

	// Create item image for each grid
	m_itemImage = ImageView::create();
	m_itemImage->setHorizontalAlignment(HorizontalAlignment::Fill);
	m_itemImage->setVerticalAlignment(VerticalAlignment::Fill);

	m_rootContainer->add(m_itemImage);

	setRoot(m_rootContainer);

}

/**
 * updateItem, updates map item(grid).
 * It makes a request from the service provider.
 * The Service provider to gets the image and calls onComplete() if successful.
 */
void CustomMapView::updateItem(const QString imagePath)
{
	WebServiceRequest *webServicerequest = new WebServiceRequest(imagePath);

	connect(webServicerequest, SIGNAL(complete(QByteArray, bool)), this,
						SLOT(onComplete(QByteArray data, bool success)));

	webServicerequest->getResponse();
}


void CustomMapView::onComplete(QByteArray data, bool success)
{
	if (success) {
		m_itemImage->setImage(Image(data));
		m_itemImage->setVisible(true);
	} else {
		qDebug() << "Image request failed";
	}
}

void CustomMapView::select(bool select){
	// When an item is selected show the colored highlight Container
	Q_UNUSED(select);
}

void CustomMapView::reset(bool selected, bool activated)
{
	Q_UNUSED(activated);
	Q_UNUSED(selected);
	m_itemImage->setVisible(false);
}

void CustomMapView::activate(bool activate){
	// There is no special activate state, select and activated looks the same.
	select(activate);
}

/*CustomMapView::~CustomMapView() {
	// TODO Auto-generated destructor stub
}*/

 CustomMapViewProvider

#include "CustomMapViewProvider.hpp"
#include "CustomMapView.hpp"

using namespace bb::cascades;

CustomMapViewProvider::CustomMapViewProvider() {

}

//CustomMapViewProvide::~CustomMapViewProvide() {
//	// TODO Auto-generated destructor stub
//}

VisualNode * CustomMapViewProvider::createItem(ListView* list,
		const QString &type) {

	 Q_UNUSED(type);
	 Q_UNUSED(list);

	CustomMapView *customMapView = new CustomMapView();
	return customMapView;
}

void CustomMapViewProvider::updateItem(ListView* list,
        bb::cascades::VisualNode *listItem, const QString &type,
        const QVariantList &indexPath, const QVariant &data) {

	Q_UNUSED(type);
	Q_UNUSED(list);

	// Updates the map item control with correct data.
	QVariantMap map = data.value<QVariantMap>();
	CustomMapView *customMapView = static_cast<CustomMapView *>(listItem);

	qDebug() << indexPath;
	QString imagePath = map["path"].toString();

	// Call  the instance of our CustomContrlol MyItemClass and provide the data we want it to layout
	customMapView->updateItem(imagePath);
}

 

WebServiceRequest

 

#include "WebServiceRequest.hpp"

WebServiceRequest::WebServiceRequest(QString url)
{

	webServiceUrl = url;

}

WebServiceRequest::~WebServiceRequest() {
	// TODO Auto-generated destructor stub
}

void WebServiceRequest::getResponse()
{
	QNetworkAccessManager* netManager = new QNetworkAccessManager();
	if (!netManager) {
		qDebug() << "Unable to create QNetworkAccessManager";
		emit complete("Unable to create QNetworkAccessManager", false);
		return;
	}

	QUrl url(webServiceUrl);
	QNetworkRequest req(url);

	QNetworkReply* ipReply = netManager->get(req);
	connect(ipReply, SIGNAL(finished()), this, SLOT(onReply()));
}

void WebServiceRequest::onReply()
{
	QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
	QString response;
	bool success = false;
	if (reply) {
		if(reply->error() == QNetworkReply::NoError) {
			int available = reply->bytesAvailable();
			if (available > 0) {
				success = true;
				emit complete(reply->readAll(), success);
			}
		} else {
			response = QString("Error: ")
					+ reply->errorString()
					+ QString(" status:")
					+ reply->attribute(
							QNetworkRequest::HttpStatusCodeAttribute).toString();
		}

		reply->deleteLater();
	}
}

 

main.qml

import bb.cascades 1.0
import my.library 1.0 //Custom library where CustomImageView and our ListProvider resides

Page {
    content: ScrollView {
        gestureHandlers: [
            PinchHandler {
                onPinchUpdated: {
                    //scrollView.zoomToPoint(event.midPointX, event.midPointY, event.pinchRatio)
                }
            }
        ]
        id: scrollView
        scrollViewProperties {
            scrollMode: ScrollMode.None
            pinchToZoomEnabled: true

        }
        ListView {
            overlapTouchPolicy: OverlapTouchPolicy.Allow
            objectName: "listView"
            layout: GridListLayout {
                columnCount: 2
            }

            listItemProvider: CustomImageViewProvider { //Our list item provider
            }

            listItemComponents: [
                ListItemComponent {
                    CustomImageView { //CustomImageView to load image from remote via internet
                    }
                }
            ]

            dataModel: XmlDataModel {
                source: "images.xml"
            }
        }
    }

}

 

Developer
Posts: 1,008
Registered: ‎12-12-2010
My Device: Passport (Red Limited Edition)
My Carrier: Mobile Vikings

Re: How to implement GRID/TILED Image View with scrolling in BB10

I can't see the debug log, you may want to check that.

-------------------------------------------
BlackBerry Certified Builder for Native Application Development -- Proud member of the Belgian BlackBerry Developer group
Samples: Park in Ghent
Feeling generous? Nominate me for BB Elite member!
Developer
Posts: 44
Registered: ‎05-22-2013
My Device: Blackberry 10
My Carrier: 02

Re: How to implement GRID/TILED Image View with scrolling in BB10

The image was not attached. Also I noticed it is not possible to attach  attach an image. I have copied the important debug messages and paste here.

 

May 28 05:07:31.362     -----ONLINE-----        SHUTDOWN    <implicit>     com.example.mapTest.testDev_ple_mapTest2cdda51d.  50630885      0

May 28 05:07:53.162     CASCADES_BUILD::UNKNOWN     INFO        default        com.example.mapTest.testDev_ple_mapTest2cdda51d.  50630885      0   

May 28 05:07:53.227     [warn @ imf_properties.cpp:162 (tid:2-cascades-server)]: Null call back function request. Notification request ignored. WARNING default com.example.mapTest.testDev_ple_mapTest2cdda51d.50630885        0   

May 28 05:07:53.227    [emerg @ imf_vkb_helper.cpp:193 (tid:2-cascades-server)]: Cannot initiate global candidate selection service.  CRITICAL    default     com.example.mapTest.testDev_ple_mapTest2cdda51d.50630885  0
     

 Also a point to note, in main.qml "Problems loading my.library" and "images.xml" is not a supported asset file.