00001
00008 #include <sstream>
00009 #include "TransferFunctionWidget.h"
00010 #include "Error.h"
00011 #include <wx/busyinfo.h>
00012
00013 #ifdef APPLE_APPLICATION_BUNDLE
00014 #include <CoreFoundation/CFBundle.h>
00015 #endif
00016
00017 const int ID_DRAWALL_CHECKBOX = wxID_HIGHEST + 42;
00018 const int ID_HISTOGRAM_CHECKBOX = wxID_HIGHEST + 43;
00019 const int ID_ACTIVEPLOT_RADIOBOX = wxID_HIGHEST + 44;
00020 const int ID_PLOTMODE_RADIOBOX = wxID_HIGHEST + 45;
00021 const int ID_SAVE_BUTTON = wxID_HIGHEST + 46;
00022 const int ID_LOAD_BUTTON = wxID_HIGHEST + 47;
00023 const int ID_REFRESH_BUTTON = wxID_HIGHEST + 48;
00024 const int ID_RESET_BUTTON = wxID_HIGHEST + 49;
00025
00026 const int MIN_DATAVALUE = 0;
00027 const int MAX_DATAVALUE = 255;
00028
00029 const int MAX_PLOT_POINTS = 64;
00030
00031 const int PLOT_PEN_WIDTH = 1;
00032 const int PLOT_PEN_STYLE = wxSOLID;
00033
00034 const int PLOT_POINT_STYLE = wxSOLID;
00035 const int PLOT_POINT_SIZE = 8;
00036 const int PLOT_POINT_SIZE_HALF = PLOT_POINT_SIZE / 2;
00037
00038 const int PLOT_WIDTH = 510;
00039 const int PLOT_HEIGHT = 128;
00040 const int PLOT_BORDER = 20;
00041
00042
00043 const unsigned char HISTOGRAM_COLOR_R = 25;
00044 const unsigned char HISTOGRAM_COLOR_G = 25;
00045 const unsigned char HISTOGRAM_COLOR_B = 25;
00046
00047
00048 const wxString SAVE_TOOLTIP = wxT("Saves the current transfer function to a file.");
00049 const wxString LOAD_TOOLTIP = wxT("Loads a transfer function form a file.");
00050 const wxString REFRESH_TOOLTIP = wxT("Updates the renderer with the transfer function (only needed if Realtime mode is disabled).");
00051 const wxString RESET_TOOLTIP = wxT("Reverts the transfer function to its original state.");
00052 const wxString DRAWALL_TOOLTIP = wxT("Draws the Red, Green, Blue and Alpha functions.");
00053 const wxString HISTOGRAM_TOOLTIP = wxT("Enables/Disables drawing of the histogram.");
00054 const wxString PLOT_MODE_TOOLTIP = wxT("Choose the tool for altering the transfer function:\n *Move - Allows for moving the individual plot points.\n *Add - Allows for new plot points to be created.\n *Remove - Allows for the removal of plot points.");
00055 const wxString PLOT_SELECTION_TOOLTIP = wxT("Select the active function.");
00056
00057 BEGIN_EVENT_TABLE(TransferFunctionPlot, wxWindow)
00058 EVT_PAINT(TransferFunctionPlot::OnPaint)
00059 EVT_MOTION(TransferFunctionPlot::MouseMove)
00060 EVT_LEFT_UP(TransferFunctionPlot::MouseLeftUp)
00061 EVT_LEFT_DOWN(TransferFunctionPlot::MouseLeftDown)
00062 EVT_MOUSEWHEEL(TransferFunctionPlot::MouseWheel)
00063 EVT_LEAVE_WINDOW(TransferFunctionPlot::MouseLeave)
00064 END_EVENT_TABLE()
00065
00066 BEGIN_EVENT_TABLE(TransferFunctionWidget, wxWindow)
00067 EVT_CHECKBOX(ID_DRAWALL_CHECKBOX, TransferFunctionWidget::OnDrawAllClick)
00068 EVT_CHECKBOX(ID_HISTOGRAM_CHECKBOX, TransferFunctionWidget::OnDrawHistogramClick)
00069 EVT_RADIOBOX(ID_ACTIVEPLOT_RADIOBOX, TransferFunctionWidget::OnActivePlotSelection)
00070 EVT_RADIOBOX(ID_PLOTMODE_RADIOBOX, TransferFunctionWidget::OnPlotModeSelection)
00071 EVT_BUTTON(ID_SAVE_BUTTON, TransferFunctionWidget::OnSaveClick)
00072 EVT_BUTTON(ID_LOAD_BUTTON, TransferFunctionWidget::OnLoadClick)
00073 EVT_BUTTON(ID_REFRESH_BUTTON, TransferFunctionWidget::OnRefreshClick)
00074 EVT_BUTTON(ID_RESET_BUTTON, TransferFunctionWidget::OnResetClick)
00075 END_EVENT_TABLE()
00076
00077
00078 TransferFunctionPlot::TransferFunctionPlot(wxWindow *parent)
00079 :
00080 wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(PLOT_WIDTH + 2*PLOT_BORDER, PLOT_HEIGHT + 2*PLOT_BORDER)),
00081 delayUpdates(false),
00082 drawHistogram(false),
00083 drawAll(false),
00084 currDataValue(0),
00085 currValue(1.0f),
00086 selectedPoint(-1),
00087 mode(MOVE),
00088 listner(NULL)
00089 {
00090 SetBackgroundColour(wxColor(0, 0, 0));
00091
00092 ResetPlot();
00093
00094 activePlot = &alphaPlot;
00095 activePlotColor = Colors::Grey;
00096
00097 #ifdef APPLE_APPLICATION_BUNDLE
00098
00099 CFBundleRef bundle = CFBundleGetMainBundle();
00100 CFURLRef gridUrl = CFBundleCopyResourceURL(bundle, CFSTR("grid"), CFSTR("bmp"), NULL);
00101
00102 CFStringRef gridStr = CFURLCopyPath(gridUrl);
00103
00104 CFIndex len = CFStringGetLength(gridStr);
00105 char *str = new char[len + 1];
00106 CFStringGetCString(gridStr, str, len + 1, kCFStringEncodingASCII);
00107
00108 bgGrid.LoadFile(str, wxBITMAP_TYPE_BMP);
00109
00110 delete [] str;
00111
00112 CFRelease(gridStr);
00113 CFRelease(gridUrl);
00114
00115 #else
00116
00117 bgGrid.LoadFile("./grid.bmp", wxBITMAP_TYPE_BMP);
00118
00119 #endif
00120
00121 wxImage im(PLOT_WIDTH - 2, PLOT_HEIGHT - 2);
00122 histogram = wxBitmap(im);
00123 }
00124
00125
00126 TransferFunctionPlot::~TransferFunctionPlot()
00127 {
00128 }
00129
00130
00131 void TransferFunctionPlot::ResetPlot()
00132 {
00133 redPlot.clear();
00134 greenPlot.clear();
00135 bluePlot.clear();
00136 alphaPlot.clear();
00137
00138 PlotPoint start;
00139 start.value = 0.0f;
00140 start.dataValue = MIN_DATAVALUE;
00141
00142 PlotPoint end;
00143 end.value = 1.0f;
00144 end.dataValue = MAX_DATAVALUE;
00145
00146 redPlot.push_back(start);
00147 greenPlot.push_back(start);
00148 bluePlot.push_back(start);
00149 alphaPlot.push_back(start);
00150
00151 redPlot.push_back(end);
00152 greenPlot.push_back(end);
00153 bluePlot.push_back(end);
00154 alphaPlot.push_back(end);
00155
00156 RefreshListner();
00157 Refresh();
00158 }
00159
00160
00161 void TransferFunctionPlot::OnPaint(wxPaintEvent& event)
00162 {
00163 wxPaintDC dc(this);
00164
00165 dc.DrawBitmap(bgGrid, 0, 0);
00166
00167 if(drawHistogram)
00168 dc.DrawBitmap(histogram, PLOT_BORDER + 2, PLOT_BORDER + 1);
00169
00170 if(drawAll)
00171 {
00172 DrawPlot(dc, redPlot, Colors::Red);
00173 DrawPlot(dc, greenPlot, Colors::Green);
00174 DrawPlot(dc, bluePlot, Colors::Blue);
00175 DrawPlot(dc, alphaPlot, Colors::Grey);
00176 }
00177
00178 if(activePlot)
00179 {
00180 DrawPlot(dc, *activePlot, activePlotColor);
00181 DrawPlotPoints(dc, *activePlot, activePlotColor);
00182 }
00183
00184 dc.SetTextForeground(wxColor(255, 255, 255));
00185 dc.SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
00186
00187 wxString val = wxT("Value = ");
00188 val << currValue;
00189
00190 wxString dataVal = wxT("Data Value = ");
00191 dataVal << currDataValue;
00192
00193 dc.DrawText(val, PLOT_BORDER, 3);
00194 dc.DrawText(dataVal, PLOT_WIDTH - 63, 3);
00195 }
00196
00197
00198 void TransferFunctionPlot::MouseMove(wxMouseEvent &m)
00199 {
00200 if(selectedPoint != -1 && mode == MOVE)
00201 {
00202 int x = m.GetX() - PLOT_BORDER;
00203 int y = m.GetY() - PLOT_BORDER;
00204
00205 int low = 0;
00206 int high = PLOT_WIDTH;
00207 if(selectedPoint == 0)
00208 {
00209 x = 0;
00210 }
00211 else
00212 {
00213 low = PlotDataValueToXCoord(activePlot->at(selectedPoint - 1).dataValue);
00214 }
00215
00216 int last = (int)activePlot->size() - 1;
00217 if(selectedPoint == last)
00218 {
00219 x = PLOT_WIDTH;
00220 }
00221 else
00222 {
00223 high = PlotDataValueToXCoord(activePlot->at(selectedPoint + 1).dataValue);
00224 }
00225
00226 x = Clamp(x, low, high);
00227 y = Clamp(y, 0, PLOT_HEIGHT);
00228
00229 PlotPoint &p = activePlot->at(selectedPoint);
00230 ScreenToPlotPoint(x, y, p);
00231
00232 currDataValue = p.dataValue;
00233 currValue = p.value;
00234
00235 Refresh();
00236
00237 if(!delayUpdates)
00238 RefreshListner();
00239 }
00240 }
00241
00242
00243 void TransferFunctionPlot::MouseLeftDown(wxMouseEvent &m)
00244 {
00245 int x = m.GetX() - PLOT_BORDER;
00246 int y = m.GetY() - PLOT_BORDER;
00247
00248 switch(mode)
00249 {
00250 case MOVE:
00251 SelectPoint(x, y);
00252 break;
00253 case ADD:
00254 AddPoint(x, y);
00255 break;
00256 case REMOVE:
00257 RemovePoint(x, y);
00258 break;
00259 };
00260
00261 PlotPoint p;
00262 ScreenToPlotPoint(x, y, p);
00263
00264 currDataValue = p.dataValue;
00265 currValue = p.value;
00266
00267 bool mouseDown = true;
00268 }
00269
00270
00271 void TransferFunctionPlot::MouseLeftUp(wxMouseEvent &m)
00272 {
00273 mouseDown = false;
00274 selectedPoint = -1;
00275 }
00276
00277
00278 void TransferFunctionPlot::MouseWheel(wxMouseEvent &m)
00279 {
00280 }
00281
00282
00283 void TransferFunctionPlot::MouseLeave(wxMouseEvent &m)
00284 {
00285 if(mouseDown && selectedPoint != -1 && !delayUpdates)
00286 RefreshListner();
00287
00288 mouseDown = false;
00289 selectedPoint = -1;
00290 }
00291
00292
00293 void TransferFunctionPlot::SetPlotMode(PlotMode m)
00294 {
00295 mode = m;
00296 }
00297
00298
00299 void TransferFunctionPlot::DrawAll(bool b)
00300 {
00301 drawAll = b;
00302 Refresh();
00303 }
00304
00305
00306 void TransferFunctionPlot::DrawHistogram(bool b)
00307 {
00308 drawHistogram = b;
00309 Refresh();
00310 }
00311
00312
00313 void TransferFunctionPlot::MakeRedActive()
00314 {
00315 selectedPoint = -1;
00316 activePlot = &redPlot;
00317 activePlotColor = Colors::Red;
00318 Refresh();
00319 }
00320
00321
00322 void TransferFunctionPlot::MakeGreenActive()
00323 {
00324 selectedPoint = -1;
00325 activePlot = &greenPlot;
00326 activePlotColor = Colors::Green;
00327 Refresh();
00328 }
00329
00330
00331 void TransferFunctionPlot::MakeBlueActive()
00332 {
00333 selectedPoint = -1;
00334 activePlot = &bluePlot;
00335 activePlotColor = Colors::Blue;
00336 Refresh();
00337 }
00338
00339
00340 void TransferFunctionPlot::MakeAlphaActive()
00341 {
00342 selectedPoint = -1;
00343 activePlot = &alphaPlot;
00344 activePlotColor = Colors::Grey;
00345 Refresh();
00346 }
00347
00348
00349 void TransferFunctionPlot::SetListner(TransferPlotChangeListner *l)
00350 {
00351 listner = l;
00352 RefreshListner();
00353 }
00354
00355
00356 void TransferFunctionPlot::UpdateTexture(TransferTexture *tex)
00357 {
00358 if(tex)
00359 tex->CreateFunction(redPlot, greenPlot, bluePlot, alphaPlot);
00360 }
00361
00362
00363 void TransferFunctionPlot::PlotPointToScreen(const PlotPoint &p, int &x, int &y) const
00364 {
00365 x = PlotDataValueToXCoord(p.dataValue);
00366 y = PlotValueToYCoord(p.value);
00367 }
00368
00369
00370 int TransferFunctionPlot::PlotDataValueToXCoord(int dataValue) const
00371 {
00372 return (int)(((float)dataValue / MAX_DATAVALUE) * PLOT_WIDTH);
00373 }
00374
00375
00376 int TransferFunctionPlot::PlotValueToYCoord(float value) const
00377 {
00378 return (int)((1.0f - value) * PLOT_HEIGHT);
00379 }
00380
00381
00382 void TransferFunctionPlot::ScreenToPlotPoint(int x, int y, PlotPoint &p) const
00383 {
00384 p.dataValue = (int)(((float)x / PLOT_WIDTH) * MAX_DATAVALUE);
00385 p.value = 1.0f - ((float)y / PLOT_HEIGHT);
00386 }
00387
00388
00389 void TransferFunctionPlot::DrawPlot(wxPaintDC &dc, const std::vector<PlotPoint> &plot, const Color4f &color) const
00390 {
00391 byte r, g, b;
00392 color.Get(r, g, b);
00393
00394 wxPen pen(wxColor(r, g, b), PLOT_PEN_WIDTH, PLOT_PEN_STYLE);
00395
00396 dc.SetPen(pen);
00397
00398 size_t len = plot.size() - 1;
00399 for(size_t i = 0; i < len; i++)
00400 {
00401 wxCoord x1, x2, y1, y2;
00402 PlotPointToScreen(plot[i], x1, y1);
00403 PlotPointToScreen(plot[i + 1], x2, y2);
00404
00405 dc.DrawLine(x1 + PLOT_BORDER, y1 + PLOT_BORDER, x2 + PLOT_BORDER, y2 + PLOT_BORDER);
00406 }
00407 }
00408
00409
00410 void TransferFunctionPlot::DrawPlotPoints(wxPaintDC &dc, const std::vector<PlotPoint> &plot, const Color4f &color) const
00411 {
00412 byte r, g, b;
00413 color.Get(r, g, b);
00414
00415 wxPen pen(wxColor(r, g, b));
00416 wxBrush brush(wxColor(r, g, b));
00417
00418 dc.SetPen(pen);
00419 dc.SetBrush(brush);
00420
00421 size_t len = plot.size();
00422 for(size_t i = 0; i < len; i++)
00423 {
00424 int x, y;
00425 PlotPointToScreen(plot[i], x, y);
00426
00427 x += PLOT_BORDER;
00428 y += PLOT_BORDER;
00429
00430 dc.DrawRectangle(x - PLOT_POINT_SIZE_HALF,
00431 y - PLOT_POINT_SIZE_HALF,
00432 PLOT_POINT_SIZE,
00433 PLOT_POINT_SIZE);
00434 }
00435 }
00436
00437
00438 bool TransferFunctionPlot::SelectPoint(wxCoord x, wxCoord y)
00439 {
00440 if(activePlot)
00441 {
00442 int sel = SelectPoint(x, y, *activePlot);
00443 selectedPoint = sel;
00444 return sel != -1;
00445 }
00446
00447 return false;
00448 }
00449
00450
00451 int TransferFunctionPlot::SelectPoint(wxCoord x, wxCoord y, const std::vector<PlotPoint> &plot) const
00452 {
00453 size_t len = plot.size();
00454 for(size_t i = 0; i < len; i++)
00455 {
00456 int x1, y1;
00457 PlotPointToScreen(plot[i], x1, y1);
00458
00459 ScreenRect r;
00460 r.x1 = x1 - PLOT_POINT_SIZE_HALF;
00461 r.x2 = x1 + PLOT_POINT_SIZE_HALF;
00462 r.y1 = y1 + PLOT_POINT_SIZE_HALF;
00463 r.y2 = y1 - PLOT_POINT_SIZE_HALF;
00464
00465 if(Inside(x, y, r))
00466 return (int)i;
00467 }
00468
00469 return -1;
00470 }
00471
00472
00473 void TransferFunctionPlot::AddPoint(wxCoord x, wxCoord y)
00474 {
00475 if(activePlot)
00476 {
00477 int len = (int)activePlot->size();
00478 if(len == MAX_PLOT_POINTS)
00479 return;
00480
00481 int xpos = 0;
00482 int curr = 0;
00483
00484 do
00485 {
00486 xpos = PlotDataValueToXCoord(activePlot->at(curr).dataValue);
00487 if(x == xpos)
00488 return;
00489
00490 curr++;
00491 } while(curr < len && x > xpos);
00492
00493 PlotPoint p;
00494 ScreenToPlotPoint(x, y, p);
00495
00496 activePlot->insert(activePlot->begin() + curr - 1, p);
00497 Refresh();
00498
00499 if(!delayUpdates)
00500 RefreshListner();
00501 }
00502 }
00503
00504
00505 void TransferFunctionPlot::RemovePoint(wxCoord x, wxCoord y)
00506 {
00507 if(activePlot)
00508 {
00509 int sel = SelectPoint(x, y, *activePlot);
00510 if(sel > 0 && sel < ((int)activePlot->size() - 1))
00511 {
00512 activePlot->erase(activePlot->begin() + sel);
00513 Refresh();
00514
00515 if(!delayUpdates)
00516 RefreshListner();
00517 }
00518 }
00519 }
00520
00521
00522 void TransferFunctionPlot::Load(const char *file)
00523 {
00524 std::ifstream f(file);
00525
00526 if(!f.is_open())
00527 {
00528 std::stringstream msg;
00529 msg << "Could not open the file '" << file << "'";
00530 ErrorMessage(msg.str().c_str());
00531 }
00532
00533 std::vector<PlotPoint> r;
00534 std::vector<PlotPoint> g;
00535 std::vector<PlotPoint> b;
00536 std::vector<PlotPoint> a;
00537
00538 std::string line;
00539
00540 while(getline(f, line))
00541 {
00542 if(line.length() == 0 || line[0] == '\n' || line[0] == '\r')
00543 continue;
00544
00545 std::stringstream data(line);
00546
00547 char type;
00548 int n;
00549
00550 if((data >> type).fail())
00551 {
00552 std::stringstream msg;
00553 msg << "The plot file '" << file << "' is improperly formatted.";
00554 ErrorMessage(msg.str().c_str());
00555 return;
00556 }
00557
00558 if((data >> n).fail() || n < 0)
00559 {
00560 std::stringstream msg;
00561 msg << "The plot file '" << file << "' is improperly formatted.";
00562 ErrorMessage(msg.str().c_str());
00563 return;
00564 }
00565
00566 std::vector<PlotPoint> *sel;
00567 switch(type)
00568 {
00569 case 'r':
00570 sel = &r;
00571 break;
00572 case 'g':
00573 sel = &g;
00574 break;
00575 case 'b':
00576 sel = &b;
00577 break;
00578 case 'a':
00579 sel = &a;
00580 break;
00581 default:
00582 {
00583 std::stringstream msg;
00584 msg << "The plot file '" << file << "' is improperly formatted.";
00585 ErrorMessage(msg.str().c_str());
00586 return;
00587 }
00588 };
00589
00590 sel->clear();
00591 bool res = LoadPlot(f, *sel, n);
00592
00593 if(sel->size() == 0)
00594 {
00595 std::stringstream msg;
00596 msg << "The plot file '" << file << "' is improperly formatted.";
00597 ErrorMessage(msg.str().c_str());
00598 return;
00599 }
00600
00601 unsigned char v0 = sel->front().dataValue;
00602 unsigned char v1 = sel->back().dataValue;
00603
00604 if( !res || v0 != MIN_DATAVALUE || v1 != MAX_DATAVALUE )
00605 {
00606 std::stringstream msg;
00607 msg << "The plot file '" << file << "' is improperly formatted.";
00608 ErrorMessage(msg.str().c_str());
00609 return;
00610 }
00611 }
00612
00613 redPlot = r;
00614 greenPlot = g;
00615 bluePlot = b;
00616 alphaPlot = a;
00617
00618 Refresh();
00619
00620 RefreshListner();
00621 }
00622
00623
00624 void TransferFunctionPlot::Save(const char *file)
00625 {
00626 std::ofstream f(file);
00627
00628 if(f.is_open())
00629 {
00630 f << "r " << redPlot.size() << "\n";
00631 SavePlot(f, redPlot);
00632
00633 f << "g " << greenPlot.size() << "\n";
00634 SavePlot(f, greenPlot);
00635
00636 f << "b " << bluePlot.size() << "\n";
00637 SavePlot(f, bluePlot);
00638
00639 f << "a " << alphaPlot.size() << "\n";
00640 SavePlot(f, alphaPlot);
00641 }
00642 else
00643 {
00644 std::stringstream msg;
00645 msg << "Could not create or open the file '" << file << "'";
00646 ErrorMessage(msg.str().c_str());
00647 }
00648 }
00649
00650
00651 void TransferFunctionPlot::RefreshListner()
00652 {
00653 if(listner)
00654 listner->TransferPlotChanged(this);
00655 }
00656
00657
00658 bool TransferFunctionPlot::LoadPlot(std::ifstream &file, std::vector<PlotPoint> &plot, int n)
00659 {
00660 for(int i = 0; i < n; i++)
00661 {
00662 int dataValue;
00663 float value;
00664
00665 if( (file >> dataValue).fail() )
00666 return false;
00667
00668 if( (file >> value).fail() )
00669 return false;
00670
00671 PlotPoint p;
00672 p.dataValue = dataValue;
00673 p.value = value;
00674 plot.push_back(p);
00675 }
00676
00677 return true;
00678 }
00679
00680
00681 void TransferFunctionPlot::SavePlot(std::ofstream &file, const std::vector<PlotPoint> &plot)
00682 {
00683 size_t len = plot.size();
00684 for(size_t i = 0; i < len; i++)
00685 {
00686
00687
00688 int dataValue = (int)plot[i].dataValue;
00689 file << dataValue << " " << plot[i].value << "\n";
00690 }
00691 }
00692
00693
00694 void TransferFunctionPlot::SetHistogram(const unsigned int *h)
00695 {
00696
00697 int maxValue = 1;
00698 for(int i = 1; i < 255; i++)
00699 {
00700 if(h[i] > h[maxValue])
00701 maxValue = i;
00702 }
00703
00704 unsigned int max = h[maxValue];
00705
00706 wxImage im;
00707 im.Create(PLOT_WIDTH - 2, PLOT_HEIGHT - 2, true);
00708
00709 int colWidth = (PLOT_WIDTH - 2) / (MAX_DATAVALUE - 2);
00710
00711 for(int i = 1; i < 255; i++)
00712 {
00713 unsigned int value = h[i];
00714 float scale = std::min((float)value / max, 1.0f);
00715 unsigned int height = (unsigned int)(scale * (PLOT_HEIGHT - 2));
00716
00717 for(unsigned int j = 0; j < height; j++)
00718 {
00719 for(int k = 0; k < colWidth; k++)
00720 {
00721 int x = PLOT_WIDTH - 2 - i*colWidth + k;
00722 int y = PLOT_HEIGHT - 3 - j;
00723 im.SetRGB(x, y, HISTOGRAM_COLOR_R, HISTOGRAM_COLOR_G, HISTOGRAM_COLOR_B);
00724 }
00725 }
00726 }
00727
00728 histogram = wxBitmap(im);
00729 Refresh();
00730 }
00731
00732
00733 TransferFunctionWidget::TransferFunctionWidget(wxWindow *parent)
00734 :
00735 wxWindow(parent, wxID_ANY)
00736 {
00737 wxSizer *topLevel = new wxBoxSizer(wxVERTICAL);
00738
00739 wxStaticBoxSizer *box = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, wxT("Transfer Function")), wxHORIZONTAL);
00740 topLevel->Add(box, 0, wxALIGN_CENTER | wxLEFT, 5);
00741
00742 wxSizer *vert = new wxBoxSizer(wxVERTICAL);
00743 wxSizer *horizontal = new wxBoxSizer(wxHORIZONTAL);
00744
00745 wxButton *save = new wxButton(this, ID_SAVE_BUTTON, wxT("Save"));
00746 wxButton *load = new wxButton(this, ID_LOAD_BUTTON, wxT("Load"));
00747 wxButton *refresh = new wxButton(this, ID_REFRESH_BUTTON, wxT("Refresh"));
00748 wxButton *reset = new wxButton(this, ID_RESET_BUTTON, wxT("Reset"));
00749
00750 save->SetToolTip(SAVE_TOOLTIP);
00751 load->SetToolTip(LOAD_TOOLTIP);
00752 refresh->SetToolTip(REFRESH_TOOLTIP);
00753 reset->SetToolTip(RESET_TOOLTIP);
00754
00755 horizontal->Add(reset);
00756 horizontal->AddSpacer(25);
00757 horizontal->Add(refresh);
00758 horizontal->AddSpacer(25);
00759 horizontal->Add(save);
00760 horizontal->AddSpacer(4);
00761 horizontal->Add(load);
00762
00763 wxSizer *top = new wxBoxSizer(wxVERTICAL);
00764 top->Add(horizontal, 0, wxALIGN_CENTER);
00765
00766 plot = new TransferFunctionPlot(this);
00767 top->Add(plot, 0, wxALL, 5);
00768 box->Add(top);
00769
00770 wxArrayString plotStrings;
00771 plotStrings.Add(wxT("Red"));
00772 plotStrings.Add(wxT("Green"));
00773 plotStrings.Add(wxT("Blue"));
00774 plotStrings.Add(wxT("Alpha"));
00775
00776 wxRadioBox *plotSelection = new wxRadioBox(this,
00777 ID_ACTIVEPLOT_RADIOBOX,
00778 wxT("Select"),
00779 wxDefaultPosition,
00780 wxDefaultSize,
00781 plotStrings,
00782 4,
00783 wxRA_SPECIFY_ROWS);
00784 plotSelection->Select(3);
00785 plotSelection->SetToolTip(PLOT_SELECTION_TOOLTIP);
00786 vert->Add(plotSelection, 0, wxALIGN_CENTER_VERTICAL);
00787 vert->AddSpacer(5);
00788
00789 drawAll = new wxCheckBox(this, ID_DRAWALL_CHECKBOX, wxT("Draw All"));
00790 drawAll->SetToolTip(DRAWALL_TOOLTIP);
00791 vert->Add(drawAll);
00792
00793 drawHistogram = new wxCheckBox(this, ID_HISTOGRAM_CHECKBOX, wxT("Histogram"));
00794 drawHistogram->SetToolTip(HISTOGRAM_TOOLTIP);
00795 vert->Add(drawHistogram);
00796
00797 box->Add(vert, 0, wxALIGN_CENTER);
00798
00799 wxArrayString plotModeStrings;
00800 plotModeStrings.Add(wxT("Move"));
00801 plotModeStrings.Add(wxT("Add"));
00802 plotModeStrings.Add(wxT("Remove"));
00803
00804 wxRadioBox *plotMode = new wxRadioBox(this,
00805 ID_PLOTMODE_RADIOBOX,
00806 wxT("Point Mode"),
00807 wxDefaultPosition,
00808 wxDefaultSize,
00809 plotModeStrings,
00810 3,
00811 wxRA_SPECIFY_COLS);
00812 plotMode->SetToolTip(PLOT_MODE_TOOLTIP);
00813 top->Add(plotMode, 0, wxALIGN_CENTER);
00814
00815 SetSizerAndFit(topLevel);
00816 Layout();
00817 Center();
00818 }
00819
00820
00821 TransferFunctionWidget::~TransferFunctionWidget()
00822 {
00823 }
00824
00825
00826 void TransferFunctionWidget::OnDrawAllClick(wxCommandEvent &e)
00827 {
00828 plot->DrawAll(e.IsChecked());
00829 }
00830
00831
00832 void TransferFunctionWidget::OnDrawHistogramClick(wxCommandEvent &e)
00833 {
00834 plot->DrawHistogram(e.IsChecked());
00835 }
00836
00837
00838 void TransferFunctionWidget::OnActivePlotSelection(wxCommandEvent &e)
00839 {
00840 int sel = e.GetSelection();
00841 switch(sel)
00842 {
00843 case 0:
00844 plot->MakeRedActive();
00845 break;
00846 case 1:
00847 plot->MakeGreenActive();
00848 break;
00849 case 2:
00850 plot->MakeBlueActive();
00851 break;
00852 case 3:
00853 plot->MakeAlphaActive();
00854 break;
00855 };
00856 }
00857
00858
00859 void TransferFunctionWidget::OnPlotModeSelection(wxCommandEvent &e)
00860 {
00861 int sel = e.GetSelection();
00862 switch(sel)
00863 {
00864 case 0:
00865 plot->SetPlotMode(TransferFunctionPlot::MOVE);
00866 break;
00867 case 1:
00868 plot->SetPlotMode(TransferFunctionPlot::ADD);
00869 break;
00870 case 2:
00871 plot->SetPlotMode(TransferFunctionPlot::REMOVE);
00872 break;
00873 };
00874 }
00875
00876
00877 void TransferFunctionWidget::OnSaveClick(wxCommandEvent &e)
00878 {
00879 wxFileDialog dialog(this,
00880 wxT("Save Plot"),
00881 wxT("./DataSets"),
00882 wxEmptyString,
00883 wxT("Plot (*.plot)|*.plot"),
00884 wxSAVE | wxOVERWRITE_PROMPT);
00885
00886 if(dialog.ShowModal() == wxID_OK)
00887 {
00888 wxWindowDisabler disableAll;
00889
00890 wxString msg = "Saving ";
00891 msg += dialog.GetFilename();
00892 msg += "...";
00893
00894 wxBusyInfo info(msg, this);
00895
00896 plot->Save(dialog.GetPath().c_str());
00897 }
00898 }
00899
00900
00901 void TransferFunctionWidget::OnLoadClick(wxCommandEvent &e)
00902 {
00903 wxFileDialog dialog(this,
00904 wxT("Load Plot"),
00905 wxT("./DataSets"),
00906 wxEmptyString,
00907 wxT("Plot (*.plot)|*.plot"),
00908 wxOPEN | wxFILE_MUST_EXIST);
00909
00910 if(dialog.ShowModal() == wxID_OK)
00911 {
00912 wxWindowDisabler disableAll;
00913
00914 wxString msg = "Loading ";
00915 msg += dialog.GetFilename();
00916 msg += "...";
00917
00918 wxBusyInfo info(msg, this);
00919
00920 plot->Load(dialog.GetPath().c_str());
00921 }
00922 }
00923
00924
00925 void TransferFunctionWidget::OnRefreshClick(wxCommandEvent &e)
00926 {
00927 plot->RefreshListner();
00928 }
00929
00930
00931 void TransferFunctionWidget::OnResetClick(wxCommandEvent &e)
00932 {
00933 plot->ResetPlot();
00934 }