sfftools/sffview/tags/REL0_5_0/sffview.cpp

222 lines
5.5 KiB
C++

//
// This file is part of sffview, a program to view structured fax files (sff)
//
// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
//
// Permission to use, copy, modify, distribute, and sell this software and
// its documentation for any purpose is hereby granted without fee.
//
// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
// OR PERFORMANCE OF THIS SOFTWARE.
//
// Contributor(s):
// None
//
// You can contact the original author by email at peter.schaefer@gmx.de.
//
// I'm always pleased to hear that somebody is actually using my software.
// If you can manage it, e-mail me a quick notice. Thanks!
//
#include <wx/wx.h>
#include <wx/wfstream.h>
#include <wx/toolbar.h>
#include <wx/docview.h>
#include <wx/cmdproc.h>
#include <wx/dcprint.h>
#include "sfftypes.h"
#include "common.h"
#include "codes.h"
#include "decoder.h"
#include "sfffile.h"
#include "sffview.h"
#include "sffapp.h"
#include "sffdoc.h"
//-----------------------------------------------------------------------------
// SffView
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(SffView, wxView)
BEGIN_EVENT_TABLE(SffView, wxView)
END_EVENT_TABLE()
SffView::~SffView()
{
if (m_pMemDC)
delete m_pMemDC;
}
// What to do when a view is created. Creates actual
// windows for displaying the view.
bool SffView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
{
m_pMemDC = new wxMemoryDC();
m_nZoom = 1.0;
m_bXFlipped = false;
m_bYFlipped = false;
m_nScaleType = FITWIDTH;
frame = GetMainFrame();
canvas = GetMainFrame()->canvas;
canvas->view = this;
// Associate the appropriate frame with this view.
SetFrame(frame);
// Make sure the document manager knows that this is the
// current view.
Activate(TRUE);
// Initialize the edit menu Undo and Redo items
doc->GetCommandProcessor()->Initialize();
return TRUE;
}
void SffView::SetBitmap(wxBitmap *pBmp)
{
if (pBmp) {
m_pMemDC->SelectObject(*pBmp);
m_nBitmapHeight = pBmp->GetHeight();
m_nBitmapWidth = pBmp->GetWidth();
CalcScale();
} else {
m_pMemDC->SelectObject(wxNullBitmap);
m_nBitmapHeight = m_nBitmapWidth = 0;
}
}
void SffView::SetScale(TScale type)
{
TScale old = m_nScaleType;
m_nScaleType = type;
if (m_nScaleType != old) {
CalcScale();
canvas->Refresh();
}
}
void SffView::CalcScale()
{
int w, h;
switch (m_nScaleType)
{
case FULLSCALE:
m_nZoom=1;
canvas->SetScrollbars( 1, 1, m_nBitmapWidth, m_nBitmapHeight);
canvas->Refresh();
break;
case FITWIDTH:
frame->GetClientSize(&w, &h);
m_nZoom=w; m_nZoom = m_nZoom/m_nBitmapWidth;
canvas->SetScrollbars( 1, 1, 1, (int)(m_nBitmapHeight*m_nZoom));
canvas->Refresh();
break;
case FULLPAGE:
frame->GetClientSize(&w, &h);
m_nZoom=h; m_nZoom /= m_nBitmapHeight;
canvas->SetScrollbars( 1, 1, (int)(m_nBitmapWidth*m_nZoom), 1);
canvas->Refresh();
break;
}
}
void SffView::OnDraw(wxDC *dc)
{
// Flipping is currently not supported due to wxGTK not honouring
// the mapping mode while blitting. This seems to be badly horked
// currently (wxGTK 2.5.2)
dc->SetUserScale(m_nZoom, m_nZoom);
#if defined(__WXGTK__) && !wxCHECK_VERSION(2,8,0)
if (m_nZoom != 1) {
// Strange misbehaviour of wxGTK -> if we blit zoomed, the colours
// get inversed ??!? Workaround: wxSRC_INVERT
dc->Blit(0,0,m_nBitmapWidth,m_nBitmapHeight,m_pMemDC,0,0,wxSRC_INVERT);
} else {
dc->Blit(0,0,m_nBitmapWidth,m_nBitmapHeight,m_pMemDC,0,0,wxCOPY);
}
#else
dc->Blit(0,0,m_nBitmapWidth,m_nBitmapHeight,m_pMemDC,0,0,wxCOPY);
#endif
}
void SffView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
{
if (canvas) {
SetBitmap(((SffDocument *)GetDocument())->GetPageBitmap());
canvas->Refresh();
}
}
void SffView::FlipX()
{
m_bXFlipped = !m_bXFlipped;
canvas->Refresh();
}
void SffView::FlipY()
{
m_bYFlipped = !m_bYFlipped;
canvas->Refresh();
}
// Clean up windows used for displaying the view.
bool SffView::OnClose(bool deleteWindow)
{
if (!GetDocument()->Close())
return FALSE;
canvas->view = (wxView *) NULL;
canvas = (SffCanvas *) NULL;
wxString s(wxTheApp->GetAppName());
if (frame) frame->SetTitle(s);
SetFrame((wxFrame *) NULL);
Activate(FALSE);
return TRUE;
}
wxPrintout* SffView::OnCreatePrintout()
{
return new SffPrintout((SffDocument *)GetDocument());
}
//-----------------------------------------------------------------------------
// SffCanvas
//-----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(SffCanvas, wxScrolledWindow)
END_EVENT_TABLE()
// Define a constructor for my canvas
SffCanvas::SffCanvas(wxView *v, wxFrame *frame,
const wxPoint& pos, const wxSize& size) :
wxScrolledWindow(frame, -1, pos, size, wxSUNKEN_BORDER)
{
view = v;
SetBackgroundColour(_T("WHITE"));
}
// Define the repainting behaviour
void SffCanvas::OnDraw(wxDC& dc)
{
if (view) {
view->OnDraw(&dc);
}
}