Viewport.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright © 2009, 2010 James Legg.
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 */
00011 #include "Viewport.h"
00012 
00013 #include <Debug.h>
00014 
00015 Viewport::Viewport()
00016     :   Gtk::Table(2, 2)
00017     ,   m_h_scroll_adjustment(49.5, 0.0, 101.0, 1.5, 1.0, 1.0)
00018     ,   m_h_scroll_bar(m_h_scroll_adjustment)
00019     ,   m_v_scroll_adjustment(49.5, 0.0, 101.0, 1.5, 1.0, 1.0)
00020     ,   m_v_scroll_bar(m_v_scroll_adjustment)
00021     ,   document(0)
00022 {
00023     create();
00024 }
00025 
00026 Viewport::Viewport(Viewport & viewport)
00027     :   Gtk::Table(2, 2)
00028     ,   m_h_scroll_adjustment(49.5, 0.0, 101.0, 1.5, 1.0, 1.0)
00029     ,   m_h_scroll_bar(m_h_scroll_adjustment)
00030     ,   m_v_scroll_adjustment(49.5, 0.0, 101.0, 1.5, 1.0, 1.0)
00031     ,   m_v_scroll_bar(m_v_scroll_adjustment)
00032     ,   m_view(viewport.m_view)
00033     ,   document(viewport.document)
00034 {
00035     create();
00036 }
00037 
00038 void Viewport::create()
00039 {
00040     add_events(Gdk::SCROLL_MASK);
00041     attach(m_h_scroll_bar, 0, 1, 1, 2,
00042            Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
00043     m_h_scroll_bar.show();
00044     attach(m_v_scroll_bar, 1, 2, 0, 1,
00045            Gtk::SHRINK, Gtk::FILL | Gtk::EXPAND);
00046     m_v_scroll_bar.show();
00047     attach(m_view, 0, 1, 0, 1,
00048            Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND);
00049     m_view.show();
00050     m_h_scroll_bar.signal_change_value().connect(
00051                 sigc::mem_fun(*this, &Viewport::on_h_scrollbar_change_value));
00052     m_v_scroll_bar.signal_change_value().connect(
00053                 sigc::mem_fun(*this, &Viewport::on_v_scrollbar_change_value));
00054     m_v_scroll_bar.set_inverted();
00055 }
00056 
00057 Viewport::~Viewport()
00058 {
00059 }
00060 
00061 void Viewport::set_document(Document::Document & document_in)
00062 {
00063     document = &document_in;
00064     m_view.set_document(document_in);
00065     resize_adjustments();
00066 }
00067 
00068 void Viewport::update()
00069 {
00070     resize_adjustments();
00071     // Redraw the view to reflect the changed track.
00072     m_view.queue_draw();
00073 }
00074 
00075 void Viewport::set_angle(const ViewAngle angle)
00076 {
00077     m_view.set_angle(angle);
00078     resize_adjustments();
00079 }
00080 
00081 void Viewport::zoom_in()
00082 {
00083     m_view.set_scale(m_view.get_scale() * 1.25);
00084     resize_adjustments();
00085 }
00086 
00087 void Viewport::zoom_out()
00088 {
00089     m_view.set_scale(m_view.get_scale() * 0.8);
00090     resize_adjustments();
00091 }
00092 
00093 void Viewport::scale_to_fit()
00094 {
00095     // find the scale to fit in each direction.
00096     float scale_x = double(m_view.get_width()) /
00097                     (   m_h_scroll_adjustment.get_upper() -
00098                         m_h_scroll_adjustment.get_lower());
00099     float scale_y = double(m_view.get_height()) /
00100                     (   m_v_scroll_adjustment.get_upper() -
00101                         m_v_scroll_adjustment.get_lower());
00102     // now use the largest scale so they both fit.
00103     if (scale_x < scale_y)
00104     {
00105         m_view.set_scale(scale_x);
00106     }
00107     else
00108     {
00109         m_view.set_scale(scale_y);
00110     }
00111     
00112     resize_adjustments();
00113     // move scrollbars to the middle.
00114     double lower = m_h_scroll_adjustment.get_lower();
00115     double upper = m_h_scroll_adjustment.get_upper();
00116     double size = m_h_scroll_adjustment.get_page_size();
00117     double pos = lower + (upper - lower - size) / 2.0;
00118     m_h_scroll_adjustment.set_value(pos);
00119     on_h_scrollbar_change_value(Gtk::SCROLL_NONE, m_h_scroll_adjustment.get_value());
00120     
00121     lower = m_v_scroll_adjustment.get_lower();
00122     upper = m_v_scroll_adjustment.get_upper();
00123     size = m_v_scroll_adjustment.get_page_size();
00124     pos = lower + (upper - lower - size) / 2.0;
00125     m_v_scroll_adjustment.set_value(pos);
00126     on_v_scrollbar_change_value(Gtk::SCROLL_NONE, m_v_scroll_adjustment.get_value());
00127 }
00128 
00129 void Viewport::resize_adjustments()
00130 {
00131     // don't adjust before a document is assigned.
00132     if (!document)
00133     {
00134         DEBUG_MESSAGE("    No track to use to set scrollbar adjustments");
00135         return;
00136     }
00137     const Track::AxisAlignedBoundingBox box(document->get_track().get_path().get_bounding_box());
00138     const float scale = m_view.get_scale();
00139     // Find the half the distance across the screen.
00140     double h_offset = double(m_view.get_width()) / scale / 2.0;
00141     double v_offset = double(m_view.get_height()) / scale / 2.0;
00142     // set the page size of the adjustments to the amount shown on the screen
00143     m_h_scroll_adjustment.set_page_size(h_offset * 2.0);
00144     m_v_scroll_adjustment.set_page_size(v_offset * 2.0);
00145     // adjust step size to reflect the scale.
00146     m_h_scroll_adjustment.set_step_increment(20.0 / scale);
00147     m_v_scroll_adjustment.set_step_increment(20.0 / scale);
00148     if (box.valid())
00149     {
00150         switch (m_view.get_angle())
00151         {
00152             case View::VIEW_TOP:
00153                 m_h_scroll_adjustment.set_lower(box.get_min_x());
00154                 m_h_scroll_adjustment.set_upper(box.get_max_x());
00155                 m_v_scroll_adjustment.set_lower(box.get_min_y());
00156                 m_v_scroll_adjustment.set_upper(box.get_max_y());
00157                 // scroll bar's value is the begining of the page,
00158                 // so it is half the page size lower than the centre.
00159                 m_h_scroll_adjustment.set_value(m_view.get_centre().x() - h_offset);
00160                 m_v_scroll_adjustment.set_value(m_view.get_centre().y() - v_offset);
00161                 break;
00162             case View::VIEW_SIDE:
00163                 m_h_scroll_adjustment.set_lower(box.get_min_y());
00164                 m_h_scroll_adjustment.set_upper(box.get_max_y());
00165                 m_v_scroll_adjustment.set_lower(box.get_min_z());
00166                 m_v_scroll_adjustment.set_upper(box.get_max_z());
00167                 m_h_scroll_adjustment.set_value(m_view.get_centre().y() - h_offset);
00168                 m_v_scroll_adjustment.set_value(m_view.get_centre().z() - v_offset);
00169                 break;
00170             case View::VIEW_FRONT:
00171                 m_h_scroll_adjustment.set_lower(box.get_min_x());
00172                 m_h_scroll_adjustment.set_upper(box.get_max_x());
00173                 m_v_scroll_adjustment.set_lower(box.get_min_z());
00174                 m_v_scroll_adjustment.set_upper(box.get_max_z());
00175                 m_h_scroll_adjustment.set_value(m_view.get_centre().x() - h_offset);
00176                 m_v_scroll_adjustment.set_value(m_view.get_centre().z() - v_offset);
00177                 break;
00178         }
00179     } else {
00180         m_h_scroll_adjustment.set_lower(-30.0);
00181         m_h_scroll_adjustment.set_upper(30.0);
00182         m_v_scroll_adjustment.set_lower(-30.0);
00183         m_v_scroll_adjustment.set_upper(30.0);
00184         DEBUG_MESSAGE("    No valid bounding box for track!");
00185     }
00186     // now Update the scrollbar for the display and to emit notify signals.
00187     m_h_scroll_bar.set_adjustment(m_h_scroll_adjustment);
00188     m_v_scroll_bar.set_adjustment(m_v_scroll_adjustment);
00189     on_h_scrollbar_change_value(Gtk::SCROLL_NONE, m_h_scroll_adjustment.get_value());
00190     on_v_scrollbar_change_value(Gtk::SCROLL_NONE, m_v_scroll_adjustment.get_value());
00191 }
00192 
00193 bool Viewport::on_h_scrollbar_change_value(Gtk::ScrollType scroll, double new_value)
00194 {
00195     DEBUG_MESSAGE("Horizontal scrollbar's value changed.");
00196     btVector3 centre = m_view.get_centre();
00197     double h_offset = m_h_scroll_adjustment.get_page_size() / 2.0;
00198     switch (m_view.get_angle())
00199     {
00200         case View::VIEW_TOP:
00201             // the value of the scrollbar is the position of the left edge,
00202             // so the position of the centre is half the screen width more.
00203             centre.setX(new_value + h_offset);
00204             break;
00205         case View::VIEW_SIDE:
00206             centre.setY(new_value + h_offset);
00207             break;
00208         case View::VIEW_FRONT:
00209             centre.setX(new_value + h_offset);
00210             break;
00211     }
00212     m_view.set_centre(centre);
00213     return true;
00214 }
00215 
00216 bool Viewport::on_v_scrollbar_change_value(Gtk::ScrollType scroll, double new_value)
00217 {
00218     btVector3 centre = m_view.get_centre();
00219     double v_offset = m_v_scroll_adjustment.get_page_size() / 2.0;
00220     switch (m_view.get_angle())
00221     {
00222         case View::VIEW_TOP:
00223             centre.setY(new_value + v_offset);
00224             break;
00225         case View::VIEW_SIDE:
00226             centre.setZ(new_value + v_offset);
00227             break;
00228         case View::VIEW_FRONT:
00229             centre.setZ(new_value + v_offset);
00230             break;
00231     }
00232     m_view.set_centre(centre);
00233     return true;
00234 }
00235 
00236 bool Viewport::on_scroll_event(GdkEventScroll * event)
00237 {
00238     switch (event->direction)
00239     {
00240         case GDK_SCROLL_UP:
00241             m_v_scroll_bar.set_value(m_v_scroll_bar.get_value()
00242                     + m_v_scroll_adjustment.get_step_increment());
00243             on_v_scrollbar_change_value(Gtk::SCROLL_NONE,
00244                                         m_v_scroll_bar.get_value());
00245             break;
00246         case GDK_SCROLL_DOWN:
00247             m_v_scroll_bar.set_value(m_v_scroll_bar.get_value()
00248                     - m_v_scroll_adjustment.get_step_increment());
00249             on_v_scrollbar_change_value(Gtk::SCROLL_NONE,
00250                                         m_v_scroll_bar.get_value());
00251             break;
00252         case GDK_SCROLL_LEFT:
00253             m_h_scroll_bar.set_value(m_h_scroll_bar.get_value()
00254                     - m_h_scroll_adjustment.get_step_increment());
00255             on_h_scrollbar_change_value(Gtk::SCROLL_NONE,
00256                                         m_h_scroll_bar.get_value());
00257             break;
00258         case GDK_SCROLL_RIGHT:
00259             m_h_scroll_bar.set_value(m_h_scroll_bar.get_value()
00260                     + m_h_scroll_adjustment.get_step_increment());
00261             on_h_scrollbar_change_value(Gtk::SCROLL_NONE,
00262                                         m_h_scroll_bar.get_value());
00263             break;
00264     }
00265     return true;
00266 }
00267 
00268 void Viewport::realize_view()
00269 {
00270     m_view.realize();
00271 }
00272 
00273 sigc::signal<void, boost::shared_ptr<Document::DocumentDelta> > Viewport::signal_command()
00274 {
00275     return m_view.signal_command();
00276 }
00277 
00278 sigc::signal<void, boost::shared_ptr<Document::DocumentDelta> > Viewport::signal_preview_command()
00279 {
00280     return m_view.signal_preview_command();
00281 }
00282 
00283 sigc::signal<void> Viewport::signal_preview_cancel()
00284 {
00285     return m_view.signal_preview_cancel();
00286 }

Get Racer at SourceForge.net. Fast, secure and Free Open Source software downloads

Generated at Mon Sep 6 00:41:13 2010 by Doxygen version 1.4.7 for Racer version svn335.