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
Trusted Contributor
cjonesy
Posts: 160
Registered: ‎09-13-2012
My Device: 9900

Where to begin to pan/zoom with native screen

Hi all,

 

I'm wanting to zoom into a native screen, are there any code samples or anyone have any advice or suggestions to help me acheive this goal please? I'm ok with understanding how to catch the events but what to do after that is blank to me right now.

 

I've searched native forum for zoom only and the 5 results are irrelevent.

 

Thank you.

Trusted Contributor
cjonesy
Posts: 160
Registered: ‎09-13-2012
My Device: 9900

Re: Where to begin to pan/zoom with native screen

Sorry I don't think I have provided enough information in my last post, I am blitting ffmpeg video image data to native screen_window_t currently and it is working ok, the code is below. Going off the lack of samples or posts about this in native seach I am think the code below is where I would start.

 

if(got_frame)
		{
			int rc;
			printf("got frame \n");
			fflush( stdout );
			uint8_t *srcy = decodedFrame->data[0];
			uint8_t *srcu = decodedFrame->data[1];
			uint8_t *srcv = decodedFrame->data[2];
			printf("got src yuv frame \n");
			fflush( stdout );
			unsigned char *ptr = NULL;
			screen_get_buffer_property_pv(externalbuffer, SCREEN_PROPERTY_POINTER, (void**) &ptr);
			unsigned char *y = ptr;
			unsigned char *u = y + (600 * stride);
			unsigned char *v = u + (600 * stride) / 4;
			int i = 0;
			for ( i = 0; i < 600; i++)
			{
				int doff = i * stride;
				int soff = i * decodedFrame->linesize[0];
				memcpy(&y[doff], &srcy[soff], 1024);
			}

			for ( i = 0; i < 600 / 2; i++)
			{
				int doff = i * stride / 2;
				int soff = i * decodedFrame->linesize[1];
				memcpy(&u[doff], &srcu[soff], 1024 / 2);
			}

			for ( i = 0; i < 600 / 2; i++)
			{
				int doff = i * stride / 2;
				int soff = i * decodedFrame->linesize[2];
				memcpy(&v[doff], &srcv[soff], 1024 / 2);
			}

			screen_buffer_t screen_buffer;
			rc = screen_get_window_property_pv(externalscreen, SCREEN_PROPERTY_RENDER_BUFFERS, (void**) &screen_buffer);
			printf("after render buffers %i \n", rc);
			fflush( stdout );
			int attribs[] = { SCREEN_BLIT_SOURCE_WIDTH, 1024, SCREEN_BLIT_SOURCE_HEIGHT, 600, SCREEN_BLIT_END };
			rc = screen_blit(externalscreencontext, screen_buffer, externalbuffer, attribs);
			printf("after blit %i \n", rc);
			fflush( stdout );
			int dirty_rects[] = { 0, 0, 1024, 600 };
			rc = screen_post_window(externalscreen, screen_buffer, 1, dirty_rects, 0);
			

 

Trusted Contributor
cjonesy
Posts: 160
Registered: ‎09-13-2012
My Device: 9900

Re: Where to begin to pan/zoom with native screen

[ Edited ]

I have found the gestures samples and have been using that as a reference to help have my video include pinch to zoom functionality.

 

It seems I don't fully understand the sample although I am pretty sure I have read it carefully. The write up for this sample doesnt seem to give any detail about min size and max size.

 

What I need to happen when the pinch/ zoom in occurs is the area where I zoom in I need to become more in the centre of the screen.

 

Also when I zoom back out, how do i ensure that it only scrolls out to how it was originally along the same point? (at the moment my screen can go all over the place but other apps seem to have a nice zoom in/out going on).

 

I have posted my code below which is basically the same as the sample - I'm hoping somebody has implemented this already and would share how it's done.

 

struct gestures_set * set;
int viewport_pos[2] = { 0, 0 };
int viewport_size[2] = { 0, 0 };
int last_touch[2] = { 0, 0 };
#define MIN_VIEWPORT_SIZE 128
#define MAX_VIEWPORT_SIZE 4096



/**
 * The callback invoked when a gesture is recognized or updated.
 */
void
gesture_callback(gesture_base_t* gesture, mtouch_event_t* event, void* param, int async)
{
    if (async) {
        fprintf(stderr,"[async] ");
    }
    switch (gesture->type) {
        case GESTURE_TWO_FINGER_PAN: {
            gesture_tfpan_t* tfpan = (gesture_tfpan_t*)gesture;
            fprintf(stderr,"Two finger pan: %d, %d", (tfpan->last_centroid.x - tfpan->centroid.x), (tfpan->last_centroid.y - tfpan->centroid.y));
            if (tfpan->last_centroid.x && tfpan->last_centroid.y) {
              viewport_pos[0] += (tfpan->last_centroid.x - tfpan->centroid.x) >> 1;
              viewport_pos[1] += (tfpan->last_centroid.y - tfpan->centroid.y) >> 1;
            }
            break;
        }
        case GESTURE_PINCH: {
            gesture_pinch_t* pinch = (gesture_pinch_t*)gesture;
            fprintf(stderr,"Pinch %d, %d", (pinch->last_distance.x - pinch->distance.x), (pinch->last_distance.y - pinch->distance.y));

            int dist_x = pinch->distance.x;
            int dist_y = pinch->distance.y;
            int last_dist_x = pinch->last_distance.x;
            int last_dist_y = pinch->last_distance.y;

            int reldist = sqrt((dist_x)*(dist_x) + (dist_y)*(dist_y));
            int last_reldist = sqrt((last_dist_x)*(last_dist_x) + (last_dist_y)*(last_dist_y));

            if (reldist && last_reldist) {
                viewport_size[0] += (last_reldist - reldist) >> 1;
                viewport_size[1] += (last_reldist - reldist) >> 1;

                /* Size restrictions */
                if (viewport_size[0] < MIN_VIEWPORT_SIZE) {
                    viewport_size[0] = MIN_VIEWPORT_SIZE;
                } else if (viewport_size[0] > MAX_VIEWPORT_SIZE) {
                    viewport_size[0] = MAX_VIEWPORT_SIZE;
                }
                if (viewport_size[1] < MIN_VIEWPORT_SIZE) {
                    viewport_size[1] = MIN_VIEWPORT_SIZE;
                } else if (viewport_size[1] > MAX_VIEWPORT_SIZE) {
                    viewport_size[1] = MAX_VIEWPORT_SIZE;
                }

                /* Zoom into center of image */
                if (viewport_size[0] > MIN_VIEWPORT_SIZE && viewport_size[1] > MIN_VIEWPORT_SIZE &&
                        viewport_size[0] < MAX_VIEWPORT_SIZE && viewport_size[1] < MAX_VIEWPORT_SIZE) {
                    viewport_pos[0] -= (last_reldist - reldist) >> 2;
                    viewport_pos[1] -= (last_reldist - reldist) >> 2;
                }
            }
            break;
        }

 

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Where to begin to pan/zoom with native screen

All you're really doing is modifying SCREEN_PROPERTY_SOURCE_POSITION and SCREEN_PROPERTY_SOURCE_SIZE of your video window.

Sounds like the code you posted (from gesture sample?) spits out viewport_pos and viewport_size... You should just be able to hook those into the properties I mentioned above.

max size is obviously your video window size, and min size will be however far you want to allow the user to zoom in.

 

Trusted Contributor
cjonesy
Posts: 160
Registered: ‎09-13-2012
My Device: 9900

Re: Where to begin to pan/zoom with native screen

[ Edited ]

Thanks Sean, thats what im doing hooking video_pos and video_size to SCREEN_PROPERTY_SOURCE_POSITION and SCREEN_PROPERTY_SOURCE_SIZE after handleScreenEvent() and then flushing screen context.

 

But my problem is if i zoom in - say top left of video is at 0,0 before zoom, I want it to go back to 0,0 when zoomed back out. Along the same trail. going back to the same res as well.

 

My video is 1024 x 600 so I don't want to see gaps when i zoom back out (I have tried disabling 2 finger pan to no avail). Splashtop remote has a good example of this.

 

I have again just tried to change min and max to 1024 & 600 and all I get is an horizontal zoom in then when zooming out I am left with a smaller screen when zooming out.

 

Is the sample meant to allow for my requirements as is? if not, is it a lot of work to implement do you think?

 

 

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Where to begin to pan/zoom with native screen

I can't speak to the fitness of the specific sample to your use case.  I do know that I used it as a starting point for implementing zoom & pan on a photo previously which worked the same way that it does in the picture-viewer app.

If you absolutely need to back out via some "historical" path, then you will need to record that path on the zoom-in, so that you can replay it backwards on the way out.  I'm not sure I understand that requirement though.. seems pretty odd.

 

Trusted Contributor
cjonesy
Posts: 160
Registered: ‎09-13-2012
My Device: 9900

Re: Where to begin to pan/zoom with native screen

Sean, let me try again to explain what i need as i don't think it's an odd requirement so i must be misunderstood.

 

If i zoom out too much or zoom out when not already zoomed in using the native pictures app it will automatically zoom back in until there is no gaps between the edge of the screen and the edge of the image. Nice.

 

If I zoom out again when not zoomed in using splashtop remote it won't move - again nice.

 

If I do the same with gestures app or with my app (gesture pinch/pan code) then I can zoom out TOO much which leaves me with a smaller video/image in the corner of the screen. I want it so if a zoom out occurs which is more than the original then it defaults to how it was before a zoom occurs - so the user doesnt end up with a tiny image.

 

I have tried changing the min and max but no help and I don't fully undertsand what they represent - the max width or max height? I have tried setting pos to 0 if it less than 0 at the end of gesture callback.

 

If someone has done zoom in native im pretty sure they would have implemented what i need to learn.

 

 

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Where to begin to pan/zoom with native screen

the zoom-out yielding a smaller-than-the-screen image is solely related to the MAX size from what I recall.  Note that if you are not dealing with a square screen and image, you will need an X min & max and a Y min & max, and will need to do appropriate clipping/nudging to ensure things stay aligned as you require.

Trusted Contributor
cjonesy
Posts: 160
Registered: ‎09-13-2012
My Device: 9900

Re: Where to begin to pan/zoom with native screen

What you just mentioned is timely - I set max to 600 and it's seems good for height but not for width - its stretches out very wide but the height stays at 600. If  I set it at 1024 the height is then the problem. Tried this many times but because you mention square image this time it makes sense.

 

looking at even native picture app and splashtop (the professionals!)  it seems there is a gap either side of the image which probably makes them both square images - I wonder if they have gone through this already and decided for the square image rather than the bump and nudge - is the res of the images in picture app shown as a square 600 x 600 or is it 800 x 600?

 

Regarding the other way nudging - I did actually set x and y max values earlier (setting them to video_size[0] and video_size[1] when required but didn't get far). The nudging/clipping is probably why - any links to learn or could you give a bit more on how to do that part please?

 

 

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Where to begin to pan/zoom with native screen

ok cool.  yah, pictures app is probably showing 800x600 for 4:3 images or 1024x576 for 16:9 images (actually, it'll be native resolution, so more like 2592x1944).

 

sorry, I don't have any links.. when I was implementing mine, I just sort of worked it out on paper.  I'm sure if you search the web, you'll find some math on the subject.

 

Cheers,

Sean