mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 22:02:58 -06:00
723 lines
19 KiB
C++
723 lines
19 KiB
C++
#include "PixRasterBaseCtrl.h"
|
|
#include "PixRasterCtrl.h"
|
|
|
|
NAMESPACE_UPP
|
|
|
|
#define BackColor SColorFace()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// constructor
|
|
PixRasterBaseCtrl::PixRasterBaseCtrl(PixRasterCtrl *t, bool hScroll, bool vScroll)
|
|
{
|
|
// connects to associated RasterCtrl
|
|
pixRasterCtrl = t;
|
|
|
|
// whether control has scrollbars
|
|
hasHScrollBar = hScroll;
|
|
hasVScrollBar = vScroll;
|
|
|
|
// adds scrollbar
|
|
if(hasHScrollBar)
|
|
{
|
|
AddFrame(hScrollBar.Horz());
|
|
hScrollBar <<= THISBACK(OnScroll);
|
|
}
|
|
if(hasVScrollBar)
|
|
{
|
|
AddFrame(vScrollBar.Vert());
|
|
vScrollBar <<= THISBACK(OnScroll);
|
|
}
|
|
|
|
// marks cache as invalid
|
|
imageCache.SetValid(false);
|
|
|
|
// no marker selected
|
|
selectedMarker = NULL;
|
|
highlightMarker = NULL;
|
|
dragPolygon.Clear();
|
|
|
|
} // END constructor class PixRasterBaseCtrl
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// destructor
|
|
PixRasterBaseCtrl::~PixRasterBaseCtrl()
|
|
{
|
|
} // END destructor class PixRasterBaseCtrl
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// converts a page and an array of page points into an array of view points
|
|
Vector<Point> PixRasterBaseCtrl::PointsToView(int page, Vector<Point> const &pts)
|
|
{
|
|
// gets the PixRaster object
|
|
PixBase *pixBase = pixRasterCtrl->GetPixBase();
|
|
|
|
// calculate view position inside the full tiff image
|
|
// in page coords
|
|
int viewLeft, viewTop;
|
|
if(hScrollBar.IsVisible())
|
|
viewLeft = ScaleToPage(hScrollBar.Get());
|
|
else
|
|
viewLeft = 0;
|
|
if(vScrollBar.IsVisible())
|
|
viewTop = ScaleToPage(vScrollBar.Get());
|
|
else
|
|
viewTop = 0;
|
|
|
|
// gets requested page position (in page coordinates)
|
|
int pageTop = 0;
|
|
int gapSize = ScaleToPage(10);
|
|
for(int i = 0; i < page; i++)
|
|
pageTop += pixBase->GetHeightEx(i) + gapSize;
|
|
|
|
// if page not visible, just return an empty array
|
|
int pageBottom = pageTop + pixBase->GetHeightEx(page);
|
|
int viewBottom = viewTop + ScaleToPage(GetSize().cy);
|
|
if(viewBottom < pageTop || viewTop > pageBottom)
|
|
return Vector<Point>();
|
|
|
|
// horizontal gap if page width < ctrl width
|
|
int viewWidth = ScaleToPage(GetSize().cx);
|
|
int pageWidth = pixBase->GetWidthEx(page);
|
|
int hGap;
|
|
if(pageWidth < viewWidth)
|
|
hGap = (viewWidth - pageWidth) / 2;
|
|
else
|
|
hGap = 0;
|
|
|
|
// calculates the offset of points in page coordinates
|
|
int dx = -viewLeft + hGap;
|
|
int dy = -viewTop + pageTop;
|
|
|
|
// creates the new array scaling the coordinates
|
|
Vector<Point>res(pts, 1);
|
|
for(int iPoint = 0; iPoint < res.GetCount(); iPoint++)
|
|
{
|
|
res[iPoint].x = ScaleToView(res[iPoint].x + dx);
|
|
res[iPoint].y = ScaleToView(res[iPoint].y + dy);
|
|
}
|
|
return res;
|
|
|
|
} // END PixRasterBaseCtrl::PointsToView()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// converts a view point into page + page point
|
|
bool PixRasterBaseCtrl::PointToPage(Point const &srcPt, int &page, Point &destPt)
|
|
{
|
|
if(!pixRasterCtrl)
|
|
return false;
|
|
|
|
// gets the PixRaster object
|
|
PixBase *pixBase = pixRasterCtrl->GetPixBase();
|
|
if(!pixBase || !pixBase->GetPageCount())
|
|
return false;
|
|
|
|
// gets point position in raster coordinates
|
|
int yPos = ScaleToPage(vScrollBar.Get() + srcPt.y);
|
|
|
|
// gets gap size between pages
|
|
int gapSize = ScaleToPage(10);
|
|
|
|
// iterates through page positions to find the requested one
|
|
int top = 0;
|
|
for(int iPage = 0; iPage < pixBase->GetPageCount(); iPage++)
|
|
{
|
|
int pageWidth = pixBase->GetWidthEx(iPage);
|
|
int pageHeight = pixBase->GetHeightEx(iPage);
|
|
int bottom = top + pageHeight;
|
|
|
|
if(yPos >= top && yPos <= bottom)
|
|
{
|
|
int xPos;
|
|
if(ScaleToView(pageWidth) >= GetSize().cx)
|
|
xPos = ScaleToPage(srcPt.x);
|
|
else
|
|
xPos = ScaleToPage(srcPt.x) - (ScaleToPage(GetSize().cx) - pageWidth) / 2;
|
|
if(xPos < 0 || xPos > pageWidth)
|
|
return false;
|
|
destPt = Point(xPos, yPos - top);
|
|
page = iPage;
|
|
return true;
|
|
}
|
|
top += pageHeight + gapSize;
|
|
}
|
|
|
|
} // END PixRasterBaseCtrl::PointToPage()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// left mouse button handlers
|
|
void PixRasterBaseCtrl::LeftDown(Point p, dword keyflags)
|
|
{
|
|
// translates mouse coordinate in page and page coordinates
|
|
int page;
|
|
Point pagePt;
|
|
if(!PointToPage(p, page, pagePt))
|
|
return;
|
|
|
|
// found a page on point, scan it to get the marker on it (if any)
|
|
|
|
// gets the PixRaster object
|
|
PixBase *pixBase = pixRasterCtrl->GetPixBase();
|
|
|
|
int minDist = ScaleToPage(5);
|
|
Markers *markers = pixBase->GetMarkersEx(page);
|
|
for(int i = 0; i < markers->GetCount(); i++)
|
|
{
|
|
Marker &marker = (*markers)[i];
|
|
int index;
|
|
Marker::HitKind hitKind = marker.Hit(pagePt, minDist, index);
|
|
if(hitKind == Marker::Miss)
|
|
continue;
|
|
|
|
// found a marker on cursor -- start drag op
|
|
dragPolygon = PointsToView(page, marker.DragOutline(pagePt, pagePt, minDist));
|
|
selectedMarker = ▮
|
|
dragPoint = pagePt;
|
|
dragPage = page;
|
|
}
|
|
|
|
|
|
} // END PixRasterBaseCtrl::LeftDown()
|
|
|
|
void PixRasterBaseCtrl::LeftUp(Point p, dword keyflags)
|
|
{
|
|
Point endDragPoint;
|
|
int endDragPage;
|
|
|
|
// if dragging a marker, stop and update it
|
|
if(selectedMarker)
|
|
{
|
|
int minDist = ScaleToPage(5);
|
|
PointToPage(p, endDragPage, endDragPoint);
|
|
// if dest point still on page, complete dragging op
|
|
// otherwise abort it
|
|
if(endDragPage == dragPage)
|
|
selectedMarker->Drag(dragPoint, endDragPoint, minDist);
|
|
selectedMarker = NULL;
|
|
pixRasterCtrl->Refresh();
|
|
}
|
|
|
|
} // END PixRasterBaseCtrl::LeftDown()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// right mouse button handlers
|
|
void PixRasterBaseCtrl::RightDown(Point p, dword keyflags)
|
|
{
|
|
|
|
} // END PixRasterBaseCtrl::RightDown()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// middle mouse button pan handlers
|
|
void PixRasterBaseCtrl::MiddleDown(Point p, dword keyflags)
|
|
{
|
|
panPoint = p;
|
|
panHScroll = hScrollBar.Get();
|
|
panVScroll = vScrollBar.Get();
|
|
|
|
} // END PixRasterBaseCtrl::MiddleDown()
|
|
|
|
void PixRasterBaseCtrl::MouseMove(Point p, dword keyflags)
|
|
{
|
|
Point endDragPoint;
|
|
int endDragPage;
|
|
|
|
if(!pixRasterCtrl || !pixRasterCtrl->GetPixBase())
|
|
return;
|
|
|
|
// check what we're dragging....
|
|
if(keyflags & K_MOUSEMIDDLE)
|
|
{
|
|
// moves with middle button pressed -- panning image
|
|
|
|
// gets distance between current and pan point
|
|
int dx = panPoint.x - p.x + panHScroll;
|
|
int dy = panPoint.y - p.y + panVScroll;
|
|
|
|
// gets max scrolling values
|
|
int hMax = hScrollBar.GetTotal();
|
|
int vMax = vScrollBar.GetTotal();
|
|
|
|
// sets new pan position
|
|
if(dx < 0) dx = 0;
|
|
if(dx > hMax) dx = hMax;
|
|
if(dy < 0) dy = 0;
|
|
if(dy > vMax) dy = vMax;
|
|
hScrollBar.Set(dx);
|
|
vScrollBar.Set(dy);
|
|
|
|
Refresh();
|
|
}
|
|
else if((keyflags & K_MOUSELEFT) && selectedMarker)
|
|
{
|
|
// dragging a marker
|
|
|
|
int minDist = ScaleToPage(5);
|
|
PointToPage(p, endDragPage, endDragPoint);
|
|
|
|
if(endDragPage == dragPage)
|
|
dragPolygon = PointsToView(dragPage, selectedMarker->DragOutline(dragPoint, endDragPoint, minDist));
|
|
else
|
|
dragPolygon.Clear();
|
|
pixRasterCtrl->Refresh();
|
|
}
|
|
else
|
|
{
|
|
// nothing else, just highlight marker under cursor
|
|
// and set the appropriate cursor
|
|
int page;
|
|
Point pagePt;
|
|
int minDist = ScaleToPage(5);
|
|
Marker *newMarker = NULL;
|
|
if(PointToPage(p, page, pagePt))
|
|
{
|
|
PixBase *pixBase = pixRasterCtrl->GetPixBase();
|
|
Markers *markers = pixBase->GetMarkersEx(page);
|
|
for(int iMarker = 0; iMarker < markers->GetCount(); iMarker++)
|
|
{
|
|
Marker &marker = (*markers)[iMarker];
|
|
int index;
|
|
if(marker.Hit(pagePt, minDist, index) != Marker::Miss)
|
|
{
|
|
newMarker = ▮
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(highlightMarker != newMarker)
|
|
{
|
|
highlightMarker = newMarker;
|
|
pixRasterCtrl->Refresh();
|
|
}
|
|
}
|
|
|
|
} // END PixRasterBaseCtrl::MouseMove()
|
|
|
|
Image PixRasterBaseCtrl::CursorImage(Point p, dword keyflags)
|
|
{
|
|
if(keyflags & K_MOUSEMIDDLE)
|
|
return Image::Hand();
|
|
else
|
|
return Image::Arrow();
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// mouse wheel handler
|
|
void PixRasterBaseCtrl::MouseWheel(Point p, int zdelta, dword keyflags)
|
|
{
|
|
int max = vScrollBar.GetTotal();
|
|
int step = max / 100;
|
|
if(step <= 0)
|
|
step = 1;
|
|
int newPos = vScrollBar.Get();
|
|
if(zdelta < 0)
|
|
newPos += step;
|
|
else
|
|
newPos -= step;
|
|
if(newPos > max)
|
|
newPos = max;
|
|
if(newPos < 0)
|
|
newPos = 0;
|
|
vScrollBar.Set(newPos);
|
|
|
|
Refresh();
|
|
|
|
} // END PixRasterBaseCtrl::MouseWheel()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// repaint images on image cache
|
|
void PixRasterBaseCtrl::PaintCache()
|
|
{
|
|
Array<Rect> rects;
|
|
|
|
// if no associated PixRaster object, do nothing
|
|
if(!pixRasterCtrl || !pixRasterCtrl->GetPixBase())
|
|
return;
|
|
|
|
// backups old imageCache positions inside the full tiff image
|
|
int oldCacheLeft = cacheLeft;
|
|
int oldCacheTop = cacheTop;
|
|
|
|
// calculate new imageCache position inside the full tiff image
|
|
if(hScrollBar.IsVisible())
|
|
cacheLeft = hScrollBar.Get();
|
|
else
|
|
cacheLeft = 0;
|
|
if(vScrollBar.IsVisible())
|
|
cacheTop = vScrollBar.Get();
|
|
else
|
|
cacheTop = 0;
|
|
|
|
// if cache is not valid OR scrolled out a full window, gets full cache area
|
|
if(
|
|
!imageCache.IsValid() ||
|
|
abs(oldCacheLeft-cacheLeft) >= imageCache.GetWidth() ||
|
|
abs(oldCacheTop-cacheTop) >= imageCache.GetHeight()
|
|
)
|
|
{
|
|
rects.Add(Rect(imageCache.GetSize()));
|
|
imageCache.SetValid(true);
|
|
oldCacheLeft = oldCacheTop = 0;
|
|
}
|
|
else
|
|
{
|
|
// shifts imageCache
|
|
imageCache.Scroll(Size(oldCacheLeft-cacheLeft, oldCacheTop-cacheTop));
|
|
|
|
// calculates the (1 or 2) rects that must be repainted
|
|
int startLine = 0;
|
|
int endLine = imageCache.GetHeight();
|
|
|
|
// top rectangle, if any
|
|
if(cacheTop < oldCacheTop)
|
|
{
|
|
rects.Add(Rect(0, 0, imageCache.GetWidth(), oldCacheTop-cacheTop));
|
|
startLine += oldCacheTop-cacheTop;
|
|
}
|
|
// bottom rectangle, if any
|
|
else if(cacheTop > oldCacheTop)
|
|
{
|
|
rects.Add(Rect(0, imageCache.GetHeight()-(cacheTop-oldCacheTop), imageCache.GetWidth(), imageCache.GetHeight()));
|
|
endLine += oldCacheTop-cacheTop;
|
|
}
|
|
// left rectangle, if any
|
|
if(cacheLeft < oldCacheLeft)
|
|
rects.Add(Rect(0, startLine, oldCacheLeft - cacheLeft, endLine));
|
|
else if(cacheLeft > oldCacheLeft)
|
|
rects.Add(Rect(imageCache.GetWidth()-(cacheLeft-oldCacheLeft), startLine, imageCache.GetWidth(), endLine));
|
|
}
|
|
|
|
// gets associated PixRaster object
|
|
PixBase *pixBase = pixRasterCtrl->GetPixBase();
|
|
|
|
// scans the PixRaster pages to see if some of them fits in
|
|
// rectangles that must be repainted
|
|
int currentTop = 0;
|
|
int currentPage = pixBase->GetActivePage();
|
|
for(int i = 0 ; i < pixBase->GetPageCount() ; i++)
|
|
{
|
|
// sets the active page
|
|
pixBase->SeekPage(i);
|
|
|
|
// translates current top of page in view coordinates
|
|
int viewCurrentTop = ScaleToView(currentTop);
|
|
|
|
// gets current page size and translates it in view coordinates
|
|
Rect viewPageRect(
|
|
-cacheLeft,
|
|
-cacheTop + viewCurrentTop,
|
|
ScaleToView(pixBase->GetSize().cx) - cacheLeft,
|
|
ScaleToView(pixBase->GetSize().cy) - cacheTop + viewCurrentTop
|
|
);
|
|
|
|
// now scans the rectangles that must be repainted
|
|
// and checks if current page has some area on it
|
|
for(int iRect = 0; iRect < rects.GetCount(); iRect++)
|
|
{
|
|
// gets current rectangle
|
|
Rect rect = rects[iRect];
|
|
|
|
// intersects with page rect
|
|
rect.Intersect(viewPageRect);
|
|
|
|
// if intersection is not empty, do repaint the stuff
|
|
if(!rect.IsEmpty())
|
|
{
|
|
// gets back the tiff rectangle
|
|
Rect tiffRect(
|
|
ScaleToPage(rect.left + cacheLeft),
|
|
ScaleToPage(rect.top + cacheTop) - currentTop,
|
|
ScaleToPage(rect.right + cacheLeft),
|
|
ScaleToPage(rect.bottom + cacheTop) -currentTop
|
|
);
|
|
|
|
// rescales the image area
|
|
ImageEncoder t;
|
|
Rescale(t, rect.GetSize(), *pixBase, tiffRect);
|
|
|
|
// and copies insiede the cache area
|
|
Image img = Image(t);
|
|
ASSERT(rect.top >= 0 && rect.top + img.GetHeight() <= imageCache.GetHeight());
|
|
ASSERT(rect.left >= 0 && rect.left + img.GetWidth() <= imageCache.GetWidth());
|
|
imageCache.Copy(Point(rect.left, rect.top), Rect(0, 0, img.GetWidth(), img.GetHeight()), img);
|
|
}
|
|
}
|
|
currentTop += pixBase->GetHeight() + ScaleToPage(10);
|
|
}
|
|
|
|
// restore PixRaster's active page
|
|
pixBase->SeekPage(currentPage);
|
|
|
|
|
|
} // END PixRasterBaseCtrl::PaintCache()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// repaint polygon markers over the images
|
|
void PixRasterBaseCtrl::PaintMarkers(Draw &d)
|
|
{
|
|
// if no associated PixRaster object, do nothing
|
|
if(!pixRasterCtrl || !pixRasterCtrl->GetPixBase())
|
|
return;
|
|
|
|
// gets associated PixRaster object
|
|
PixBase *pixBase = pixRasterCtrl->GetPixBase();
|
|
|
|
// calculate view position inside the full tiff image
|
|
int left, top;
|
|
if(hScrollBar.IsVisible())
|
|
left = hScrollBar.Get();
|
|
else
|
|
left = 0;
|
|
if(vScrollBar.IsVisible())
|
|
top = vScrollBar.Get();
|
|
else
|
|
top = 0;
|
|
|
|
// loop for all pages, to see which of them fits the view
|
|
int currentTop = 0;
|
|
int currentPage = pixBase->GetActivePage();
|
|
for(int i = 0 ; i < pixBase->GetPageCount() ; i++)
|
|
{
|
|
// sets the active page
|
|
pixBase->SeekPage(i);
|
|
|
|
// translates current top of page in view coordinates
|
|
int viewCurrentTop = ScaleToView(currentTop);
|
|
|
|
// gets current page size and translates it in view coordinates
|
|
Rect viewPageRect(
|
|
-left,
|
|
-top + viewCurrentTop,
|
|
ScaleToView(pixBase->GetSize().cx) - left,
|
|
ScaleToView(pixBase->GetSize().cy) - top + viewCurrentTop
|
|
);
|
|
|
|
// this is when page view is smaller than ctrl view
|
|
int hGap;
|
|
int pw = viewPageRect.right - viewPageRect.left;
|
|
if(pw >= GetSize().cx)
|
|
hGap = 0;
|
|
else
|
|
hGap = (GetSize().cx - pw) / 2;
|
|
|
|
// checks wether the page fits the view..
|
|
viewPageRect.Intersect(GetView());
|
|
if(!viewPageRect.IsEmpty())
|
|
{
|
|
|
|
// this page is inside view, let's take its markers
|
|
Markers &markers = *pixBase->GetMarkers();
|
|
for(int iMarker = 0; iMarker < markers.GetCount(); iMarker++)
|
|
{
|
|
Marker &marker = markers[iMarker];
|
|
|
|
// don't paint marker being dragged... it will be done by
|
|
// drag routine itself
|
|
if(&marker == selectedMarker)
|
|
continue;
|
|
|
|
switch(marker.GetKind())
|
|
{
|
|
case Marker::EmptyMarker:
|
|
continue;
|
|
|
|
default:
|
|
Vector<Point> pts = marker.GetPoints();
|
|
Point points[pts.GetCount()];
|
|
for(int i = 0; i < pts.GetCount(); i++)
|
|
{
|
|
points[i].x = ScaleToView(pts[i].x) - left + hGap;
|
|
points[i].y = ScaleToView(pts[i].y) - top + viewCurrentTop;
|
|
}
|
|
if(&marker != highlightMarker)
|
|
d.DrawPolygon(points, pts.GetCount(),
|
|
marker.GetFillColor(),
|
|
marker.GetBorderThickness(),
|
|
marker.GetBorderColor(),
|
|
marker.GetBorderLineType(),
|
|
White);
|
|
else
|
|
d.DrawPolygon(points, pts.GetCount(),
|
|
marker.GetSelFillColor(),
|
|
marker.GetSelBorderThickness(),
|
|
marker.GetSelBorderColor(),
|
|
marker.GetSelBorderLineType(),
|
|
White);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
currentTop += pixBase->GetHeight() + ScaleToPage(10);
|
|
}
|
|
|
|
// restore PixRaster's active page
|
|
pixBase->SeekPage(currentPage);
|
|
|
|
} // END PixRasterBaseCtrl::PaintMarkers()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// paint routine
|
|
void PixRasterBaseCtrl::Paint(Draw &d)
|
|
{
|
|
// clears background
|
|
d.DrawRect(GetSize(), SColorFace());
|
|
|
|
// if no associated PixRaster, does nothing
|
|
if(!pixRasterCtrl->GetPixBase())
|
|
return;
|
|
|
|
// paints image inside cache, if needed
|
|
PaintCache();
|
|
|
|
// paints image cache inside control
|
|
if(imageCache.GetWidth() >= GetSize().cx)
|
|
imageCache.Paint(d, Point(0, 0));
|
|
else
|
|
imageCache.Paint(d, Point((GetSize().cx - imageCache.GetWidth()) / 2, 0));
|
|
|
|
// paints markers inside control
|
|
PaintMarkers(d);
|
|
|
|
// if dragging, paints rubber banded polygon
|
|
if(selectedMarker && dragPolygon.GetCount())
|
|
{
|
|
d.DrawPolygon(dragPolygon, dragPolygon.GetCount(),
|
|
selectedMarker->GetFillColor(),
|
|
selectedMarker->GetBorderThickness(),
|
|
selectedMarker->GetBorderColor(),
|
|
PEN_DOT,
|
|
White);
|
|
}
|
|
|
|
} // END LeptonicaBaseCtrl::Paint()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// scrollbar handler
|
|
void PixRasterBaseCtrl::OnScroll(void)
|
|
{
|
|
Refresh();
|
|
|
|
} // END PixRasterBaseCtrl::OnScroll()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// handles changes in images or ctrl
|
|
void PixRasterBaseCtrl::Layout(void)
|
|
{
|
|
// this to avoid recursion
|
|
static bool inside = false;
|
|
|
|
// if no associated PixRaster or no pages to display, hides scrollbar and return
|
|
if(!pixRasterCtrl->GetPixBase() || !pixRasterCtrl->GetPageCount())
|
|
{
|
|
hScrollBar.Hide();
|
|
vScrollBar.Hide();
|
|
return;
|
|
}
|
|
|
|
// if already doing layout, just return
|
|
if(inside)
|
|
return;
|
|
|
|
// marks inside layout
|
|
inside = true;
|
|
|
|
// stores scroll positions, in order to go on right position
|
|
// after zoom operations
|
|
int hScrollPos = hScrollBar.Get();
|
|
int hScrollMax = hScrollBar.GetTotal();
|
|
int vScrollPos = vScrollBar.Get();
|
|
int vScrollMax = vScrollBar.GetTotal();
|
|
|
|
// gets the PixRaster object
|
|
PixBase *pixBase = pixRasterCtrl->GetPixBase();
|
|
|
|
// calculates max width and height
|
|
// and total Tiff height, for all pages, with no gaps by now
|
|
int rasterWidth = 0;
|
|
int rasterHeight = 0;
|
|
int maxHeight = 0;
|
|
int pageCount = pixBase->GetPageCount();
|
|
for(int i = 0 ; i < pageCount ; i++)
|
|
{
|
|
// sets current page
|
|
pixBase->SeekPage(i);
|
|
|
|
// gets page size
|
|
Size sz = pixBase->GetSizeEx(i);
|
|
|
|
// updates width, maximum height and total height
|
|
if(sz.cx > rasterWidth)
|
|
rasterWidth = sz.cx;
|
|
if(sz.cy > maxHeight)
|
|
maxHeight = sz.cy;
|
|
rasterHeight += sz.cy;
|
|
}
|
|
|
|
// calculates image scale factor
|
|
imageScale = CalcScale(imageScale, rasterWidth, maxHeight);
|
|
|
|
// stops layouting if imagescale is null
|
|
if(!imageScale)
|
|
{
|
|
inside = false;
|
|
return;
|
|
}
|
|
|
|
// now calculate gaps to be exactly 10 pixels in every zoom factor
|
|
int gapSize = ScaleToPage(10);
|
|
|
|
// adds total gaps sizes to total height
|
|
rasterHeight += (pageCount -1) * gapSize;
|
|
|
|
// and finally, sets up scrollbars and shows them
|
|
// and calculate cache sizes
|
|
int scaledRasterHeight = ScaleToView(rasterHeight);
|
|
int cacheHeight;
|
|
vScrollBar.SetPage(GetSize().cy);
|
|
vScrollBar.SetTotal(scaledRasterHeight);
|
|
if(vScrollMax)
|
|
vScrollBar.Set(iscale(vScrollPos, scaledRasterHeight, vScrollMax));
|
|
else
|
|
vScrollBar.Set(0);
|
|
if(GetSize().cy <= scaledRasterHeight)
|
|
{
|
|
if(hasVScrollBar)
|
|
vScrollBar.Show();
|
|
cacheHeight = GetSize().cy;
|
|
}
|
|
else
|
|
{
|
|
vScrollBar.Hide();
|
|
cacheHeight = scaledRasterHeight;
|
|
}
|
|
int scaledRasterWidth = ScaleToView(rasterWidth);
|
|
int cacheWidth;
|
|
hScrollBar.SetPage(GetSize().cx);
|
|
hScrollBar.SetTotal(scaledRasterWidth);
|
|
if(hScrollMax)
|
|
hScrollBar.Set(iscale(hScrollPos, scaledRasterWidth, hScrollMax));
|
|
else
|
|
hScrollBar.Set(0);
|
|
if(GetSize().cx <= scaledRasterWidth)
|
|
{
|
|
if(hasHScrollBar)
|
|
hScrollBar.Show();
|
|
cacheWidth = GetSize().cx;
|
|
}
|
|
else
|
|
{
|
|
hScrollBar.Hide();
|
|
cacheWidth = scaledRasterWidth;
|
|
}
|
|
|
|
// creates cache image, empty by now
|
|
imageCache.Init(Size(cacheWidth, cacheHeight));
|
|
|
|
// updates image
|
|
Refresh();
|
|
|
|
// mark layout terminated
|
|
inside = false;
|
|
|
|
} // END PixRasterBaseCtrl::Layout()
|
|
|
|
END_UPP_NAMESPACE
|