| OZ++ Class: ScrolledImageView |
/******************************************************************************
*
* Copyright (c) 2017 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* ScrolledImageView.h
*
*****************************************************************************/
//2017/05/10
//2017/10/16 Modified to use create method.
#pragma once
//
#include <oz++/motif/CustomScrolledView.h>
#include <oz++/motif/Color.h>
#include <oz++/motif/DC.h>
#include <oz++/RECT.h>
namespace OZ {
class ScrolledImageView :public CustomScrolledView {
private:
Pixmap pixmap;
//Pixmap geometry
uint width; //Pixmap Width
uint height; //Pixmap Height
uint borderw;
uint depth;
void getImageGeometry(Pixmap pixmap, uint& width, uint& height,
uint& borderw, uint& depth)
{
Window root;
int x, y;
if (pixmap != None) {
XGetGeometry(getDisplay(), pixmap, &root,
&x, &y, &width, &height,
&borderw, &depth);
}
}
public:
ScrolledImageView(View* parent, const char* name, Args& args)
:CustomScrolledView(parent, name, args),
pixmap(None),
width(0),
height(0),
borderw(0),
depth(0)
{
}
ScrolledImageView()
:CustomScrolledView(),
pixmap(None),
width(0),
height(0),
borderw(0),
depth(0)
{
}
void create(View* parent, const char* name, Args& args)
{
CustomScrolledView::create(parent, name, args);
}
~ScrolledImageView()
{
clear();
}
void clear()
{
if (pixmap != None) {
XFreePixmap(getDisplay(), pixmap);
pixmap = None;
}
}
void getImageGeometry(uint& w, uint& h,
uint& bw, uint& d)
{
w = width;
h = height;
bw = borderw;
d = depth;
}
void showImageGeometry()
{
printf("width=%d height=%d borderw=%d depth=%d\n",
width, height, borderw, depth);
}
//virtual function
virtual void createPixmap()
{
}
void setPixmap(Pixmap pixmap)
{
clear();
this->pixmap = pixmap;
getImageGeometry(pixmap, width, height, borderw, depth);
//The values returned by width() and height() don't return
// real window size until this view is mapped.
BulletinBoard* bb = getWorkArea();
int w = bb->width();
int h = bb->height();
dprintf("setPixmap pixmap(w=%d, h=%d), view(w=%d, h=%d)\n",
width, height, w, h);
setScrollBarMaximum((Dimension)width, (Dimension)height);
setScrollBarPosition(0, 0);
//setHorizScrollBarRange(0, width);
if (w > width) {
w = width;
}
setHorizScrollBarSliderSize(w);
//setVertScrollBarRange(0, height);
if (h > height) {
h = height;
}
setVertScrollBarSliderSize(h);
setScrollBarPosition(0, 0);
sendExposeEvent();
}
Pixmap getPixmap()
{
return pixmap;
}
void getGeometry(Pixmap pixmap, uint& width, uint& height,
uint& borderw, uint& depth)
{
Window root;
int x, y;
XGetGeometry(getDisplay(), pixmap, &root,
&x, &y, &width, &height,
&borderw, &depth);
}
virtual void display()
{
Position hpos = 0;
Position vpos = 0;
getScrollBarPosition(hpos, vpos);
Pixmap pixmap = getPixmap();
if (pixmap == None) {
createPixmap();
}
pixmap = getPixmap();
if (pixmap != None) {
//1 Copy the source pixmap to the destination workArea of this scrolled window.
BulletinBoard* dest = getWorkArea();
//2 Get the size of the workArea;
uint w = dest->width();
uint h = dest->height();
//3 Get a destination device context of the destinatin bulletinBoard.
DC destDC(dest);
//4 Copy the source pixmap to the destination bulletin board through destDC.
destDC.copyArea(pixmap, 0, 0, width, height, -hpos, -vpos);
//5 You have to clear a garbage area in the following way.
if (w > width) {
RECT rr= {width, 0, w, height};
if (h>height) {
rr.bottom = h;
}
destDC.fillRectangle(rr.left, rr.top, rr.right-rr.left, rr.bottom - rr.top);
}
if (h > height) {
RECT rr = {0, height, width, h};
if (w>width) {
rr.right = w;
}
destDC.fillRectangle(rr.left, rr.top, rr.right-rr.left, rr.bottom - rr.top);
}
} else {
//pixmap is None
}
}
};
}