NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
imagepanel.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2017 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19
20#include <wx/artprov.h>
21#include <wx/dir.h>
22#include <wx/clipbrd.h>
23#include "imagepanel.hpp"
24#include "../../kernel/core/ui/language.hpp"
25
26extern Language _guilang;
27
28
29BEGIN_EVENT_TABLE(ImagePanel, wxPanel)
30// some useful events
31/*
32 EVT_MOTION(wxImagePanel::mouseMoved)
33 EVT_LEFT_DOWN(wxImagePanel::mouseDown)
34 EVT_LEFT_UP(wxImagePanel::mouseReleased)
35 EVT_RIGHT_DOWN(wxImagePanel::rightClick)
36 EVT_LEAVE_WINDOW(wxImagePanel::mouseLeftWindow)
37 EVT_KEY_UP(wxImagePanel::keyReleased)
38 EVT_MOUSEWHEEL(wxImagePanel::mouseWheelMoved)
39 */
40// EVT_ENTER_WINDOW (ImagePanel::OnEnter)
41 EVT_SET_FOCUS (ImagePanel::OnFocus)
42 EVT_KILL_FOCUS (ImagePanel::OnLoseFocus)
43 EVT_KEY_DOWN (ImagePanel::keyPressed)
44 EVT_NAVIGATION_KEY (ImagePanel::OnNavigationKey)
45 // catch paint events
46 EVT_PAINT (ImagePanel::paintEvent)
47 //Size event
48 EVT_SIZE (ImagePanel::OnSize)
49
55
56
57
58
66ImagePanel::ImagePanel(wxFrame* parent, wxString file, wxBitmapType format) : wxPanel(parent)
67{
68 // load the file... ideally add a check to see if loading was successful
69 wxInitAllImageHandlers();
70 parentFrame = parent;
71
72 this->LoadImage(file, format, false);
73
74 toptoolbar = parentFrame->CreateToolBar(wxTB_HORIZONTAL | wxTB_FLAT);
75 toptoolbar->AddTool(ID_SAVEIMAGE, _guilang.get("GUI_TB_SAVE"), wxArtProvider::GetBitmap(wxART_FILE_SAVE, wxART_TOOLBAR), _guilang.get("GUI_TB_SAVE_TTP"));
76 toptoolbar->AddTool(ID_COPYIMAGE, _guilang.get("GUI_TB_COPY"), wxArtProvider::GetBitmap(wxART_COPY, wxART_TOOLBAR), _guilang.get("GUI_TB_COPY"));
77 toptoolbar->AddSeparator();
78 toptoolbar->AddTool(ID_PREVIOUSIMAGE, _guilang.get("GUI_TB_PREVIOUSIMAGE"), wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR), _guilang.get("GUI_TB_PREVIOUSIMAGE"));
79 toptoolbar->AddTool(ID_NEXTIMAGE, _guilang.get("GUI_TB_NEXTIMAGE"), wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR), _guilang.get("GUI_TB_NEXTIMAGE"));
80 toptoolbar->Realize();
81
82 parentFrame->Bind(wxEVT_MENU, &ImagePanel::OnSaveAs, this, ID_SAVEIMAGE);
83 parentFrame->Bind(wxEVT_MENU, &ImagePanel::OnCopy, this, ID_COPYIMAGE);
84 parentFrame->Bind(wxEVT_MENU, &ImagePanel::OnNextImage, this, ID_NEXTIMAGE);
85 parentFrame->Bind(wxEVT_MENU, &ImagePanel::OnPreviousImage, this, ID_PREVIOUSIMAGE);
86}
87
88
100void ImagePanel::LoadImage(const wxString& filename, wxBitmapType format, bool doUpdateFrame)
101{
102 image.LoadFile(filename, format);
103 w = image.GetWidth();
104 h = image.GetHeight();
105 sized_w = -1;
106 sized_h = -1;
107 currentFile = filename;
108
109 if (doUpdateFrame)
110 {
111 this->SetSize(this->getRelation()*600,600);
112 parentFrame->SetClientSize(this->GetSize());
113 parentFrame->SetTitle("NumeRe-ImageViewer: " + wxFileName(filename).GetName());
114 this->paintNow();
115 }
116}
117
118
128bool ImagePanel::LoadNextImage(const wxFileName& filename)
129{
130 if (filename.GetExt() == "png" || filename.GetExt() == "bmp" || filename.GetExt() == "jpg" || filename.GetExt() == "jpeg" || filename.GetExt() == "gif" || filename.GetExt() == "tif" || filename.GetExt() == "tiff")
131 {
132 wxBitmapType format;
133
134 if (filename.GetExt() == "png")
135 format = wxBITMAP_TYPE_PNG;
136 if (filename.GetExt() == "bmp")
137 format = wxBITMAP_TYPE_BMP;
138 if (filename.GetExt() == "jpg" || filename.GetExt() == "jpeg")
139 format = wxBITMAP_TYPE_JPEG;
140 if (filename.GetExt() == "gif")
141 format = wxBITMAP_TYPE_GIF;
142 if (filename.GetExt() == "tif" || filename.GetExt() == "tiff")
143 format = wxBITMAP_TYPE_TIF;
144
145 //wxFileName current(currentFile);
146 LoadImage(filename.GetFullPath(), format);
147 return true;
148 }
149
150 return false;
151}
152
153
163wxArrayString ImagePanel::getFileList(const wxString& dirname)
164{
165 wxArrayString filelist;
166 if (wxDir::GetAllFiles(dirname, &filelist, "*.*", wxDIR_FILES))
167 return filelist;
168 return wxArrayString();
169}
170
171
182void ImagePanel::paintEvent(wxPaintEvent & evt)
183{
184 // depending on your system you may need to look at double-buffered dcs
185 wxPaintDC dc(this);
186 render(dc);
187}
188
189
204{
205 // depending on your system you may need to look at double-buffered dcs
206 wxClientDC dc(this);
207 render(dc);
208}
209
210
221void ImagePanel::render(wxDC& dc)
222{
223 int neww, newh;
224 dc.GetSize(&neww, &newh);
225
226 if (neww != sized_w || newh != sized_h)
227 {
228 if (neww/(double)newh > w/(double)h)
229 {
230 sized_w = w/(double)h*newh;
231 sized_h = newh;
232 }
233 else
234 {
235 sized_w = neww;
236 sized_h = h/(double)w*neww;
237 }
238 // BICUBIC may be slow, but in this case it doesn't have to be fast. However, in most cases the images will be mase smaller and the default quality is bad in this case
239 resized = wxBitmap(image.Scale(sized_w, sized_h, wxIMAGE_QUALITY_BICUBIC));
240 dc.DrawBitmap( resized, 0, 0, false );
241 }
242 else
243 {
244 dc.DrawBitmap( resized, 0, 0, false );
245 }
246}
247
248
259void ImagePanel::OnSize(wxSizeEvent& event)
260{
261 Refresh();
262 //skip the event.
263 event.Skip();
264}
265
266
275void ImagePanel::keyPressed(wxKeyEvent& event)
276{
277 // connecting the ESC Key with closing the image
278 if (event.GetKeyCode() == WXK_ESCAPE)
279 m_parent->Close();
280}
281
282
292void ImagePanel::OnNavigationKey(wxNavigationKeyEvent& event)
293{
294 // connect the navigation keys with next and previous image
295 wxCommandEvent commandevent;
296 if (event.GetDirection())
297 OnNextImage(commandevent);
298 else
299 OnPreviousImage(commandevent);
300}
301
302
311void ImagePanel::OnEnter(wxMouseEvent& event)
312{
313 this->SetFocus();
314 event.Skip();
315}
316
317
325void ImagePanel::OnFocus(wxFocusEvent& event)
326{
327 //m_parent->SetTransparent(wxIMAGE_ALPHA_OPAQUE);
328 event.Skip();
329}
330
331
339void ImagePanel::OnLoseFocus(wxFocusEvent& event)
340{
341 //m_parent->SetTransparent(80);
342 event.Skip();
343}
344
345
354void ImagePanel::OnSaveAs(wxCommandEvent& event)
355{
356 wxString title = _guilang.get("GUI_DLG_SAVEAS");
357 wxString filterString = "PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|JPEG (*.jpg)|*.jpg";
358 wxFileName fileName = currentFile;
359 wxFileDialog dlg(this, title, fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR), fileName.GetName(), filterString, wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxFD_CHANGE_DIR);
360
361 // ie, user clicked cancel
362 if(dlg.ShowModal() != wxID_OK)
363 {
364 return;
365 }
366
367 fileName = wxFileName(dlg.GetPath());
368
369 image.SaveFile(fileName.GetFullName());
370}
371
372
381void ImagePanel::OnCopy(wxCommandEvent& event)
382{
383 if (wxTheClipboard->Open())
384 {
385 wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(image)));
386 wxTheClipboard->Close();
387 }
388}
389
390
399void ImagePanel::OnNextImage(wxCommandEvent& event)
400{
401 wxFileName filename(currentFile);
402 wxArrayString filelist = getFileList(filename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
403 if (!filelist.size())
404 return;
405 int nIndex = filelist.Index(filename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + filename.GetFullName());
406 if (nIndex == wxNOT_FOUND)
407 return;
408
409 for (size_t i = 1; i < filelist.size(); i++)
410 {
411 if (nIndex+i == filelist.size())
412 nIndex = -(int)i;
413
414 if (LoadNextImage(filelist[i+nIndex]))
415 return;
416 }
417}
418
419
428void ImagePanel::OnPreviousImage(wxCommandEvent& event)
429{
430 wxFileName filename(currentFile);
431 wxArrayString filelist = getFileList(filename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
432 if (!filelist.size())
433 return;
434 int nIndex = filelist.Index(filename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + filename.GetFullName());
435 if (nIndex == wxNOT_FOUND)
436 return;
437
438 for (int i = -1; i > -(int)filelist.size(); i--)
439 {
440 if (nIndex+i < 0)
441 nIndex = filelist.size()-i-1;
442
443 if (LoadNextImage(filelist[i+nIndex]))
444 return;
445 }
446}
447
448
void OnCopy(wxCommandEvent &event)
This member function handles the "copy" toolbar option of the parent frame.
Definition: imagepanel.cpp:381
void OnLoseFocus(wxFocusEvent &event)
On lose focus event handler.
Definition: imagepanel.cpp:339
void OnSaveAs(wxCommandEvent &event)
This member function handles the "save as" toolbar option of the parent frame.
Definition: imagepanel.cpp:354
bool LoadNextImage(const wxFileName &filename)
This method tries to load the desired image file and returns, whether it was successful or not.
Definition: imagepanel.cpp:128
void paintNow()
Alternatively, you can use a clientDC to paint on the panel at any time. Using this generally does no...
Definition: imagepanel.cpp:203
void keyPressed(wxKeyEvent &event)
This function closes the parent frame, if the user presses the ESC key.
Definition: imagepanel.cpp:275
double getRelation() const
Definition: imagepanel.hpp:45
void OnSize(wxSizeEvent &event)
Here we call refresh to tell the panel to draw itself again. So when the user resizes the image panel...
Definition: imagepanel.cpp:259
wxImage image
Definition: imagepanel.hpp:26
void paintEvent(wxPaintEvent &evt)
Called by the system of by wxWidgets when the panel needs to be redrawn. You can also trigger this ca...
Definition: imagepanel.cpp:182
void OnEnter(wxMouseEvent &event)
On enter event handler focuses this panel.
Definition: imagepanel.cpp:311
void OnFocus(wxFocusEvent &event)
On focus event handler.
Definition: imagepanel.cpp:325
wxBitmap resized
Definition: imagepanel.hpp:27
wxString currentFile
Definition: imagepanel.hpp:29
void OnNavigationKey(wxNavigationKeyEvent &event)
This member function chooses the next or previous image in the file list, depending on the arrow key ...
Definition: imagepanel.cpp:292
void render(wxDC &dc)
Here we do the actual rendering. I put it in a separate method so that it can work no matter what typ...
Definition: imagepanel.cpp:221
wxFrame * parentFrame
Definition: imagepanel.hpp:30
void OnPreviousImage(wxCommandEvent &event)
This member function displays the previous image in the current folder.
Definition: imagepanel.cpp:428
void OnNextImage(wxCommandEvent &event)
This member function displays the next image in the current folder.
Definition: imagepanel.cpp:399
wxArrayString getFileList(const wxString &dirname)
This method returns a list of all files in the current folder (used for iterating over all images).
Definition: imagepanel.cpp:163
void LoadImage(const wxString &filename, wxBitmapType=wxBITMAP_TYPE_ANY, bool doUpdateFrame=true)
This method loads the specified file, updates the parent frame's size (if desired) and displays the i...
Definition: imagepanel.cpp:100
This class handles the internal language system and returns the language strings of the selected lang...
Definition: language.hpp:38
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
@ ID_SAVEIMAGE
@ ID_PREVIOUSIMAGE
@ ID_NEXTIMAGE
@ ID_COPYIMAGE
Language _guilang
auto format(const std::locale &loc, const CharT *fmt, const Streamable &tp) -> decltype(to_stream(std::declval< std::basic_ostream< CharT > & >(), fmt, tp), std::basic_string< CharT >{})
Definition: date.h:6249
END_EVENT_TABLE()