core/vgui/vgui_adaptor.cxx
Go to the documentation of this file.
00001 // This is core/vgui/vgui_adaptor.cxx
00002 #include "vgui_adaptor.h"
00003 //:
00004 // \file
00005 // \author fsm
00006 // \brief  See vgui_adaptor.h for a description of this file.
00007 
00008 #include <vcl_cassert.h>
00009 #include <vcl_iostream.h>
00010 
00011 #include <vgui/vgui_gl.h>
00012 
00013 #include <vgui/vgui.h>
00014 #include <vgui/vgui_window.h>
00015 #include <vgui/vgui_event.h>
00016 #include <vgui/vgui_macro.h>
00017 #include <vgui/vgui_command.h>
00018 #include <vgui/vgui_dialog.h>
00019 #include <vgui/vgui_matrix_state.h>
00020 #include <vgui/vgui_tableau.h>
00021 #include <vgui/vgui_tableau_sptr.h>
00022 #include <vgui/vgui_popup_params.h>
00023 #include <vgui/internals/vgui_adaptor_tableau.h>
00024 
00025 
00026 vgui_adaptor *vgui_adaptor::current = 0;
00027 static int adaptor_count = 0;
00028 
00029 //-----------------------------------------------------------------------------
00030 //: Constructor - create a default adaptor.
00031 vgui_adaptor::vgui_adaptor()
00032   : nested_popups(false)
00033   , default_items(true)
00034   , use_double_buffering(true)
00035   , the_tableau(0)
00036 {
00037   ++adaptor_count;
00038 
00039   the_tableau = new vgui_adaptor_tableau(this);
00040   the_tableau->ref();
00041 
00042   vgui_menu sub;
00043   sub.add("Configure", new vgui_command_simple<vgui_adaptor>(this, &vgui_adaptor::config_dialog));
00044   menu.add("vgui_adaptor", sub);
00045 }
00046 
00047 //-----------------------------------------------------------------------------
00048 //: Destructor - quits application if all adaptors have been deleted.
00049 vgui_adaptor::~vgui_adaptor()
00050 {
00051   set_tableau(0);
00052   the_tableau->unref();
00053 
00054   --adaptor_count;
00055 
00056   if (adaptor_count == 0) {
00057     vcl_cerr << "All adaptors have been deleted -- calling vgui::quit()\n";
00058     vgui::quit();
00059   }
00060 }
00061 
00062 //-----------------------------------------------------------------------------#
00063 //: Get the vgui_tableau associated with this adaptor.
00064 vgui_tableau_sptr vgui_adaptor::get_tableau() const
00065 {
00066   return the_tableau->get_child();
00067 }
00068 
00069 //-----------------------------------------------------------------------------
00070 //: Set the vgui_tableau associated with this adaptor.
00071 void vgui_adaptor::set_tableau(vgui_tableau_sptr const& t)
00072 {
00073   the_tableau->set_child(t);
00074 }
00075 
00076 //-----------------------------------------------------------------------------
00077 //: Returns concatenation of the adaptor's menu with the tableau's menu.
00078 vgui_menu vgui_adaptor::get_total_popup(vgui_popup_params &params) const
00079 {
00080   // set popup_params members
00081   params.recurse = true;
00082   params.nested = nested_popups;
00083   params.defaults = default_items;
00084 
00085   vgui_menu pop(menu);
00086 
00087   if (menu.size())
00088     pop.separator();
00089 
00090   vgui_tableau_sptr tab = get_tableau();
00091   if (tab) {
00092     vgui_menu tmp;
00093     tab->get_popup(params, tmp);
00094     pop.include(tmp);
00095   }
00096 
00097   return pop;
00098 }
00099 
00100 //-----------------------------------------------------------------------------
00101 //: Pops up a dialog for changing the popup modifier and button bindings.
00102 void vgui_adaptor::config_dialog()
00103 {
00104   // table stores the correspondence between vgui modifiers and pretty names.
00105   static struct {
00106     vgui_modifier mod;
00107     char const *str;
00108   } mod_table[]={
00109     {vgui_MODIFIER_NULL, "None"},
00110     {vgui_CTRL,          "Control"},
00111     {vgui_SHIFT,         "Shift"},
00112     {vgui_ALT,           "Alt"},
00113     {vgui_META,          "Meta"}
00114   };
00115   const unsigned num_mods = sizeof(mod_table)/sizeof(mod_table[0]);
00116 
00117   // table stores the correspondence between vgui buttons and pretty names.
00118   static struct {
00119     vgui_button but;
00120     char const *str;
00121   } but_table[]={
00122     {vgui_BUTTON_NULL,   "None"},
00123     {vgui_LEFT,          "Left"},
00124     {vgui_MIDDLE,        "Middle"},
00125     {vgui_RIGHT,         "Right"}
00126   };
00127   const unsigned num_buts = sizeof(but_table)/sizeof(but_table[0]);
00128 
00129   // get current bindings :
00130   vgui_modifier popup_modifier_;
00131   vgui_button popup_button_;
00132   get_popup_bindings(popup_modifier_, popup_button_);
00133 
00134   // make choice vcl_list, using the ordering in the table,
00135   // and set the initial value of the modifier index.
00136   unsigned mod_index = 0;
00137   vcl_vector<vcl_string> mod_labels;
00138   for (unsigned i=0; i<num_mods; ++i) {
00139     if (mod_table[i].mod == popup_modifier_)
00140       mod_index = i;
00141     mod_labels.push_back(mod_table[i].str);
00142   }
00143 
00144   // make choice vcl_list, using the ordering in the table,
00145   // and set the initial value of the button index.
00146   unsigned but_index = 0;
00147   vcl_vector<vcl_string> but_labels;
00148   for (unsigned i=0; i<num_buts; ++i) {
00149     if (but_table[i].but == popup_button_)
00150       but_index = i;
00151     but_labels.push_back(but_table[i].str);
00152   }
00153 
00154 #ifdef DEBUG
00155   vcl_cerr << "mod_index " << mod_index << vcl_endl
00156            << "button_index " << but_index << vcl_endl;
00157 #endif
00158 
00159   bool nested_popups_val = nested_popups;
00160   bool default_items_val = default_items;
00161   vgui_dialog mydialog("Adaptor Config");
00162   mydialog.choice("Popup modifier", mod_labels, mod_index);
00163   mydialog.choice("Popup button",   but_labels, but_index);
00164   mydialog.checkbox("Nested popups", nested_popups_val);
00165   mydialog.checkbox("Default popup items", default_items_val);
00166 
00167   if (mydialog.ask()) {
00168     assert(mod_index < num_mods);
00169     assert(but_index < num_buts);
00170     bind_popups(mod_table[mod_index].mod, but_table[but_index].but);
00171     nested_popups = nested_popups_val;
00172     default_items = default_items_val;
00173   }
00174 }
00175 
00176 //-----------------------------------------------------------------------------
00177 //: Dispatches the given event to the tableau.
00178 //  This method performs various checks which can be performed generically for
00179 //  all tableaux. It is not the responsibility of this method to take care of
00180 //  overlay handling - the derived class must sort that out.
00181 //  The derived class must also ensure that the correct draw buffer is set.
00182 bool vgui_adaptor::dispatch_to_tableau(vgui_event const &e)
00183 {
00184   vgui_macro_report_errors;
00185 
00186   // if the event is DRAW, DRAW_OVERLAY or RESHAPE
00187   // then set the glViewport
00188   if (e.type == vgui_DRAW ||
00189       e.type == vgui_DRAW_OVERLAY ||
00190       e.type == vgui_RESHAPE) {
00191     glViewport(0, 0, get_width(), get_height());
00192 
00193   }
00194 
00195   // set projection matrices to identity
00196   vgui_matrix_state::identity_gl_matrices();
00197 
00198   vgui_macro_report_errors;
00199 
00200   // sanity check the 'origin' field :
00201   if (e.origin == 0)
00202     const_cast<vgui_event&>(e).origin = this;
00203   else
00204     assert(e.origin == this);
00205 
00206   vgui_adaptor::current = this;
00207 
00208   // send the event to the tableau :
00209   bool f = the_tableau->handle(e);
00210   vgui_macro_report_errors;
00211   glFlush();
00212   return f;
00213 }
00214 
00215 //-----------------------------------------------------------------------------
00216 vgui_window *vgui_adaptor::get_window() const
00217 {
00218   vgui_macro_warning << "get_window() not implemented\n";
00219   return 0;
00220 }
00221 
00222 //-----------------------------------------------------------------------------
00223 //: Bind the given modifier/button combination to the popup menu.
00224 void vgui_adaptor::bind_popups(vgui_modifier /*m*/, vgui_button /*b*/)
00225 {
00226   vgui_macro_warning << "bind_popups() not implemented\n";
00227 }
00228 
00229 //-----------------------------------------------------------------------------
00230 void vgui_adaptor::get_popup_bindings(vgui_modifier &, vgui_button &) const
00231 {
00232   vgui_macro_warning << "get_popup_bindings() not implemented\n";
00233 }
00234 
00235 //-----------------------------------------------------------------------------
00236 void vgui_adaptor::swap_buffers()
00237 {
00238   vgui_macro_warning << "swap_buffers() not implemented\n";
00239 }
00240 
00241 //-----------------------------------------------------------------------------
00242 void vgui_adaptor::post_message(char const *, void const *)
00243 {
00244   vgui_macro_warning << "post_message() not implemented\n";
00245 }
00246 
00247 //-----------------------------------------------------------------------------
00248 void vgui_adaptor::make_current()
00249 {
00250   vgui_macro_warning << "make_current() not implemented\n";
00251 }
00252 
00253 //-----------------------------------------------------------------------------
00254 void vgui_adaptor::post_timer(float, int)
00255 {
00256   vgui_macro_warning << "post_timer(float, int) not implemented\n";
00257 }
00258 
00259 //-----------------------------------------------------------------------------
00260 void vgui_adaptor::kill_timer(int)
00261 {
00262   vgui_macro_warning << "kill_timer(int) not implemented\n";
00263 }
00264 
00265 //-----------------------------------------------------------------------------
00266 int  vgui_adaptor::post_timer(float t)
00267 {
00268   static int counter = 0;
00269   post_timer(t, counter);
00270   return counter++;
00271 }
00272 
00273 //-----------------------------------------------------------------------------
00274 void vgui_adaptor::post_destroy()
00275 {
00276   vgui_macro_warning << "post_destroy() not implemented\n";
00277 }
00278 
00279 void vgui_adaptor::post_idle_request()
00280 {
00281   // ignore idle processing by default.
00282 }