00001 // Filename: pgWaitBar.cxx 00002 // Created by: drose (14Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "pgWaitBar.h" 00016 #include "pgMouseWatcherParameter.h" 00017 00018 #include "throw_event.h" 00019 00020 TypeHandle PGWaitBar::_type_handle; 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: PGWaitBar::Constructor 00024 // Access: Published 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 PGWaitBar:: 00028 PGWaitBar(const string &name) : PGItem(name) 00029 { 00030 set_cull_callback(); 00031 00032 _range = 100.0; 00033 _value = 0.0; 00034 _bar_state = -1; 00035 } 00036 00037 //////////////////////////////////////////////////////////////////// 00038 // Function: PGWaitBar::Destructor 00039 // Access: Public, Virtual 00040 // Description: 00041 //////////////////////////////////////////////////////////////////// 00042 PGWaitBar:: 00043 ~PGWaitBar() { 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: PGWaitBar::Copy Constructor 00048 // Access: Protected 00049 // Description: 00050 //////////////////////////////////////////////////////////////////// 00051 PGWaitBar:: 00052 PGWaitBar(const PGWaitBar ©) : 00053 PGItem(copy), 00054 _range(copy._range), 00055 _value(copy._value) 00056 { 00057 _bar_state = -1; 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function: PGWaitBar::make_copy 00062 // Access: Public, Virtual 00063 // Description: Returns a newly-allocated Node that is a shallow copy 00064 // of this one. It will be a different Node pointer, 00065 // but its internal data may or may not be shared with 00066 // that of the original Node. 00067 //////////////////////////////////////////////////////////////////// 00068 PandaNode *PGWaitBar:: 00069 make_copy() const { 00070 LightReMutexHolder holder(_lock); 00071 return new PGWaitBar(*this); 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: PGWaitBar::cull_callback 00076 // Access: Protected, Virtual 00077 // Description: This function will be called during the cull 00078 // traversal to perform any additional operations that 00079 // should be performed at cull time. This may include 00080 // additional manipulation of render state or additional 00081 // visible/invisible decisions, or any other arbitrary 00082 // operation. 00083 // 00084 // Note that this function will *not* be called unless 00085 // set_cull_callback() is called in the constructor of 00086 // the derived class. It is necessary to call 00087 // set_cull_callback() to indicated that we require 00088 // cull_callback() to be called. 00089 // 00090 // By the time this function is called, the node has 00091 // already passed the bounding-volume test for the 00092 // viewing frustum, and the node's transform and state 00093 // have already been applied to the indicated 00094 // CullTraverserData object. 00095 // 00096 // The return value is true if this node should be 00097 // visible, or false if it should be culled. 00098 //////////////////////////////////////////////////////////////////// 00099 bool PGWaitBar:: 00100 cull_callback(CullTraverser *trav, CullTraverserData &data) { 00101 LightReMutexHolder holder(_lock); 00102 update(); 00103 return PGItem::cull_callback(trav, data); 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function: PGWaitBar::setup 00108 // Access: Published 00109 // Description: Creates a PGWaitBar with the indicated dimensions, 00110 // with the indicated maximum range. 00111 //////////////////////////////////////////////////////////////////// 00112 void PGWaitBar:: 00113 setup(PN_stdfloat width, PN_stdfloat height, PN_stdfloat range) { 00114 LightReMutexHolder holder(_lock); 00115 set_state(0); 00116 clear_state_def(0); 00117 00118 set_frame(-0.5f * width, 0.5f * width, -0.5f * height, 0.5f * height); 00119 00120 PN_stdfloat bevel = 0.05f; 00121 00122 PGFrameStyle style; 00123 style.set_width(bevel, bevel); 00124 00125 style.set_color(0.6f, 0.6f, 0.6f, 1.0f); 00126 style.set_type(PGFrameStyle::T_bevel_in); 00127 set_frame_style(0, style); 00128 00129 style.set_color(0.8f, 0.8f, 0.8f, 1.0f); 00130 style.set_type(PGFrameStyle::T_bevel_out); 00131 set_bar_style(style); 00132 } 00133 00134 //////////////////////////////////////////////////////////////////// 00135 // Function: PGWaitBar::update 00136 // Access: Private 00137 // Description: Computes the appropriate size of the bar frame 00138 // according to the percentage completed. 00139 //////////////////////////////////////////////////////////////////// 00140 void PGWaitBar:: 00141 update() { 00142 LightReMutexHolder holder(_lock); 00143 int state = get_state(); 00144 00145 // If the bar was last drawn in this state and is still current, we 00146 // don't have to draw it again. 00147 if (_bar_state == state) { 00148 return; 00149 } 00150 00151 // Remove the old bar geometry, if any. 00152 _bar.remove_node(); 00153 00154 // Now create new bar geometry. 00155 if ((_value != 0.0f) && (_range != 0.0f)) { 00156 NodePath &root = get_state_def(state); 00157 nassertv(!root.is_empty()); 00158 00159 PGFrameStyle style = get_frame_style(state); 00160 const LVecBase4 &frame = get_frame(); 00161 const LVecBase2 &width = style.get_width(); 00162 00163 // Put the bar within the item's frame's border. 00164 LVecBase4 bar_frame(frame[0] + width[0], 00165 frame[1] - width[0], 00166 frame[2] + width[1], 00167 frame[3] - width[1]); 00168 00169 // And scale the bar according to our value. 00170 PN_stdfloat frac = _value / _range; 00171 frac = max(min(frac, (PN_stdfloat)1.0), (PN_stdfloat)0.0); 00172 bar_frame[1] = bar_frame[0] + frac * (bar_frame[1] - bar_frame[0]); 00173 00174 _bar = _bar_style.generate_into(root, bar_frame, 1); 00175 } 00176 00177 // Indicate that the bar is current for this state. 00178 _bar_state = state; 00179 }