X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=src%2Fviews.cpp;h=d40fd5edd988240a2f38ff43d1fda38b4a95f770;hp=f150237ba69005232ad9ef6f407d9c73b121fc80;hb=efc398029330f4d9170257db29e4420e50f25625;hpb=ebb615bb35cf344a765aa65414982904e59f961b diff --git a/src/views.cpp b/src/views.cpp index f150237..d40fd5e 100644 --- a/src/views.cpp +++ b/src/views.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: views.cpp,v 1.30 2000/12/18 09:31:26 kevin Exp $ +** $Id: views.cpp,v 1.33 2000/12/20 14:52:30 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -71,7 +71,9 @@ END_EVENT_TABLE() ImageFileCanvas::ImageFileCanvas (ImageFileView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style) : wxScrolledWindow(frame, -1, pos, size, style) { - m_pView = v; + m_pView = v; + m_xCursor = -1; + m_yCursor = -1; } void @@ -79,8 +81,35 @@ ImageFileCanvas::OnDraw(wxDC& dc) { if (m_pView) m_pView->OnDraw(& dc); +} + +void +ImageFileCanvas::DrawRubberBandCursor (wxDC& dc, int x, int y) +{ + const ImageFile& rIF = m_pView->GetDocument()->getImageFile(); + ImageFileArrayConst v = rIF.getArray(); + int nx = rIF.nx(); + int ny = rIF.ny(); + + dc.SetLogicalFunction (wxINVERT); + dc.SetPen (*wxGREEN_PEN); + dc.DrawLine (0, y, nx, y); + dc.DrawLine (x, 0, x, ny); + dc.SetLogicalFunction (wxCOPY); +} + +bool +ImageFileCanvas::GetCurrentCursor (int& x, int& y) +{ + x = m_xCursor; + y = m_yCursor; + + if (m_xCursor >= 0 && m_yCursor >= 0) + return true; + else + return false; } - + void ImageFileCanvas::OnMouseEvent(wxMouseEvent& event) { @@ -91,24 +120,41 @@ ImageFileCanvas::OnMouseEvent(wxMouseEvent& event) PrepareDC(dc); wxPoint pt(event.GetLogicalPosition(dc)); - - if (event.LeftIsDown()) { - const ImageFile& rIF = m_pView->GetDocument()->getImageFile(); - ImageFileArrayConst v = rIF.getArray(); - int nx = rIF.nx(); - int ny = rIF.ny(); - - if (pt.x >= 0 && pt.x < nx && pt.y >= 0 && pt.y < ny) { - std::ostringstream os; - os << "Image value (" << pt.x << "," << pt.y << ") = " << v[pt.x][ny - 1 - pt.y] << "\n"; - *theApp->getLog() << os.str().c_str(); - } else - *theApp->getLog() << "Mouse out of image range (" << pt.x << "," << pt.y << ")\n"; - - } + + if (event.RightIsDown()) { + const ImageFile& rIF = m_pView->GetDocument()->getImageFile(); + ImageFileArrayConst v = rIF.getArray(); + int nx = rIF.nx(); + int ny = rIF.ny(); + + if (pt.x >= 0 && pt.x < nx && pt.y >= 0 && pt.y < ny) { + std::ostringstream os; + os << "Image value (" << pt.x << "," << pt.y << ") = " << v[pt.x][ny - 1 - pt.y] << "\n"; + *theApp->getLog() << os.str().c_str(); + } else + *theApp->getLog() << "Mouse out of image range (" << pt.x << "," << pt.y << ")\n"; + } + else if (event.LeftIsDown()) { + const ImageFile& rIF = m_pView->GetDocument()->getImageFile(); + ImageFileArrayConst v = rIF.getArray(); + int nx = rIF.nx(); + int ny = rIF.ny(); + + if (pt.x >= 0 && pt.x < nx && pt.y >= 0 && pt.y < ny) { + if (m_xCursor >= 0 && m_yCursor >= 0) { + DrawRubberBandCursor (dc, m_xCursor, m_yCursor); + } + DrawRubberBandCursor (dc, pt.x, pt.y); + m_xCursor = pt.x; + m_yCursor = pt.y; + std::ostringstream os; + os << "Selected column" << pt.x << " and row" << pt.y << "\n"; + *theApp->getLog() << os.str().c_str(); + } else + *theApp->getLog() << "Mouse out of image range (" << pt.x << "," << pt.y << ")\n"; + } } - // ImageFileView IMPLEMENT_DYNAMIC_CLASS(ImageFileView, wxView) @@ -116,7 +162,9 @@ IMPLEMENT_DYNAMIC_CLASS(ImageFileView, wxView) BEGIN_EVENT_TABLE(ImageFileView, wxView) EVT_MENU(IFMENU_FILE_PROPERTIES, ImageFileView::OnProperties) EVT_MENU(IFMENU_VIEW_SCALE_MINMAX, ImageFileView::OnScaleMinMax) -EVT_MENU(IFMENU_VIEW_SCALE_AUTO, ImageFileView::OnScaleAuto) +EVT_MENU(IFMENU_VIEW_SCALE_AUTO, ImageFileView::OnScaleAuto) +EVT_MENU(IFMENU_PLOT_ROW, ImageFileView::OnPlotRow) +EVT_MENU(IFMENU_PLOT_COL, ImageFileView::OnPlotCol) END_EVENT_TABLE() ImageFileView::ImageFileView(void) @@ -229,14 +277,19 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view) wxMenu *view_menu = new wxMenu; view_menu->Append(IFMENU_VIEW_SCALE_MINMAX, "Display Scale &Set..."); view_menu->Append(IFMENU_VIEW_SCALE_AUTO, "Display Scale &Auto..."); - + + wxMenu *plot_menu = new wxMenu; + plot_menu->Append (IFMENU_PLOT_ROW, "Plot &Row"); + plot_menu->Append (IFMENU_PLOT_COL, "Plot &Column"); + wxMenu *help_menu = new wxMenu; help_menu->Append(MAINMENU_HELP_ABOUT, "&About"); wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, "&File"); - menu_bar->Append(view_menu, "&View"); + menu_bar->Append(view_menu, "&View"); + menu_bar->Append(plot_menu, "&Plot"); menu_bar->Append(help_menu, "&Help"); subframe->SetMenuBar(menu_bar); @@ -277,6 +330,10 @@ ImageFileView::OnDraw (wxDC* dc) { if (m_bitmap.Ok()) dc->DrawBitmap(m_bitmap, 0, 0, false); + + int xCursor, yCursor; + if (m_canvas->GetCurrentCursor (xCursor, yCursor)) + m_canvas->DrawRubberBandCursor (*dc, xCursor, yCursor); } @@ -317,7 +374,7 @@ ImageFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) ) ySize = clamp (ySize, 0, 800); m_frame->SetClientSize (xSize, ySize); m_canvas->SetScrollbars(20, 20, nx/20, ny/20); - m_canvas->SetBackgroundColour(*wxWHITE); + m_canvas->SetBackgroundColour(*wxWHITE); } if (m_canvas) @@ -346,8 +403,97 @@ ImageFileView::OnClose (bool deleteWindow) } return true; } - - + +#include "wx/plot.h" + +void +ImageFileView::OnPlotRow (wxCommandEvent& event) +{ + int xCursor, yCursor; + if (! m_canvas->GetCurrentCursor (xCursor, yCursor)) { + *theApp->getLog() << "No row selected. Please use left mouse button on image to select row\n"; + return; + } + + const ImageFile& rIF = dynamic_cast(GetDocument())->getImageFile(); + ImageFileArrayConst v = rIF.getArray(); + int nx = rIF.nx(); + int ny = rIF.ny(); + + if (v != NULL && yCursor < ny) { + double* pX = new double [nx]; + double* pY = new double [nx]; + for (int i = 0; i < nx; i++) { + pX[i] = i; + pY[i] = v[i][yCursor]; + } + PlotFileDocument* pPlotDoc = dynamic_cast(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT)); + if (! pPlotDoc) { + sys_error (ERR_SEVERE, "Internal error: unable to create Plot file"); + } else { + PlotFile& rPlot = pPlotDoc->getPlotFile(); + std::ostringstream title; + title << "Row " << yCursor; + rPlot.setTitle(title.str()); + rPlot.setXLabel("Column"); + rPlot.setYLabel("Pixel Value"); + rPlot.setCurveSize (2, nx); + rPlot.addColumn (0, pX); + rPlot.addColumn (1, pY); + } + delete pX; + delete pY; + } + +} + +void +ImageFileView::OnPlotCol (wxCommandEvent& event) +{ + int xCursor, yCursor; + if (! m_canvas->GetCurrentCursor (xCursor, yCursor)) { + // os << "No column selected. Please use left mouse button on image to select column\n"; + return; + } + + const ImageFile& rIF = dynamic_cast(GetDocument())->getImageFile(); + ImageFileArrayConst v = rIF.getArray(); + int nx = rIF.nx(); + int ny = rIF.ny(); + + if (v != NULL && xCursor < nx) { + double* pX = new double [ny]; + double* pY = new double [ny]; + double minVal = v[xCursor][0]; + double maxVal = minVal; + for (int i = 0; i < ny; i++) { + double y = v[xCursor][i]; + if (minVal < y) + minVal = y; + else if (maxVal > y) + maxVal = y; + pX[i] = i; + pY[i] = y; + } + PlotFileDocument* pPlotDoc = dynamic_cast(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT)); + if (! pPlotDoc) { + sys_error (ERR_SEVERE, "Internal error: unable to create Plot file"); + } else { + PlotFile& rPlot = pPlotDoc->getPlotFile(); + std::ostringstream title; + title << "Column " << xCursor; + rPlot.setTitle(title.str()); + rPlot.setXLabel("Row"); + rPlot.setYLabel("Pixel Value"); + rPlot.setCurveSize (2, nx); + rPlot.addColumn (0, pX); + rPlot.addColumn (1, pY); + } + delete pX; + delete pY; + } +} + // PhantomCanvas @@ -975,3 +1121,206 @@ ProjectionFileView::OnClose (bool deleteWindow) return true; } + + +// PlotFileCanvas +PlotFileCanvas::PlotFileCanvas (PlotFileView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style) +: wxScrolledWindow(frame, -1, pos, size, style) +{ + m_pView = v; +} + +void +PlotFileCanvas::OnDraw(wxDC& dc) +{ + if (m_pView) + m_pView->OnDraw(& dc); +} + +// PlotFileView + +IMPLEMENT_DYNAMIC_CLASS(PlotFileView, wxView) + +BEGIN_EVENT_TABLE(PlotFileView, wxView) +EVT_MENU(PJMENU_FILE_PROPERTIES, PlotFileView::OnProperties) +END_EVENT_TABLE() + +PlotFileView::PlotFileView(void) +: wxView(), m_canvas(NULL), m_frame(NULL) +{ +} + +PlotFileView::~PlotFileView(void) +{ +} + +void +PlotFileView::OnProperties (wxCommandEvent& event) +{ + const PlotFile& rProj = GetDocument()->getPlotFile(); + std::ostringstream os; + os << "Columns: " << rProj.getNumColumns() << ", Records: " << rProj.getNumRecords() << "\n"; + *theApp->getLog() << os.str().c_str(); + wxMessageDialog dialogMsg (m_frame, os.str().c_str(), "Plot File Properties", wxOK | wxICON_INFORMATION); + dialogMsg.ShowModal(); +} + + +PlotFileCanvas* +PlotFileView::CreateCanvas (wxView *view, wxFrame *parent) +{ + PlotFileCanvas* pCanvas; + int width, height; + parent->GetClientSize(&width, &height); + + pCanvas = new PlotFileCanvas (dynamic_cast(view), parent, wxPoint(0, 0), wxSize(width, height), 0); + + pCanvas->SetBackgroundColour(*wxWHITE); + pCanvas->Clear(); + + return pCanvas; +} + +wxFrame* +PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view) +{ + wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Plot Frame", wxPoint(10, 10), wxSize(500, 300), wxDEFAULT_FRAME_STYLE); + + wxMenu *file_menu = new wxMenu; + + file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom..."); + file_menu->Append(wxID_OPEN, "&Open..."); + file_menu->Append(wxID_SAVE, "&Save"); + file_menu->Append(wxID_SAVEAS, "Save &As..."); + file_menu->Append(wxID_CLOSE, "&Close"); + + file_menu->AppendSeparator(); + file_menu->Append(PJMENU_FILE_PROPERTIES, "P&roperties"); + + file_menu->AppendSeparator(); + file_menu->Append(wxID_PRINT, "&Print..."); + file_menu->Append(wxID_PRINT_SETUP, "Print &Setup..."); + file_menu->Append(wxID_PREVIEW, "Print Pre&view"); + + wxMenu *help_menu = new wxMenu; + help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents"); + help_menu->AppendSeparator(); + help_menu->Append(MAINMENU_HELP_ABOUT, "&About"); + + wxMenuBar *menu_bar = new wxMenuBar; + + menu_bar->Append(file_menu, "&File"); + menu_bar->Append(help_menu, "&Help"); + + subframe->SetMenuBar(menu_bar); + + subframe->Centre(wxBOTH); + + return subframe; +} + + +bool +PlotFileView::OnCreate(wxDocument *doc, long WXUNUSED(flags) ) +{ + m_frame = CreateChildFrame(doc, this); + SetFrame(m_frame); + + int width, height; + m_frame->GetClientSize(&width, &height); + m_frame->SetTitle ("Plot File"); + m_canvas = CreateCanvas (this, m_frame); + +#ifdef __X__ + int x, y; // X requires a forced resize + m_frame->GetSize(&x, &y); + m_frame->SetSize(-1, -1, x, y); +#endif + + m_frame->Show(true); + Activate(true); + + return true; +} + +void +PlotFileView::OnDraw (wxDC* dc) +{ + const PlotFile& rPlot = GetDocument()->getPlotFile(); + const int iNColumns = rPlot.getNumColumns(); + const int iNRecords = rPlot.getNumRecords(); + + if (iNColumns > 0 && iNRecords > 0) { + int xsize, ysize; + m_canvas->GetClientSize (&xsize, &ysize); + SGPDriver driver (dc, xsize, ysize); + SGP sgp (driver); + const PlotFile& rPhantom = GetDocument()->getPlotFile(); + EZPlot plot (sgp); + + if (! rPlot.getTitle().empty()) { + std::string s("title "); + s += rPlot.getTitle(); + plot.ezset (s); + } + if (! rPlot.getXLabel().empty()) { + std::string s("xlabel "); + s += rPlot.getXLabel(); + plot.ezset (s); + } + if (! rPlot.getYLabel().empty()) { + std::string s("ylabel "); + s += rPlot.getYLabel(); + plot.ezset (s); + } + + plot.ezset("box"); + plot.ezset("grid"); + + double* pdXaxis = new double [iNRecords]; + rPlot.getColumn (0, pdXaxis); + + double* pdY = new double [iNRecords]; + for (int iCol = 1; iCol < iNColumns; iCol++) { + rPlot.getColumn (iCol, pdY); + plot.addCurve (pdXaxis, pdY, iNRecords); + } + + delete pdXaxis; + delete pdY; + + plot.plot(); + } +} + + +void +PlotFileView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) ) +{ + if (m_canvas) + m_canvas->Refresh(); +} + +bool +PlotFileView::OnClose (bool deleteWindow) +{ + if (!GetDocument()->Close()) + return false; + + m_canvas->Clear(); + m_canvas->m_pView = NULL; + m_canvas = NULL; + wxString s(wxTheApp->GetAppName()); + if (m_frame) + m_frame->SetTitle(s); + SetFrame(NULL); + + Activate(false); + + if (deleteWindow) { + delete m_frame; + return true; + } + return true; +} +