From ccdd1996cb46a44d3cebbd94f7d189d5dc8696b1 Mon Sep 17 00:00:00 2001 From: JJones780 Date: Wed, 6 Feb 2019 15:22:29 -0700 Subject: [PATCH] LayoutMapper class to re-arrange page ordering. Initial mappings: Horizontal, Vertical, VerticalPaired. Issues: Unable to annotate all pages... other code ( PagePosition Handler etc?) must be assuming layout. --- src/gui/Layout.cpp | 149 ++++++++++++++++++++++++++++++++++++++- src/gui/Layout.h | 5 +- src/gui/LayoutMapper.cpp | 60 ++++++++++++++++ src/gui/LayoutMapper.h | 63 +++++++++++++++++ 4 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 src/gui/LayoutMapper.cpp create mode 100644 src/gui/LayoutMapper.h diff --git a/src/gui/Layout.cpp b/src/gui/Layout.cpp index 6624d831..66ba2f7a 100644 --- a/src/gui/Layout.cpp +++ b/src/gui/Layout.cpp @@ -6,6 +6,7 @@ #include "pageposition/PagePositionHandler.h" #include "widgets/XournalWidget.h" #include "gui/scroll/ScrollHandling.h" +#include "gui/LayoutMapper.h" Layout::Layout(XournalView* view, ScrollHandling* scrollHandling) @@ -189,6 +190,130 @@ const int XOURNAL_ROOM_FOR_SHADOW = 3; const int XOURNAL_PADDING_BETWEEN = 15; void Layout::layoutPages() +{ + this->layoutPagesUsingMapper(); +} + + + + +void Layout::layoutPagesUsingMapper() +{ + XOJ_CHECK_TYPE(Layout); + + int len = this->view->viewPagesLen; + + Settings* settings = this->view->getControl()->getSettings(); + bool verticalSpace = settings->getAddVerticalSpace(); + bool horizontalSpace = settings->getAddHorizontalSpace(); + bool dualPage = settings->isShowTwoPages(); + int columnSetting = settings->getViewColumns(); + int pairsOffset = settings->getPairsOffset(); + int pagesOffset = 0; + + if (!dualPage ) pairsOffset = 0; + + LayoutMapper mapper( len, columnSetting, false, pairsOffset, dualPage?LayoutType::VerticalPaired: LayoutType::Vertical ); + + pagesOffset = mapper.offset; + + int rows = mapper.r; + int columns = mapper.c; + + int sizeCol[columns]; + for ( int i =0; i< columns; i++){ sizeCol[i] = 0; } + + int sizeRow[rows]; + for ( int i =0; i< rows; i++){ sizeRow[i] = 0; } + + + for ( int r=0; r < rows; r++ ) + { + for ( int c=0; c < columns; c++ ) + { + int k = mapper.map(c,r); + if(k>=0){ + + XojPageView* v = this->view->viewPages[k]; + + if (sizeCol[c] < v->getDisplayWidth()) + { + sizeCol[c] = v->getDisplayWidth(); + } + if ( sizeRow[r] < v->getDisplayHeight()) + { + sizeRow[r] = v->getDisplayHeight(); + } + } + + } + } + + + int x = XOURNAL_PADDING; + int y = XOURNAL_PADDING; + for ( int r=0; r < rows; r++ ) + { + for ( int c=0; c < columns; c++ ) + { + int k = mapper.map(c,r); + if(k>=0){ + XojPageView* v = this->view->viewPages[k]; + int vDisplayWidth = v->getDisplayWidth(); + { + int paddingLeft; + int paddingRight; + int columnPadding = 0; + columnPadding = (sizeCol[c] - vDisplayWidth ); + + if (dualPage && len >1){ // dual page mode + if (c%2 == 0 ){ //align right + paddingLeft = XOURNAL_PADDING_BETWEEN - XOURNAL_ROOM_FOR_SHADOW + columnPadding; + paddingRight = XOURNAL_ROOM_FOR_SHADOW; + } + else{ //align left + paddingLeft = XOURNAL_ROOM_FOR_SHADOW; + paddingRight = XOURNAL_PADDING_BETWEEN - XOURNAL_ROOM_FOR_SHADOW + columnPadding; + } + } + else{ // not dual page mode - center + paddingLeft = XOURNAL_PADDING_BETWEEN/2 + columnPadding/2; //center justify + paddingRight = XOURNAL_PADDING_BETWEEN - paddingLeft + columnPadding/2; + } + + + x += paddingLeft; + + v->layout.setX(x); + v->layout.setY(y); + + x += sizeCol[c] + paddingRight; + + } + } + else + { + x += sizeCol[c] + XOURNAL_PADDING_BETWEEN; + } + } + x = XOURNAL_PADDING; + y+=sizeRow[r] + XOURNAL_PADDING_BETWEEN ; + + } + + int totalWidth = XOURNAL_PADDING *2 + XOURNAL_PADDING_BETWEEN * columns; + for ( int c =0; c< columns; c++){ totalWidth += sizeCol[c]; } + int totalHeight = XOURNAL_PADDING *2 + XOURNAL_PADDING_BETWEEN * rows; + for ( int r =0; r< rows; r++){ totalHeight += sizeRow[r]; } + + + this->setLayoutSize(totalWidth, totalHeight); + this->view->pagePosition->update(this->view->viewPages, len, totalHeight); + + +} + +void Layout::layoutPagesOriginal() { XOJ_CHECK_TYPE(Layout); @@ -204,9 +329,16 @@ void Layout::layoutPages() int columns = settings->getViewColumns(); int pairsOffset = settings->getPairsOffset(); int pagesOffset = 0; + + int rows = len + columns -1 / columns; + + int size[columns]; for ( int i =0; i< columns; i++){ size[i] = 0; } + + int sizeRow[rows]; + for ( int i =0; i< rows; i++){ sizeRow[i] = 0; } @@ -221,12 +353,18 @@ void Layout::layoutPages() { XojPageView* v = this->view->viewPages[i]; - int rId = (i+ pagesOffset) % columns; + int cId = (i+ pagesOffset) % columns; + int rId = (i+pagesOffset) / rows; - if (size[rId] < v->getDisplayWidth()) + if (size[cId] < v->getDisplayWidth()) { - size[rId] = v->getDisplayWidth(); + size[cId] = v->getDisplayWidth(); } + if ( sizeRow[rId] < v->getDisplayHeight()) + { + sizeRow[rId] = v->getDisplayHeight(); + } + } @@ -331,6 +469,11 @@ void Layout::layoutPages() this->view->pagePosition->update(this->view->viewPages, len, totalHeight); } + + + + + void Layout::setLayoutSize(int width, int height) { XOJ_CHECK_TYPE(Layout); diff --git a/src/gui/Layout.h b/src/gui/Layout.h index f3f03342..21eddf62 100644 --- a/src/gui/Layout.h +++ b/src/gui/Layout.h @@ -74,7 +74,10 @@ public: /** * Performs a layout of the XojPageView's managed in this Layout */ - void layoutPages(); + void layoutPages(); //calls one of the following two: + + void layoutPagesOriginal(); + void layoutPagesUsingMapper(); /** * Updates the current XojPageView. The XojPageView is selected based on diff --git a/src/gui/LayoutMapper.cpp b/src/gui/LayoutMapper.cpp new file mode 100644 index 00000000..fa38e5ef --- /dev/null +++ b/src/gui/LayoutMapper.cpp @@ -0,0 +1,60 @@ +#include "gui/LayoutMapper.h" + + +#define XYH( x,y,r,c,off) (( c * y + x) - off%c) +#define XYV( x,y,r,c,off) (( r* x + y) - off%r) +#define XYVP( x,y,r,c,off ) (((( y+ r* int(x/2))*2 + x%2 ) - off % 2) + + +#define MAX(A, B) ((A) > (B) ? (A) : (B)) + + +LayoutMapper::LayoutMapper( int pages, int rORc, bool isR , int off, LayoutType type ){ + + if(isR){ + r = MAX(1, rORc); + c = MAX(1, (pages + off + (rORc -1) )/rORc); // using + ( rORc-1) to round up (int)pages/rows + }else{ + c = MAX(1, rORc); + r = MAX(1, (pages + off + (rORc -1) )/rORc); + } + + layoutType = type; + switch ( type){ + case Horizontal: + offset = off % c; + break; + case Vertical: //vertical layout + offset = off % r; + break; + case VerticalPaired: + offset = off % (2*r); + break; + } + possiblePages = r * c; + rORc = rORc; + actualPages = pages; +} + + +int LayoutMapper::map(int x, int y){ + int res; + switch( layoutType) + { + case Horizontal: + res = (x + c * y); + break; + + case Vertical: //vertical layout + res = (y + r* x); + break; + + case VerticalPaired: + res = ((( y + r*( (int)(x/2) )) * 2 ) + x %2); + break; + } + res -= offset; + if( res>=actualPages) res = -1; + + return res; +} diff --git a/src/gui/LayoutMapper.h b/src/gui/LayoutMapper.h new file mode 100644 index 00000000..8b518280 --- /dev/null +++ b/src/gui/LayoutMapper.h @@ -0,0 +1,63 @@ +/* + * Xournal++ + * + * A layout manager - map where( row,column) to which page( document index) + * + * @author Justin Jones + * https://github.com/xournalpp/xournalpp + * + * @license GNU GPLv2 or later + */ + +#pragma once + +enum LayoutType { + Horizontal, + Vertical, + VerticalPaired, + //TODO: add in Right to Left mappings for other cultures (i.e. Japanese ) +}; + +/** + * @brief Allow different orderings of document pages in layout. + */ + +class LayoutMapper +{ + +public: + int c=0; + int r=0; + int rORc; + int actualPages=0; + int possiblePages=0; + int offset = 0; + LayoutType layoutType; + + + /** + * Initialize mapper of LayoutType with number of pages and of fixed rows or columns + * @param pages The number of pages in the document + * @param rORc Number of rows OR columns depending on boolean flag isR + * @param isR How to interpret rORc: True is rows + * @param off Pages to offset - usually one or zero in order to pair up properly + * @param type Specify LayoutType desired. Options include: Horizontal, Vertical, VerticalPaired + * + * @return Page index to put at coordinates + */ + LayoutMapper( int pages, int rORc, bool isR , int off, LayoutType type ); + + + + + /** + * Map page location to document index + * + * @param x Row we are interested in + * @param y Column we are interested in + * + * @return Page index to put at coordinates + */ + int map(int x, int y); + +};