Knowledge Base - How to show thumbnail gridView

This article shows how to add PDFVGrid implementation in PDFV class:

in PDFV.h add the interface:

@interface PDFVGrid: PDFV
{
    int m_grid_mode;
    int m_element_height;
    int m_orientation;
    int m_sel;
    bool m_rtol;
}
-(id)init:(int)orientation :(bool)rtol;
-(id)init:(int)orientation :(bool)rtol :(int)height :(int)gridMode;
-(void)vOpen:(PDFDoc *) doc :(int)page_gap :(id<PDFVInnerDel>)notifier :(const struct PDFVThreadBack *)disp;
-(void)vClose;
-(void)vLayout;
-(void)vDraw:(PDFVCanvas *)canvas :(bool)zooming;
-(void)vSetSel:(int)pageno;
-(int)vGetSel;
-(void)vRenderAsync:(int)pageno;
-(void)vRenderSync:(int)pageno;
@end

Then add the implementation in PDFV.m

@implementation PDFVGrid
-(id)init:(int)orientation :(bool)rtol
{
    return [self init:orientation :rtol :0 :0];
}
 
-(id)init:(int)orientation :(bool)rtol :(int)height :(int)gridMode
{
    if( self = [super init] )
    {
        m_orientation = orientation;
        m_rtol = rtol;
        m_element_height = height;
        m_grid_mode = gridMode;
        if (orientation == 2) {
            m_sel = -1;
        }
        
        if( rtol && orientation == 0 ) m_x = 0x7FFFFFFF;
    }
    return self;
}
 
-(void)vOpen:(PDFDoc *)doc : (int)page_gap :(id<PDFVInnerDel>)notifier :(const struct PDFVThreadBack *)disp
{
    [super vOpen :doc :page_gap :notifier :disp];
    if( m_rtol && (m_orientation == 0 || m_orientation == 2) ) m_x = 0x7FFFFFFF;
}
 
-(void)vClose
{
    [super vClose];
    m_sel = 0;
}
 
-(void)vLayout
{
    if( m_doc == NULL || m_w <= m_page_gap || m_h <= m_page_gap ) return;
    int cur = 0;
    int cnt = [m_doc pageCount];
    PDF_SIZE sz = [m_doc getPagesMaxSize];
    
    m_scale_min = (((float)(m_element_height)) / sz.cy);
    m_scale_max = m_scale_min * g_zoom_level;
    m_scale = m_scale_min;
    
    float elementWidth = (sz.cx * m_scale);
    int cols;
    
    switch (m_grid_mode) {
        case 0:
            cols = (m_w / (elementWidth + m_page_gap)); //full screen
            break;
        case 1:
            cols = m_w / ((elementWidth + m_page_gap ) * 2); //justify center
            break;
        default:
            cols = (m_w / (elementWidth + m_page_gap)); //full screen
            break;
    }
    
    float gap = (m_w - ((cols * elementWidth) + (m_page_gap * (cols - 1)))) / 2;
 
    int left = gap;
    int top = m_page_gap / 2;
    cur = 0;
    m_docw = 0;
    m_doch = 0;
    
    while( cur < cnt )
    {
        for (int i = 0; i < cols; i++) {
            if (cur >= cnt) break;
            PDFVPage *vpage = m_pages[cur];
            [vpage SetRect :left: top: m_scale];
            left += [vpage GetWidth] + m_page_gap;
            if( m_doch < [vpage GetHeight] ) m_doch = [vpage GetHeight];
            cur++;
        }
        
        left = gap;
        top += m_page_gap + (sz.cy * m_scale);
        m_doch = top + (sz.cy * m_scale);
    }
    m_docw = m_w;
}
 
-(int)vGetPage:(int) vx :(int) vy
{
    if( !m_pages || m_pages_cnt <= 0 ) return -1;
    
    int left = 0;
    int right = m_pages_cnt - 1;
    int x = m_x + vx;
    int y = m_y + vy;
    int gap = m_page_gap>>1;
    
    while( left <= right )
    {
        int mid = (left + right)>>1;
        PDFVPage *pg1 = m_pages[mid];
        
        if (y < ([pg1 GetY] - gap))
        {
            right = mid - 1;
        }
        else if(y > ([pg1 GetY] + [pg1 GetHeight] + gap))
        {
            left = mid + 1;
        }
        else
        {
            if( x < [pg1 GetX] )
            {
                right = mid - 1;
            }
            else if( x > [pg1 GetX] + [pg1 GetWidth] + gap )
            {
                left = mid + 1;
            }
            else
            {
                return mid;
            }
        }
    }
    if( right < 0 ) return 0;
    //else if(left > 0 && left < m_pages_cnt) return left;
    else return m_pages_cnt - 1;
}
 
