📄 cn3d_png.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: cn3d_png.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 18:28:18 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.21 * PRODUCTION * =========================================================================== *//* $Id: cn3d_png.cpp,v 1000.3 2004/06/01 18:28:18 gouriano Exp $* ===========================================================================** PUBLIC DOMAIN NOTICE* National Center for Biotechnology Information** This software/database is a "United States Government Work" under the* terms of the United States Copyright Act. It was written as part of* the author's official duties as a United States Government employee and* thus cannot be copyrighted. This software/database is freely available* to the public for use. The National Library of Medicine and the U.S.* Government have not placed any restriction on its use or reproduction.** Although all reasonable efforts have been taken to ensure the accuracy* and reliability of the software and data, the NLM and the U.S.* Government do not and cannot warrant the performance or results that* may be obtained by using this software or data. The NLM and the U.S.* Government disclaim all warranties, express or implied, including* warranties of performance, merchantability or fitness for any particular* purpose.** Please cite the author in any work or product based on this material.** ===========================================================================** Authors: Paul Thiessen** File Description:* save structure window to PNG file** ===========================================================================*/#ifdef _MSC_VER#pragma warning(disable:4018) // disable signed/unsigned mismatch warning in MSVC#endif#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <corelib/ncbi_limits.h>// need GL headers for off-screen rendering#if defined(__WXMSW__)#include <windows.h>#include <GL/gl.h>#include <GL/glu.h>#elif defined(__WXGTK__)#include <GL/gl.h>#include <GL/glu.h>#include <GL/glx.h>#include <gdk/gdkx.h>#elif defined(__WXMAC__)#include <OpenGL/gl.h>#include <OpenGL/glu.h>#endif#include <wx/platform.h>#if defined(__WXGTK__) && defined(__LINUX__)// use system headers/libs for linux builds#include <png.h>#else// otherwise, use libs built into wxWindows#include "../cn3d/png.h"#endif#include "cn3d_png.hpp"#include "cn3d_glcanvas.hpp"#include "opengl_renderer.hpp"#include "progress_meter.hpp"#include "cn3d_tools.hpp"#include "messenger.hpp"////////////////////////////////////////////////////////////////////////////////////////////////// The following is taken unmodified from wxDesigner's C++ code from png_dialog.wdr////////////////////////////////////////////////////////////////////////////////////////////////#include <wx/image.h>#include <wx/statline.h>#include <wx/spinbutt.h>#include <wx/spinctrl.h>#include <wx/splitter.h>#include <wx/listctrl.h>#include <wx/treectrl.h>#include <wx/notebook.h>#include <wx/grid.h>// Declare window functions#define ID_TEXT 10000#define ID_B_BROWSE 10001#define ID_T_NAME 10002#define ID_T_WIDTH 10003#define ID_T_HEIGHT 10004#define ID_C_ASPECT 10005#define ID_C_INTERLACE 10006#define ID_B_OK 10007#define ID_B_CANCEL 10008wxSizer *SetupPNGOptionsDialog( wxPanel *parent, bool call_fit = TRUE, bool set_sizer = TRUE );////////////////////////////////////////////////////////////////////////////////////////////////// fix jmpbuf symbol problem on aix#if defined(_AIX43) && defined(jmpbuf)#undef jmpbuf#endifUSING_NCBI_SCOPE;BEGIN_SCOPE(Cn3D)static ProgressMeter *progressMeter = NULL;static const int PROGRESS_RESOLUTION = 100, MAX_BUFFER_PIXELS = 1000000;static int nRows;class PNGOptionsDialog : private wxDialog{public: PNGOptionsDialog(wxWindow *parent); bool Activate(int initialWidth, int initialHeight, bool initialInterlaced); bool GetValues(wxString *outputFilename, int *width, int *height, bool *interlaced);private: double initialAspect; bool dontProcessChange; // event callbacks void OnButton(wxCommandEvent& event); void OnChangeSize(wxCommandEvent& event); void OnCheckbox(wxCommandEvent& event); void OnCloseWindow(wxCloseEvent& event); DECLARE_EVENT_TABLE()};#define DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(var, id, type) \ type *var; \ var = wxDynamicCast(FindWindow(id), type); \ if (!var) { \ ERRORMSG("Can't find window with id " << id); \ return; \ }#define DECLARE_AND_FIND_WINDOW_RETURN_RESULT_ON_ERR(var, id, type, errResult) \ type *var; \ var = wxDynamicCast(FindWindow(id), type); \ if (!var) { \ ERRORMSG("Can't find window with id " << id); \ return errResult; \ }// to make sure values are legitimate integers; use wxString::ToDouble to avoid parsing// strings as octal or hexadecimal...#define GET_AND_IS_VALID_SIZE(textctrl, var) \ (textctrl->GetValue().ToDouble(&var) && var >= 1 && fmod(var, 1.0) == 0.0 && var <= kMax_Int)BEGIN_EVENT_TABLE(PNGOptionsDialog, wxDialog) EVT_BUTTON (-1, PNGOptionsDialog::OnButton) EVT_TEXT (-1, PNGOptionsDialog::OnChangeSize) EVT_CHECKBOX (-1, PNGOptionsDialog::OnCheckbox) EVT_CLOSE ( PNGOptionsDialog::OnCloseWindow)END_EVENT_TABLE()PNGOptionsDialog::PNGOptionsDialog(wxWindow *parent) : wxDialog(parent, -1, "Export Options", wxPoint(50, 50), wxDefaultSize, wxCAPTION | wxSYSTEM_MENU | wxFRAME_NO_TASKBAR), // not resizable dontProcessChange(false){ // construct the panel wxPanel *panel = new wxPanel(this, -1); wxSizer *topSizer = SetupPNGOptionsDialog(panel, false); // call sizer stuff topSizer->Fit(panel); SetClientSize(topSizer->GetMinSize());}void PNGOptionsDialog::OnButton(wxCommandEvent& event){ switch (event.GetId()) { case ID_B_BROWSE: { DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(tName, ID_T_NAME, wxTextCtrl) wxString filename = wxFileSelector( "Choose a filename for output", GetUserDir().c_str(), "", ".png", "All Files|*.*|PNG files (*.png)|*.png", wxSAVE | wxOVERWRITE_PROMPT); if (filename.size() > 0) tName->SetValue(filename); break; } case ID_B_OK: { wxString str; int w, h; bool i; if (GetValues(&str, &w, &h, &i)) EndModal(wxOK); else wxBell(); break; } case ID_B_CANCEL: EndModal(wxCANCEL); break; }}void PNGOptionsDialog::OnChangeSize(wxCommandEvent& event){ // avoid recursive calls to this, since SetValue() triggers this event; only process size fields if (dontProcessChange || !(event.GetId() == ID_T_WIDTH || event.GetId() == ID_T_HEIGHT)) return; DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(tWidth, ID_T_WIDTH, wxTextCtrl) DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(tHeight, ID_T_HEIGHT, wxTextCtrl) DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(cAspect, ID_C_ASPECT, wxCheckBox) DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(cInterlace, ID_C_INTERLACE, wxCheckBox) // post refreshes for both, in case background color changes tWidth->Refresh(true); tHeight->Refresh(true); double w, h; if (!GET_AND_IS_VALID_SIZE(tWidth, w)) { tWidth->SetBackgroundColour(*wxRED); return; } tWidth->SetBackgroundColour(*wxWHITE); if (!GET_AND_IS_VALID_SIZE(tHeight, h)) { tHeight->SetBackgroundColour(*wxRED); return; } tHeight->SetBackgroundColour(*wxWHITE); // adjust to aspect ratio if indicated dontProcessChange = true; if (cAspect->GetValue()) { wxString num; if (event.GetId() == ID_T_WIDTH) { h = floor(w / initialAspect + 0.5); num.Printf("%i", (int) h); tHeight->SetValue(num); } else { w = floor(h * initialAspect + 0.5); num.Printf("%i", (int) w); tWidth->SetValue(num); } } dontProcessChange = false; // only allow interlacing if image is small enough if (w * h > MAX_BUFFER_PIXELS) { if (cInterlace->IsEnabled()) { cInterlace->Enable(false); cInterlace->SetValue(false); } } else { if (!cInterlace->IsEnabled()) { cInterlace->Enable(true); cInterlace->SetValue(true); } }}void PNGOptionsDialog::OnCheckbox(wxCommandEvent& event){ if (event.GetId() == ID_C_ASPECT) { // adjust height when aspect checkbox is turned on DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(cAspect, ID_C_ASPECT, wxCheckBox) if (cAspect->GetValue()) { DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(tWidth, ID_T_WIDTH, wxTextCtrl) DECLARE_AND_FIND_WINDOW_RETURN_ON_ERR(tHeight, ID_T_HEIGHT, wxTextCtrl) double w, h; if (GET_AND_IS_VALID_SIZE(tWidth, w)) { wxString num; h = floor(w / initialAspect + 0.5); num.Printf("%i", (int) h); tHeight->SetValue(num); } } }}void PNGOptionsDialog::OnCloseWindow(wxCloseEvent& event){ EndModal(wxCANCEL);}bool PNGOptionsDialog::Activate(int initialWidth, int initialHeight, bool initialInterlaced){ DECLARE_AND_FIND_WINDOW_RETURN_RESULT_ON_ERR(tName, ID_T_NAME, wxTextCtrl, false) DECLARE_AND_FIND_WINDOW_RETURN_RESULT_ON_ERR(tWidth, ID_T_WIDTH, wxTextCtrl, false) DECLARE_AND_FIND_WINDOW_RETURN_RESULT_ON_ERR(tHeight, ID_T_HEIGHT, wxTextCtrl, false) DECLARE_AND_FIND_WINDOW_RETURN_RESULT_ON_ERR(cAspect, ID_C_ASPECT, wxCheckBox, false) DECLARE_AND_FIND_WINDOW_RETURN_RESULT_ON_ERR(cInterlace, ID_C_INTERLACE, wxCheckBox, false) dontProcessChange = true; wxString num; num.Printf("%i", initialWidth); tWidth->SetValue(num); num.Printf("%i", initialHeight); tHeight->SetValue(num); initialAspect = ((double) initialWidth) / initialHeight; cAspect->SetValue(true); dontProcessChange = false; if (initialWidth*initialHeight > MAX_BUFFER_PIXELS) { cInterlace->Enable(false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -