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.
presentation
JJones780 7 years ago committed by JJones780
parent e92c65b4e1
commit ccdd1996cb
  1. 149
      src/gui/Layout.cpp
  2. 5
      src/gui/Layout.h
  3. 60
      src/gui/LayoutMapper.cpp
  4. 63
      src/gui/LayoutMapper.h

@ -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);

@ -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

@ -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;
}

@ -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);
};
Loading…
Cancel
Save