-(void)vFlushRange
{
    PDF_SIZE sz = [m_doc getPagesMaxSize];
    float elementWidth = (sz.cx * m_scale);
    int cols;
    switch (m_grid_mode) {
        case 0:
            cols = (m_w / (elementWidth + m_page_gap)); //full screen
            break;
        case 1:
            cols = m_w / ((elementWidth + m_page_gap ) * 2); //justify center
            break;
        default:
            cols = (m_w / (elementWidth + m_page_gap)); //full screen
            break;
    }
    float gap = (m_w - ((cols * elementWidth) + (m_page_gap * (cols - 1)))) / 2;
    gap += 5;
    
    int pageno1 = [self vGetPage: gap :0];
    int pageno2 = [self vGetPage:m_w - gap :m_h];
    if( pageno1 >= 0 && pageno2 >= 0 )
    {
        if( pageno1 > pageno2 )
        {
            int tmp = pageno1;
            pageno1 = pageno2;
            pageno2 = tmp;
        }
        pageno2++;
        if( m_prange_start < pageno1 )
        {
            int start = m_prange_start;
            int end = pageno1;
            if( end > m_prange_end ) end = m_prange_end;
            while( start < end )
            {
                [m_thread end_thumb: m_pages[start]];
                start++;
            }
        }
        if( m_prange_end > pageno2 )
        {
            int start = pageno2;
            int end = m_prange_end;
            if( start < m_prange_start ) start = m_prange_start;
            while( start < end )
            {
                [m_thread end_thumb:m_pages[start]];
                start++;
            }
        }
    }
    else
    {
        int start = m_prange_start;
        int end = m_prange_end;
        while( start < end )
        {
            [m_thread end_thumb:m_pages[start]];
            start++;
        }
    }
    m_prange_start = pageno1;
    m_prange_end = pageno2;
    pageno1 = [self vGetPage:m_w/4:m_h/4];
    if( m_del && pageno1 != m_pageno )
    {
        [m_del OnPageChanged:m_pageno = pageno1];
    }
}
 
-(void)vDraw:(PDFVCanvas *)canvas :(bool)zooming
{
    if( m_w <= 0 || m_h <= 0 || !m_doc ) return;
    [self vFlushRange];
    int cur = m_prange_start;
    int end = m_prange_end;
    
    //NSTimeInterval time1 = [[NSDate date] timeIntervalSince1970]*1000;
    //[canvas FillRect:CGRectMake(0, 0, m_w, m_h) :m_back_clr];
    while( cur < end )
    {
        PDFVPage *vpage = m_pages[cur];
        [m_thread start_thumb:vpage];
        [vpage DrawThumb:canvas];
        cur++;
    }
    
    if( m_del )
    {
        cur = m_prange_start;
        end = m_prange_end;
        while( cur < end )
        {
            PDFVPage *vpage = m_pages[cur];
            [m_del OnPageDisplayed:[canvas context]:vpage];
            cur++;
        }
    }
}
-(void)vSetSel:(int)pageno
{
    if( !m_doc ) return;
    if( pageno >= 0 && pageno < [m_doc pageCount] )
        m_sel = pageno;
}
-(int)vGetSel
{
    return m_sel;
}
 
-(void)vRenderAsync:(int)pageno
{
    [m_thread end_thumb:m_pages[pageno]];
    [m_thread start_thumb:m_pages[pageno]];
}
 
-(void)vRenderSync:(int)pageno
{
    [m_thread end_thumb:m_pages[pageno]];
    [m_pages[pageno] ThumbPrepare];
    [[m_pages[pageno] Thumb] Render];
}
 
@end

Now, you can create the grid var (PDFThumbView *m_Gridview;) and add methods to show/hide the gridview in RDPDFViewController:

- (void)showGridView
{
    if (!m_Gridview) {
        CGRect frame = self.view.frame;
        m_Gridview = [[PDFThumbView alloc] initWithFrame:CGRectMake(0, [[UIApplication sharedApplication] statusBarFrame].size.height + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - [[UIApplication sharedApplication] statusBarFrame].size.height + self.navigationController.navigationBar.frame.size.height)];
        [m_Gridview vOpen:m_doc :(id<PDFThumbViewDelegate>)self mode:1];
        
        [self.view addSubview:m_Gridview];
    } else {
        [self hideGridView];
    }
}
 
- (void)hideGridView
{
    if(m_Gridview) {
        [m_Gridview removeFromSuperview];
        [m_Gridview vClose];
        m_Gridview = nil;
    }
}

In PDFThumbView class modify the vOpen and add the mode param:

-(void)vOpen:(PDFDoc *)doc :(id<PDFThumbViewDelegate>)delegate mode:(int)mode

Then add the mode check:

if (mode == 0) {
        m_view = [[PDFVThmb alloc] init:0:false];
    } else {
        m_view = [[PDFVGrid alloc] init:mode:false :100 * m_scale :0];
    }

If you don't want to modify the current vopen call for thumbnails, you can add another vopen method that doesn't use the mode param.

The implementation in PDFThumbView class should be something like:

-(void)vOpen:(PDFDoc *)doc :(id<PDFThumbViewDelegate>)delegate
{
    [self vOpen:doc :delegate mode:0];
}
 
-(void)vOpen:(PDFDoc *)doc :(id<PDFThumbViewDelegate>)delegate mode:(int)mode
{   
    //GEAR
    [self vClose];
    //END
    m_doc = doc;
    
    if (mode == 0) {
        m_view = [[PDFVThmb alloc] init:0:false];
    } else {
        m_view = [[PDFVGrid alloc] init:mode:false :100 * m_scale :0];
    }
    
    m_delegate = delegate;
......

In this case, the thumbnail height is 100, but you can customize that value as your requirements.

 

Applies To

RadaeePDF SDK for iOS

Details

Created : 2018-06-06 09:54:58, Last Modified : 2018-06-06 10:01:10