00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "windowFramework.h"
00016 #include "pandaFramework.h"
00017 #include "displayRegion.h"
00018 #include "buttonThrower.h"
00019 #include "transform2sg.h"
00020 #include "dSearchPath.h"
00021 #include "filename.h"
00022 #include "loader.h"
00023 #include "keyboardButton.h"
00024 #include "geom.h"
00025 #include "geomTriangles.h"
00026 #include "geomTristrips.h"
00027 #include "geomVertexData.h"
00028 #include "geomVertexFormat.h"
00029 #include "geomVertexWriter.h"
00030 #include "texturePool.h"
00031 #include "textureAttrib.h"
00032 #include "colorAttrib.h"
00033 #include "perspectiveLens.h"
00034 #include "orthographicLens.h"
00035 #include "auto_bind.h"
00036 #include "ambientLight.h"
00037 #include "directionalLight.h"
00038 #include "lightAttrib.h"
00039 #include "boundingSphere.h"
00040 #include "deg_2_rad.h"
00041 #include "config_framework.h"
00042 #include "cullFaceAttrib.h"
00043 #include "rescaleNormalAttrib.h"
00044 #include "shadeModelAttrib.h"
00045 #include "pgTop.h"
00046 #include "geomNode.h"
00047 #include "texture.h"
00048 #include "texturePool.h"
00049 #include "loaderFileTypeRegistry.h"
00050 #include "pnmImage.h"
00051 #include "virtualFileSystem.h"
00052 #include "string_utils.h"
00053 #include "bamFile.h"
00054 #include "staticTextFont.h"
00055 #include "mouseButton.h"
00056
00057
00058
00059 #include "rock_floor.rgb_src.c"
00060
00061
00062
00063
00064 #include "shuttle_controls.bam_src.c"
00065
00066
00067
00068 static const int override_priority = 100;
00069
00070 PT(TextFont) WindowFramework::_shuttle_controls_font = NULL;
00071 TypeHandle WindowFramework::_type_handle;
00072
00073
00074
00075
00076
00077
00078 WindowFramework::
00079 WindowFramework(PandaFramework *panda_framework) :
00080 _panda_framework(panda_framework)
00081 {
00082 _alight = (AmbientLight *)NULL;
00083 _dlight = (DirectionalLight *)NULL;
00084 _got_keyboard = false;
00085 _got_trackball = false;
00086 _got_lights = false;
00087 _anim_controls_enabled = false;
00088 _anim_index = 0;
00089 _wireframe_enabled = false;
00090 _texture_enabled = true;
00091 _two_sided_enabled = false;
00092 _one_sided_reverse_enabled = false;
00093 _lighting_enabled = false;
00094 _perpixel_enabled = false;
00095 _background_type = BT_default;
00096 }
00097
00098
00099
00100
00101
00102
00103 WindowFramework::
00104 WindowFramework(const WindowFramework ©, DisplayRegion *display_region) :
00105 _panda_framework(copy._panda_framework),
00106 _window(copy._window),
00107 _display_region_3d(display_region)
00108 {
00109 _alight = (AmbientLight *)NULL;
00110 _dlight = (DirectionalLight *)NULL;
00111 _got_keyboard = false;
00112 _got_trackball = false;
00113 _got_lights = false;
00114 _anim_controls_enabled = false;
00115 _anim_index = 0;
00116 _wireframe_enabled = false;
00117 _texture_enabled = true;
00118 _two_sided_enabled = false;
00119 _one_sided_reverse_enabled = false;
00120 _lighting_enabled = false;
00121 _perpixel_enabled = false;
00122 _background_type = BT_default;
00123
00124 set_background_type(copy._background_type);
00125
00126 NodePath camera_np = make_camera();
00127 _display_region_3d->set_camera(camera_np);
00128 }
00129
00130
00131
00132
00133
00134
00135 WindowFramework::
00136 ~WindowFramework() {
00137 close_window();
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 GraphicsOutput *WindowFramework::
00147 open_window(const WindowProperties &props, int flags, GraphicsEngine *engine,
00148 GraphicsPipe *pipe, GraphicsStateGuardian *gsg) {
00149 nassertr(_window == (GraphicsOutput *)NULL, _window);
00150
00151 static int next_window_index = 1;
00152 ostringstream stream;
00153 stream << "window" << next_window_index;
00154 next_window_index++;
00155 string name = stream.str();
00156
00157 _window = 0;
00158 GraphicsOutput *winout =
00159 engine->make_output(pipe, name, 0,
00160 FrameBufferProperties::get_default(),
00161 props, flags, gsg, NULL);
00162 if (winout != (GraphicsOutput *)NULL) {
00163 _window = winout;
00164
00165
00166
00167 _display_region_3d = _window->make_display_region();
00168
00169
00170
00171 _window->set_clear_color_active(false);
00172 _window->set_clear_depth_active(false);
00173 _window->set_clear_stencil_active(false);
00174
00175
00176 NodePath camera_np = make_camera();
00177 _display_region_3d->set_camera(camera_np);
00178
00179 set_background_type(_background_type);
00180
00181 if (show_frame_rate_meter) {
00182 _frame_rate_meter = new FrameRateMeter("frame_rate_meter");
00183 _frame_rate_meter->setup_window(_window);
00184 }
00185 if (show_scene_graph_analyzer_meter) {
00186 _scene_graph_analyzer_meter = new SceneGraphAnalyzerMeter("scene_graph_analyzer_meter", get_render().node());
00187 _scene_graph_analyzer_meter->setup_window(_window);
00188 }
00189 }
00190
00191 return _window;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 void WindowFramework::
00201 close_window() {
00202 _window.clear();
00203 _camera_group.remove_node();
00204 _render.remove_node();
00205 _render_2d.remove_node();
00206 _mouse.remove_node();
00207
00208 _alight = (AmbientLight *)NULL;
00209 _dlight = (DirectionalLight *)NULL;
00210 _got_keyboard = false;
00211 _got_trackball = false;
00212 _got_lights = false;
00213
00214 _wireframe_enabled = false;
00215 _texture_enabled = true;
00216 _two_sided_enabled = false;
00217 _one_sided_reverse_enabled = false;
00218 _lighting_enabled = false;
00219 _perpixel_enabled = false;
00220
00221 if (_frame_rate_meter != (FrameRateMeter *)NULL) {
00222 _frame_rate_meter->clear_window();
00223 _frame_rate_meter = (FrameRateMeter *)NULL;
00224 }
00225 if (_scene_graph_analyzer_meter != (SceneGraphAnalyzerMeter *)NULL) {
00226 _scene_graph_analyzer_meter->clear_window();
00227 _scene_graph_analyzer_meter = (SceneGraphAnalyzerMeter *)NULL;
00228 }
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238 NodePath WindowFramework::
00239 get_camera_group() {
00240 if (_camera_group.is_empty()) {
00241 _camera_group = get_render().attach_new_node("camera_group");
00242 }
00243 return _camera_group;
00244 }
00245
00246
00247
00248
00249
00250
00251 NodePath WindowFramework::
00252 get_render() {
00253 if (_render.is_empty()) {
00254 _render = NodePath("render");
00255
00256 _render.node()->set_attrib(RescaleNormalAttrib::make_default());
00257 _render.node()->set_attrib(ShadeModelAttrib::make(ShadeModelAttrib::M_smooth));
00258
00259
00260 _render.set_two_sided(0);
00261 }
00262 return _render;
00263 }
00264
00265
00266
00267
00268
00269
00270 NodePath WindowFramework::
00271 get_render_2d() {
00272 if (_render_2d.is_empty()) {
00273 _render_2d = NodePath("render_2d");
00274
00275
00276
00277 _render_2d.set_depth_write(0);
00278 _render_2d.set_depth_test(0);
00279 _render_2d.set_material_off(1);
00280 _render_2d.set_two_sided(1);
00281
00282
00283
00284
00285
00286 PN_stdfloat l, r, b, t;
00287 _display_region_3d->get_dimensions(l, r, b, t);
00288 _display_region_2d = _window->make_mono_display_region(l, r, b, t);
00289 _display_region_2d->set_sort(10);
00290
00291
00292 PT(Camera) camera = new Camera("camera2d");
00293 NodePath camera_np = _render_2d.attach_new_node(camera);
00294
00295 PT(Lens) lens = new OrthographicLens;
00296
00297 static const PN_stdfloat left = -1.0f;
00298 static const PN_stdfloat right = 1.0f;
00299 static const PN_stdfloat bottom = -1.0f;
00300 static const PN_stdfloat top = 1.0f;
00301 lens->set_film_size(right - left, top - bottom);
00302 lens->set_film_offset((right + left) * 0.5, (top + bottom) * 0.5);
00303 lens->set_near_far(-1000, 1000);
00304
00305 camera->set_lens(lens);
00306 _display_region_2d->set_camera(camera_np);
00307 }
00308
00309 return _render_2d;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318 NodePath WindowFramework::
00319 get_aspect_2d() {
00320 if (_aspect_2d.is_empty()) {
00321 PGTop *top = new PGTop("aspect_2d");
00322 _aspect_2d = get_render_2d().attach_new_node(top);
00323
00324
00325
00326 PandaNode *mouse_node = get_mouse().node();
00327 if (mouse_node->is_of_type(MouseWatcher::get_class_type())) {
00328 top->set_mouse_watcher(DCAST(MouseWatcher, mouse_node));
00329 }
00330
00331 PN_stdfloat this_aspect_ratio = aspect_ratio;
00332 if (this_aspect_ratio == 0.0f) {
00333
00334 this_aspect_ratio = 1.0f;
00335
00336 if (_window->has_size()) {
00337 int x_size = _window->get_sbs_left_x_size();
00338 int y_size = _window->get_sbs_left_y_size();
00339 if (y_size != 0) {
00340 this_aspect_ratio = (PN_stdfloat)x_size / (PN_stdfloat)y_size;
00341 }
00342 }
00343 }
00344
00345 _aspect_2d.set_scale(1.0f / this_aspect_ratio, 1.0f, 1.0f);
00346 }
00347
00348 return _aspect_2d;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 NodePath WindowFramework::
00360 get_pixel_2d() {
00361 if (_pixel_2d.is_empty()) {
00362 PGTop *top = new PGTop("pixel_2d");
00363 _pixel_2d = get_render_2d().attach_new_node(top);
00364 _pixel_2d.set_pos(-1, 0, 1);
00365
00366 if (_window->has_size()) {
00367 int x_size = _window->get_sbs_left_x_size();
00368 int y_size = _window->get_sbs_left_y_size();
00369 if (x_size > 0){
00370 _pixel_2d.set_sx(2.0f / (float)x_size);
00371 }
00372 _pixel_2d.set_sy(1.0f);
00373 if (y_size > 0){
00374 _pixel_2d.set_sz(2.0f / (float)y_size);
00375 }
00376 }
00377 }
00378
00379 return _pixel_2d;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388 NodePath WindowFramework::
00389 get_mouse() {
00390 if (_mouse.is_empty()) {
00391 NodePath mouse = _panda_framework->get_mouse(_window);
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 PT(MouseWatcher) mw = new MouseWatcher("watcher");
00402
00403 if (_window->get_side_by_side_stereo()) {
00404
00405
00406
00407
00408
00409 mw->set_display_region(_window->get_overlay_display_region());
00410 }
00411
00412 _mouse = mouse.attach_new_node(mw);
00413 }
00414 return _mouse;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423 NodePath WindowFramework::
00424 get_button_thrower() {
00425 return _button_thrower;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 void WindowFramework::
00435 enable_keyboard() {
00436 if (_got_keyboard) {
00437 return;
00438 }
00439
00440 if (_window->is_of_type(GraphicsWindow::get_class_type()) &&
00441 DCAST(GraphicsWindow, _window)->get_num_input_devices() > 0) {
00442 NodePath mouse = get_mouse();
00443
00444
00445
00446 PT(ButtonThrower) bt = new ButtonThrower("kb-events");
00447 bt->add_parameter(EventParameter(this));
00448 ModifierButtons mods;
00449 mods.add_button(KeyboardButton::shift());
00450 mods.add_button(KeyboardButton::control());
00451 mods.add_button(KeyboardButton::alt());
00452 mods.add_button(KeyboardButton::meta());
00453 bt->set_modifier_buttons(mods);
00454 _button_thrower = mouse.attach_new_node(bt);
00455 }
00456
00457 _got_keyboard = true;
00458 }
00459
00460
00461
00462
00463
00464
00465 void WindowFramework::
00466 setup_trackball() {
00467 if (_got_trackball) {
00468 return;
00469 }
00470
00471 if (_window->is_of_type(GraphicsWindow::get_class_type()) &&
00472 DCAST(GraphicsWindow, _window)->get_num_input_devices() > 0) {
00473 NodePath mouse = get_mouse();
00474 NodePath camera = get_camera_group();
00475
00476 _trackball = new Trackball("trackball");
00477 _trackball->set_pos(LVector3::forward() * 50.0);
00478 mouse.attach_new_node(_trackball);
00479
00480 PT(Transform2SG) tball2cam = new Transform2SG("tball2cam");
00481 tball2cam->set_node(camera.node());
00482 _trackball->add_child(tball2cam);
00483 }
00484
00485 _got_trackball = true;
00486 }
00487
00488
00489
00490
00491
00492
00493
00494 void WindowFramework::
00495 center_trackball(const NodePath &object) {
00496 if (_trackball == (Trackball *)NULL) {
00497 return;
00498 }
00499
00500 PT(BoundingVolume) volume = object.get_bounds();
00501
00502 nassertv(volume != (BoundingVolume *)NULL);
00503 nassertv(volume->is_of_type(GeometricBoundingVolume::get_class_type()));
00504 CPT(GeometricBoundingVolume) gbv = DCAST(GeometricBoundingVolume, volume);
00505
00506 if (object.has_parent()) {
00507 CPT(TransformState) net_transform = object.get_parent().get_net_transform();
00508 PT(GeometricBoundingVolume) new_gbv = DCAST(GeometricBoundingVolume, gbv->make_copy());
00509 new_gbv->xform(net_transform->get_mat());
00510 gbv = new_gbv;
00511 }
00512
00513
00514 if (gbv->is_infinite()) {
00515 framework_cat.warning()
00516 << "Infinite bounding volume for " << object << "\n";
00517 return;
00518 }
00519
00520 if (gbv->is_empty()) {
00521 framework_cat.warning()
00522 << "Empty bounding volume for " << object << "\n";
00523 return;
00524 }
00525
00526
00527
00528 PT(BoundingSphere) sphere = new BoundingSphere(gbv->get_approx_center(), 0.0f);
00529 if (!sphere->extend_by(gbv)) {
00530 framework_cat.warning()
00531 << "Cannot determine bounding volume of " << object << "\n";
00532 return;
00533 }
00534
00535 LPoint3 center = sphere->get_center();
00536 PN_stdfloat radius = sphere->get_radius();
00537
00538 PN_stdfloat distance = 50.0f;
00539
00540
00541
00542
00543 Lens *lens = (Lens *)NULL;
00544 if (!_cameras.empty()) {
00545 Cameras::const_iterator ci;
00546 for (ci = _cameras.begin();
00547 ci != _cameras.end() && lens == (Lens *)NULL;
00548 ++ci) {
00549 lens = (*ci)->get_lens();
00550 }
00551 }
00552
00553 if (lens != (Lens *)NULL) {
00554 LVecBase2 fov = lens->get_fov();
00555 distance = radius / ctan(deg_2_rad(min(fov[0], fov[1]) / 2.0f));
00556
00557
00558 PN_stdfloat ideal_far_plane = distance + radius * 1.5;
00559 lens->set_far(max(lens->get_default_far(), ideal_far_plane));
00560
00561
00562 PN_stdfloat ideal_near_plane = distance - radius;
00563 lens->set_near(min(lens->get_default_near(), ideal_near_plane));
00564 }
00565
00566 _trackball->set_origin(center);
00567 _trackball->set_pos(LVector3::forward() * distance);
00568
00569
00570
00571 _trackball->set_forward_scale(distance * 0.006);
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 bool WindowFramework::
00585 load_models(const NodePath &parent, int argc, char *argv[], int first_arg) {
00586 pvector<Filename> files;
00587
00588 for (int i = first_arg; i < argc && argv[i] != (char *)NULL; i++) {
00589 files.push_back(Filename::from_os_specific(argv[i]));
00590 }
00591
00592 return load_models(parent, files);
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 bool WindowFramework::
00605 load_models(const NodePath &parent, const pvector<Filename> &files) {
00606 bool all_ok = true;
00607
00608 pvector<Filename>::const_iterator fi;
00609 for (fi = files.begin(); fi != files.end(); ++fi) {
00610 const Filename &filename = (*fi);
00611 NodePath model = load_model(parent, filename);
00612 if (model.is_empty()) {
00613 all_ok = false;
00614 }
00615 }
00616
00617 return all_ok;
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627 NodePath WindowFramework::
00628 load_model(const NodePath &parent, Filename filename) {
00629 nout << "Loading " << filename << "\n";
00630
00631
00632
00633 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00634 bool search = !(filename.is_fully_qualified() || vfs->exists(filename));
00635
00636
00637
00638 bool is_image = false;
00639 string extension = filename.get_extension();
00640 #ifdef HAVE_ZLIB
00641 if (extension == "pz") {
00642 extension = Filename(filename.get_basename_wo_extension()).get_extension();
00643 }
00644 #endif // HAVE_ZLIB
00645 if (!extension.empty()) {
00646 LoaderFileTypeRegistry *reg = LoaderFileTypeRegistry::get_global_ptr();
00647 LoaderFileType *model_type =
00648 reg->get_type_from_extension(extension);
00649 if (model_type == (LoaderFileType *)NULL) {
00650
00651
00652 if (extension == "txo" || downcase(extension) == "dds") {
00653
00654
00655 is_image = true;
00656
00657 } else {
00658 TexturePool *texture_pool = TexturePool::get_global_ptr();
00659 if (texture_pool->get_texture_type(extension) != NULL) {
00660
00661 is_image = true;
00662 }
00663 }
00664 }
00665 }
00666
00667 LoaderOptions options = PandaFramework::_loader_options;
00668 if (search) {
00669 options.set_flags(options.get_flags() | LoaderOptions::LF_search);
00670 } else {
00671 options.set_flags(options.get_flags() & ~LoaderOptions::LF_search);
00672 }
00673
00674 Loader loader;
00675 PT(PandaNode) node;
00676 if (is_image) {
00677 node = load_image_as_model(filename);
00678 } else {
00679 node = loader.load_sync(filename, options);
00680 }
00681
00682 if (node == (PandaNode *)NULL) {
00683 nout << "Unable to load " << filename << "\n";
00684 return NodePath::not_found();
00685 }
00686
00687 return parent.attach_new_node(node);
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 NodePath WindowFramework::
00699 load_default_model(const NodePath &parent) {
00700 CPT(RenderState) state = RenderState::make_empty();
00701
00702 state = state->add_attrib(ColorAttrib::make_flat(LColor(0.5, 0.5, 1.0, 1.0)));
00703
00704
00705
00706 string rock_floor_string((const char *)rock_floor, rock_floor_len);
00707 istringstream rock_floor_strm(rock_floor_string);
00708 PNMImage rock_floor_pnm;
00709 if (rock_floor_pnm.read(rock_floor_strm, "rock-floor.rgb")) {
00710 PT(Texture) tex = new Texture;
00711 tex->set_name("rock-floor.rgb");
00712 tex->load(rock_floor_pnm);
00713 tex->set_minfilter(Texture::FT_linear);
00714 tex->set_magfilter(Texture::FT_linear);
00715 state = state->add_attrib(TextureAttrib::make(tex));
00716 }
00717
00718 GeomNode *geomnode = new GeomNode("tri");
00719
00720 PT(GeomVertexData) vdata = new GeomVertexData
00721 ("tri", GeomVertexFormat::get_v3n3cpt2(),
00722 Geom::UH_static);
00723 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00724 GeomVertexWriter normal(vdata, InternalName::get_normal());
00725 GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
00726
00727 vertex.add_data3(LVertex::rfu(0.0, 0.0, 0.0));
00728 vertex.add_data3(LVertex::rfu(1.0, 0.0, 0.0));
00729 vertex.add_data3(LVertex::rfu(0.0, 0.0, 1.0));
00730
00731 normal.add_data3(LNormal::back());
00732 normal.add_data3(LNormal::back());
00733 normal.add_data3(LNormal::back());
00734
00735 texcoord.add_data2(0.0, 0.0);
00736 texcoord.add_data2(1.0, 0.0);
00737 texcoord.add_data2(0.0, 1.0);
00738
00739 PT(GeomTriangles) tri = new GeomTriangles(Geom::UH_static);
00740 tri->add_consecutive_vertices(0, 3);
00741 tri->close_primitive();
00742
00743 PT(Geom) geom = new Geom(vdata);
00744 geom->add_primitive(tri);
00745
00746 geomnode->add_geom(geom, state);
00747
00748 return parent.attach_new_node(geomnode);
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758 void WindowFramework::
00759 loop_animations(int hierarchy_match_flags) {
00760
00761
00762
00763 auto_bind(get_render().node(), _anim_controls, hierarchy_match_flags);
00764 _anim_controls.loop_all(true);
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 void WindowFramework::
00776 stagger_animations() {
00777 for (int i = 0; i < _anim_controls.get_num_anims(); ++i) {
00778 AnimControl *control = _anim_controls.get_anim(i);
00779 double r = (double)rand() / (double)RAND_MAX;
00780 r = r * 0.2 + 0.9;
00781 control->set_play_rate(r);
00782 }
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 void WindowFramework::
00796 next_anim_control() {
00797 if (_anim_controls_enabled) {
00798 destroy_anim_controls();
00799
00800 ++_anim_index;
00801 if (_anim_index >= _anim_controls.get_num_anims()) {
00802 set_anim_controls(false);
00803 } else {
00804 create_anim_controls();
00805 }
00806 } else {
00807 _anim_index = 0;
00808 set_anim_controls(true);
00809 }
00810 }
00811
00812
00813
00814
00815
00816
00817
00818 void WindowFramework::
00819 set_anim_controls(bool enable) {
00820 _anim_controls_enabled = enable;
00821 if (_anim_controls_enabled) {
00822 create_anim_controls();
00823
00824 } else {
00825 destroy_anim_controls();
00826 }
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 void WindowFramework::
00840 adjust_dimensions() {
00841 PN_stdfloat this_aspect_ratio = aspect_ratio;
00842
00843 int x_size = 0, y_size = 0;
00844 if (_window->has_size()) {
00845 x_size = _window->get_sbs_left_x_size();
00846 y_size = _window->get_sbs_left_y_size();
00847 }
00848
00849 if (this_aspect_ratio == 0.0f) {
00850
00851 this_aspect_ratio = 1.0f;
00852 if (y_size != 0) {
00853 this_aspect_ratio = (float)x_size / (float)y_size;
00854 }
00855 }
00856
00857 if (!_aspect_2d.is_empty()) {
00858 _aspect_2d.set_scale(1.0f / this_aspect_ratio, 1.0f, 1.0f);
00859 }
00860
00861 if (!_pixel_2d.is_empty()) {
00862
00863 if (x_size > 0){
00864 _pixel_2d.set_sx(2.0f / (float)x_size);
00865 }
00866 _pixel_2d.set_sy(1.0f);
00867 if (y_size > 0){
00868 _pixel_2d.set_sz(2.0f / (float)y_size);
00869 }
00870 }
00871
00872 Cameras::iterator ci;
00873 for (ci = _cameras.begin(); ci != _cameras.end(); ++ci) {
00874 Lens *lens = (*ci)->get_lens();
00875 if (lens != (Lens *)NULL) {
00876 if (y_size != 0) {
00877 lens->set_film_size(x_size, y_size);
00878 } else {
00879 lens->set_aspect_ratio(this_aspect_ratio);
00880 }
00881 }
00882 }
00883 }
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 WindowFramework *WindowFramework::
00896 split_window(SplitType split_type) {
00897 DisplayRegion *new_region = NULL;
00898
00899 if (split_type == ST_default) {
00900
00901
00902
00903 if (_display_region_3d->get_pixel_width() >
00904 _display_region_3d->get_pixel_height()) {
00905 split_type = ST_horizontal;
00906 } else {
00907 split_type = ST_vertical;
00908 }
00909 }
00910
00911 PN_stdfloat left, right, bottom, top;
00912 _display_region_3d->get_dimensions(left, right, bottom, top);
00913 new_region = _display_region_3d->get_window()->make_display_region();
00914
00915 if (split_type == ST_vertical) {
00916 _display_region_3d->set_dimensions(left, right, bottom, (top + bottom) / 2.0f);
00917 if (_display_region_2d != (DisplayRegion *)NULL) {
00918 _display_region_2d->set_dimensions(left, right, bottom, (top + bottom) / 2.0f);
00919 }
00920
00921 new_region->set_dimensions(left, right, (top + bottom) / 2.0f, top);
00922
00923 } else {
00924 _display_region_3d->set_dimensions(left, (left + right) / 2.0f, bottom, top);
00925 if (_display_region_2d != (DisplayRegion *)NULL) {
00926 _display_region_2d->set_dimensions(left, (left + right) / 2.0f, bottom, top);
00927 }
00928
00929 new_region->set_dimensions((left + right) / 2.0f, right, bottom, top);
00930 }
00931
00932 PT(WindowFramework) wf = new WindowFramework(*this, new_region);
00933 _panda_framework->_windows.push_back(wf);
00934
00935 return wf;
00936 }
00937
00938
00939
00940
00941
00942
00943
00944 void WindowFramework::
00945 set_wireframe(bool enable) {
00946 if (enable == _wireframe_enabled) {
00947 return;
00948 }
00949
00950 NodePath render = get_render();
00951
00952 if (enable) {
00953 render.set_render_mode_wireframe(override_priority);
00954 render.set_two_sided(true, override_priority);
00955 } else {
00956 render.clear_render_mode();
00957 if (!_two_sided_enabled) {
00958 render.clear_two_sided();
00959 }
00960 if (_one_sided_reverse_enabled) {
00961 CPT(RenderAttrib) attrib = CullFaceAttrib::make_reverse();
00962 render.node()->set_attrib(attrib);
00963 }
00964 }
00965
00966 _wireframe_enabled = enable;
00967 }
00968
00969
00970
00971
00972
00973
00974
00975 void WindowFramework::
00976 set_texture(bool enable) {
00977 if (enable == _texture_enabled) {
00978 return;
00979 }
00980
00981 NodePath render = get_render();
00982
00983 if (!enable) {
00984 render.set_texture_off(override_priority);
00985 } else {
00986 render.clear_texture();
00987 }
00988
00989 _texture_enabled = enable;
00990 }
00991
00992
00993
00994
00995
00996
00997
00998 void WindowFramework::
00999 set_two_sided(bool enable) {
01000 if (enable == _two_sided_enabled) {
01001 return;
01002 }
01003
01004 NodePath render = get_render();
01005
01006 if (enable) {
01007 render.set_two_sided(true, override_priority);
01008 } else {
01009 if (!_wireframe_enabled) {
01010 render.clear_two_sided();
01011 }
01012 }
01013
01014 _two_sided_enabled = enable;
01015 _one_sided_reverse_enabled = false;
01016 }
01017
01018
01019
01020
01021
01022
01023
01024
01025 void WindowFramework::
01026 set_one_sided_reverse(bool enable) {
01027 if (enable == _one_sided_reverse_enabled) {
01028 return;
01029 }
01030
01031 NodePath render = get_render();
01032
01033 if (!_wireframe_enabled) {
01034 if (enable) {
01035 CPT(RenderAttrib) attrib = CullFaceAttrib::make_reverse();
01036 render.node()->set_attrib(attrib);
01037 } else {
01038 render.clear_two_sided();
01039 }
01040 }
01041
01042 _two_sided_enabled = false;
01043 _one_sided_reverse_enabled = enable;
01044 }
01045
01046
01047
01048
01049
01050
01051 void WindowFramework::
01052 set_lighting(bool enable) {
01053 if (enable == _lighting_enabled) {
01054 return;
01055 }
01056
01057 NodePath render = get_render();
01058
01059 if (enable) {
01060 if (!_got_lights) {
01061 setup_lights();
01062 }
01063 render.set_light(_alight);
01064 render.set_light(_dlight);
01065 } else {
01066 render.clear_light();
01067 }
01068
01069 _lighting_enabled = enable;
01070 }
01071
01072
01073
01074
01075
01076
01077 void WindowFramework::
01078 set_perpixel(bool enable) {
01079 if (enable == _perpixel_enabled) {
01080 return;
01081 }
01082
01083 NodePath render = get_render();
01084
01085 if (enable) {
01086 render.set_shader_auto();
01087 } else {
01088 render.set_shader_off();
01089 }
01090
01091 _perpixel_enabled = enable;
01092 }
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 void WindowFramework::
01103 set_background_type(WindowFramework::BackgroundType type) {
01104 _background_type = type;
01105
01106 if (_display_region_3d == (DisplayRegion *)NULL) {
01107 return;
01108 }
01109
01110 switch (_background_type) {
01111 case BT_other:
01112 break;
01113
01114 case BT_default:
01115 _display_region_3d->set_clear_color_active(true);
01116 _display_region_3d->set_clear_depth_active(true);
01117 _display_region_3d->set_clear_stencil_active(true);
01118 _display_region_3d->set_clear_color(_window->get_clear_color());
01119 _display_region_3d->set_clear_depth(_window->get_clear_depth());
01120 _display_region_3d->set_clear_stencil(_window->get_clear_stencil());
01121 break;
01122
01123 case BT_black:
01124 _display_region_3d->set_clear_color_active(true);
01125 _display_region_3d->set_clear_depth_active(true);
01126 _display_region_3d->set_clear_stencil_active(true);
01127 _display_region_3d->set_clear_color(LColor(0.0f, 0.0f, 0.0f, 0.0f));
01128 _display_region_3d->set_clear_depth(1.0f);
01129 _display_region_3d->set_clear_stencil(0);
01130 break;
01131
01132 case BT_gray:
01133 _display_region_3d->set_clear_color_active(true);
01134 _display_region_3d->set_clear_depth_active(true);
01135 _display_region_3d->set_clear_stencil_active(true);
01136 _display_region_3d->set_clear_color(LColor(0.3, 0.3, 0.3, 0.0f));
01137 _display_region_3d->set_clear_depth(1.0f);
01138 _display_region_3d->set_clear_stencil(0);
01139 break;
01140
01141 case BT_white:
01142 _display_region_3d->set_clear_color_active(true);
01143 _display_region_3d->set_clear_depth_active(true);
01144 _display_region_3d->set_clear_stencil_active(true);
01145 _display_region_3d->set_clear_color(LColor(1.0f, 1.0f, 1.0f, 0.0f));
01146 _display_region_3d->set_clear_depth(1.0f);
01147 _display_region_3d->set_clear_stencil(0);
01148 break;
01149
01150 case BT_none:
01151 _display_region_3d->set_clear_color_active(false);
01152 _display_region_3d->set_clear_depth_active(false);
01153 _display_region_3d->set_clear_stencil_active(false);
01154 break;
01155 }
01156 }
01157
01158
01159
01160
01161
01162
01163
01164 TextFont *WindowFramework::
01165 get_shuttle_controls_font() {
01166 if (_shuttle_controls_font == (TextFont *)NULL) {
01167 PT(TextFont) font;
01168
01169 string shuttle_controls_string((const char *)shuttle_controls, shuttle_controls_len);
01170 istringstream in(shuttle_controls_string);
01171 BamFile bam_file;
01172 if (bam_file.open_read(in, "shuttle_controls font stream")) {
01173 PT(PandaNode) node = bam_file.read_node();
01174 if (node != (PandaNode *)NULL) {
01175 _shuttle_controls_font = new StaticTextFont(node);
01176 }
01177 }
01178 }
01179
01180 return _shuttle_controls_font;
01181 }
01182
01183
01184
01185
01186
01187
01188 NodePath WindowFramework::
01189 make_camera() {
01190
01191 PT(Camera) camera = new Camera("camera");
01192 NodePath camera_np = get_camera_group().attach_new_node(camera);
01193 _cameras.push_back(camera);
01194
01195 PT(Lens) lens = new PerspectiveLens;
01196
01197 if (aspect_ratio != 0.0) {
01198
01199 lens->set_aspect_ratio(aspect_ratio);
01200
01201 } else {
01202
01203
01204 if (_window->has_size()) {
01205 int x_size = _window->get_sbs_left_x_size();
01206 int y_size = _window->get_sbs_left_y_size();
01207 if (y_size != 0) {
01208 lens->set_film_size(x_size, y_size);
01209 }
01210 }
01211 }
01212
01213 camera->set_lens(lens);
01214
01215 return camera_np;
01216 }
01217
01218
01219
01220
01221
01222
01223
01224 void WindowFramework::
01225 setup_lights() {
01226 if (_got_lights) {
01227 return;
01228 }
01229
01230 NodePath camera_group = get_camera_group();
01231 NodePath light_group = camera_group.attach_new_node("lights");
01232
01233 AmbientLight *alight = new AmbientLight("ambient");
01234 alight->set_color(LColor(0.2, 0.2, 0.2, 1.0f));
01235 DirectionalLight *dlight = new DirectionalLight("directional");
01236 dlight->set_color(LColor(0.8f, 0.8f, 0.8f, 1.0f));
01237
01238 _alight = light_group.attach_new_node(alight);
01239 _dlight = light_group.attach_new_node(dlight);
01240 _dlight.set_hpr(-10, -20, 0);
01241
01242 _got_lights = true;
01243 }
01244
01245
01246
01247
01248
01249
01250
01251
01252 PT(PandaNode) WindowFramework::
01253 load_image_as_model(const Filename &filename) {
01254 PT(Texture) tex = TexturePool::load_texture(filename);
01255 if (tex == NULL) {
01256 return NULL;
01257 }
01258
01259
01260 tex->set_minfilter(Texture::FT_linear_mipmap_linear);
01261 tex->set_magfilter(Texture::FT_linear);
01262
01263
01264 bool has_alpha = true;
01265 LVecBase2 tex_scale = tex->get_tex_scale();
01266
01267
01268
01269 int x_size = tex->get_orig_file_x_size();
01270 int y_size = tex->get_orig_file_y_size();
01271
01272
01273 PN_stdfloat left,right,top,bottom;
01274 static const PN_stdfloat scale = 10.0;
01275 if (x_size > y_size) {
01276 left = -scale;
01277 right = scale;
01278 top = (scale * y_size) / x_size;
01279 bottom = -(scale * y_size) / x_size;
01280 } else if (y_size != 0) {
01281 left = -(scale * x_size) / y_size;
01282 right = (scale * x_size) / y_size;
01283 top = scale;
01284 bottom = -scale;
01285 } else {
01286 framework_cat.warning()
01287 << "Texture size is 0 0: " << *tex << "\n";
01288
01289 left = -scale;
01290 right = scale;
01291 top = scale;
01292 bottom = -scale;
01293 }
01294
01295 PT(GeomNode) card_node = new GeomNode("card");
01296 card_node->set_attrib(TextureAttrib::make(tex));
01297 if (has_alpha) {
01298 card_node->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
01299 }
01300
01301 bool is_3d = false;
01302 if (tex->get_texture_type() == Texture::TT_3d_texture ||
01303 tex->get_texture_type() == Texture::TT_cube_map) {
01304
01305 is_3d = true;
01306 }
01307
01308 CPT(GeomVertexFormat) vformat;
01309 if (!is_3d) {
01310
01311 vformat = GeomVertexFormat::get_v3t2();
01312
01313 } else {
01314
01315 vformat = GeomVertexFormat::register_format
01316 (new GeomVertexArrayFormat
01317 (InternalName::get_vertex(), 3,
01318 GeomEnums::NT_stdfloat, GeomEnums::C_point,
01319 InternalName::get_texcoord(), 3,
01320 GeomEnums::NT_stdfloat, GeomEnums::C_texcoord));
01321 }
01322
01323 PT(GeomVertexData) vdata = new GeomVertexData
01324 ("card", vformat, Geom::UH_static);
01325 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
01326 GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
01327
01328 if (!is_3d) {
01329
01330 vertex.add_data3(LVertex::rfu(left, 0.02, top));
01331 vertex.add_data3(LVertex::rfu(left, 0.02, bottom));
01332 vertex.add_data3(LVertex::rfu(right, 0.02, top));
01333 vertex.add_data3(LVertex::rfu(right, 0.02, bottom));
01334
01335 texcoord.add_data2(0.0f, tex_scale[1]);
01336 texcoord.add_data2(0.0f, 0.0f);
01337 texcoord.add_data2(tex_scale[0], tex_scale[1]);
01338 texcoord.add_data2(tex_scale[0], 0.0f);
01339
01340 } else {
01341
01342 vertex.add_data3(-1.0f, -1.0f, 1.0f);
01343 vertex.add_data3(-1.0f, -1.0f, -1.0f);
01344 vertex.add_data3(1.0f, -1.0f, -1.0f);
01345 vertex.add_data3(1.0f, -1.0f, 1.0f);
01346 vertex.add_data3(1.0f, 1.0f, 1.0f);
01347 vertex.add_data3(1.0f, 1.0f, -1.0f);
01348 vertex.add_data3(-1.0f, 1.0f, -1.0f);
01349 vertex.add_data3(-1.0f, 1.0f, 1.0f);
01350
01351 texcoord.add_data3(-1.0f, -1.0f, 1.0f);
01352 texcoord.add_data3(-1.0f, -1.0f, -1.0f);
01353 texcoord.add_data3(1.0f, -1.0f, -1.0f);
01354 texcoord.add_data3(1.0f, -1.0f, 1.0f);
01355 texcoord.add_data3(1.0f, 1.0f, 1.0f);
01356 texcoord.add_data3(1.0f, 1.0f, -1.0f);
01357 texcoord.add_data3(-1.0f, 1.0f, -1.0f);
01358 texcoord.add_data3(-1.0f, 1.0f, 1.0f);
01359 }
01360
01361 PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
01362
01363 if (!is_3d) {
01364
01365 strip->add_consecutive_vertices(0, 4);
01366 strip->close_primitive();
01367
01368 } else {
01369
01370 strip->add_vertex(7);
01371 strip->add_vertex(0);
01372 strip->add_vertex(4);
01373 strip->add_vertex(3);
01374 strip->close_primitive();
01375
01376 strip->add_vertex(1);
01377 strip->add_vertex(6);
01378 strip->add_vertex(2);
01379 strip->add_vertex(5);
01380 strip->close_primitive();
01381
01382 strip->add_vertex(5);
01383 strip->add_vertex(4);
01384 strip->add_vertex(2);
01385 strip->add_vertex(3);
01386 strip->add_vertex(1);
01387 strip->add_vertex(0);
01388 strip->add_vertex(6);
01389 strip->add_vertex(7);
01390 strip->add_vertex(5);
01391 strip->add_vertex(4);
01392 strip->close_primitive();
01393 }
01394
01395 PT(Geom) geom = new Geom(vdata);
01396 geom->add_primitive(strip);
01397
01398 card_node->add_geom(geom);
01399
01400 return card_node.p();
01401 }
01402
01403
01404
01405
01406
01407
01408
01409 void WindowFramework::
01410 create_anim_controls() {
01411 destroy_anim_controls();
01412
01413 PT(PGItem) group = new PGItem("anim_controls_group");
01414 PGFrameStyle style;
01415 style.set_type(PGFrameStyle::T_flat);
01416 style.set_color(0.0f, 0.0f, 0.0f, 0.3);
01417 group->set_frame(-1.0f, 1.0f, 0.0f, 0.2);
01418 group->set_frame_style(0, style);
01419 group->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
01420 group->set_active(true);
01421
01422 _anim_controls_group = get_aspect_2d().attach_new_node(group);
01423 _anim_controls_group.set_pos(0.0f, 0.0f, -0.9f);
01424
01425 if (_anim_index >= _anim_controls.get_num_anims()) {
01426 PT(TextNode) label = new TextNode("label");
01427 label->set_align(TextNode::A_center);
01428 label->set_text("No animation.");
01429 NodePath tnp = _anim_controls_group.attach_new_node(label);
01430 tnp.set_pos(0.0f, 0.0f, 0.07f);
01431 tnp.set_scale(0.1f);
01432
01433 return;
01434 }
01435
01436 AnimControl *control = _anim_controls.get_anim(_anim_index);
01437 nassertv(control != (AnimControl *)NULL);
01438
01439 PT(TextNode) label = new TextNode("anim_name");
01440 label->set_align(TextNode::A_left);
01441 label->set_text(_anim_controls.get_anim_name(_anim_index));
01442 NodePath tnp = _anim_controls_group.attach_new_node(label);
01443 tnp.set_pos(-0.95f, 0.0f, 0.15f);
01444 tnp.set_scale(0.05f);
01445
01446 _anim_slider = new PGSliderBar("anim_slider");
01447 _anim_slider->setup_slider(false, 1.9f, 0.1f, 0.005f);
01448 _anim_slider->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
01449 _anim_slider->get_thumb_button()->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
01450
01451 _anim_slider->set_range(0.0f, (PN_stdfloat)(control->get_num_frames() - 1));
01452 _anim_slider->set_scroll_size(0.0f);
01453 _anim_slider->set_page_size(1.0f);
01454 NodePath snp = _anim_controls_group.attach_new_node(_anim_slider);
01455 snp.set_pos(0.0f, 0.0f, 0.06f);
01456
01457 _frame_number = new TextNode("frame_number");
01458 _frame_number->set_text_color(0.0f, 0.0f, 0.0f, 1.0f);
01459 _frame_number->set_align(TextNode::A_center);
01460 _frame_number->set_text(format_string(control->get_frame()));
01461 NodePath fnp = NodePath(_anim_slider->get_thumb_button()).attach_new_node(_frame_number);
01462 fnp.set_scale(0.05f);
01463 fnp.set_pos(0.0f, 0.0f, -0.01f);
01464
01465 _play_rate_slider = new PGSliderBar("play_rate_slider");
01466 _play_rate_slider->setup_slider(false, 0.4, 0.05f, 0.005f);
01467 _play_rate_slider->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
01468 _play_rate_slider->get_thumb_button()->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
01469 _play_rate_slider->set_value(control->get_play_rate());
01470 NodePath pnp = _anim_controls_group.attach_new_node(_play_rate_slider);
01471 pnp.set_pos(0.75f, 0.0f, 0.15f);
01472
01473
01474
01475 setup_shuttle_button("9", 0, st_back_button);
01476 setup_shuttle_button(";", 1, st_pause_button);
01477 setup_shuttle_button("4", 2, st_play_button);
01478 setup_shuttle_button(":", 3, st_forward_button);
01479
01480 _update_anim_controls_task = new GenericAsyncTask("controls", st_update_anim_controls, (void *)this);
01481 _panda_framework->get_task_mgr().add(_update_anim_controls_task);
01482 }
01483
01484
01485
01486
01487
01488
01489 void WindowFramework::
01490 destroy_anim_controls() {
01491 if (!_anim_controls_group.is_empty()) {
01492 _anim_controls_group.remove_node();
01493
01494 _panda_framework->get_event_handler().remove_hooks_with((void *)this);
01495 if (_update_anim_controls_task != NULL) {
01496 _panda_framework->get_task_mgr().remove(_update_anim_controls_task);
01497 _update_anim_controls_task.clear();
01498 }
01499 }
01500 }
01501
01502
01503
01504
01505
01506
01507
01508 void WindowFramework::
01509 update_anim_controls() {
01510 AnimControl *control = _anim_controls.get_anim(_anim_index);
01511 nassertv(control != (AnimControl *)NULL);
01512
01513 if (_anim_slider->is_button_down()) {
01514 control->pose((int)(_anim_slider->get_value() + 0.5));
01515 } else {
01516 _anim_slider->set_value((PN_stdfloat)control->get_frame());
01517 }
01518
01519 _frame_number->set_text(format_string(control->get_frame()));
01520
01521 control->set_play_rate(_play_rate_slider->get_value());
01522 }
01523
01524
01525
01526
01527
01528
01529
01530 void WindowFramework::
01531 setup_shuttle_button(const string &label, int index,
01532 EventHandler::EventCallbackFunction *func) {
01533 PT(PGButton) button = new PGButton(label);
01534 button->set_frame(-0.05f, 0.05f, 0.0f, 0.07f);
01535
01536 PN_stdfloat bevel = 0.005f;
01537
01538 PGFrameStyle style;
01539 style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
01540 style.set_width(bevel, bevel);
01541
01542 style.set_type(PGFrameStyle::T_bevel_out);
01543 button->set_frame_style(PGButton::S_ready, style);
01544
01545 style.set_type(PGFrameStyle::T_bevel_in);
01546 button->set_frame_style(PGButton::S_depressed, style);
01547
01548 style.set_color(0.9f, 0.9f, 0.9f, 1.0f);
01549 style.set_type(PGFrameStyle::T_bevel_out);
01550 button->set_frame_style(PGButton::S_rollover, style);
01551
01552 if (get_shuttle_controls_font() != (TextFont *)NULL) {
01553 PT(TextNode) tn = new TextNode("label");
01554 tn->set_align(TextNode::A_center);
01555 tn->set_font(get_shuttle_controls_font());
01556 tn->set_text(label);
01557 tn->set_text_color(0.0f, 0.0f, 0.0f, 1.0f);
01558 LMatrix4 xform = LMatrix4::scale_mat(0.07f);
01559 xform.set_row(3, LVecBase3(0.0f, 0.0f, 0.016f));
01560 tn->set_transform(xform);
01561
01562 button->get_state_def(PGButton::S_ready).attach_new_node(tn);
01563 button->get_state_def(PGButton::S_depressed).attach_new_node(tn);
01564 button->get_state_def(PGButton::S_rollover).attach_new_node(tn);
01565 }
01566
01567 NodePath np = _anim_controls_group.attach_new_node(button);
01568 np.set_pos(0.1f * index - 0.15f, 0.0f, 0.12);
01569
01570 _panda_framework->get_event_handler().add_hook(button->get_click_event(MouseButton::one()), func, (void *)this);
01571 }
01572
01573
01574
01575
01576
01577
01578 void WindowFramework::
01579 back_button() {
01580 AnimControl *control = _anim_controls.get_anim(_anim_index);
01581 nassertv(control != (AnimControl *)NULL);
01582 control->pose(control->get_frame() - 1);
01583 }
01584
01585
01586
01587
01588
01589
01590 void WindowFramework::
01591 pause_button() {
01592 AnimControl *control = _anim_controls.get_anim(_anim_index);
01593 nassertv(control != (AnimControl *)NULL);
01594 control->stop();
01595 }
01596
01597
01598
01599
01600
01601
01602 void WindowFramework::
01603 play_button() {
01604 AnimControl *control = _anim_controls.get_anim(_anim_index);
01605 nassertv(control != (AnimControl *)NULL);
01606 control->loop(false);
01607 }
01608
01609
01610
01611
01612
01613
01614 void WindowFramework::
01615 forward_button() {
01616 AnimControl *control = _anim_controls.get_anim(_anim_index);
01617 nassertv(control != (AnimControl *)NULL);
01618 control->pose(control->get_frame() + 1);
01619 }
01620
01621
01622
01623
01624
01625
01626
01627 AsyncTask::DoneStatus WindowFramework::
01628 st_update_anim_controls(GenericAsyncTask *, void *data) {
01629 WindowFramework *self = (WindowFramework *)data;
01630 self->update_anim_controls();
01631 return AsyncTask::DS_cont;
01632 }
01633
01634
01635
01636
01637
01638
01639
01640 void WindowFramework::
01641 st_back_button(const Event *, void *data) {
01642 WindowFramework *self = (WindowFramework *)data;
01643 self->back_button();
01644 }
01645
01646
01647
01648
01649
01650
01651 void WindowFramework::
01652 st_pause_button(const Event *, void *data) {
01653 WindowFramework *self = (WindowFramework *)data;
01654 self->pause_button();
01655 }
01656
01657
01658
01659
01660
01661
01662 void WindowFramework::
01663 st_play_button(const Event *, void *data) {
01664 WindowFramework *self = (WindowFramework *)data;
01665 self->play_button();
01666 }
01667
01668
01669
01670
01671
01672
01673 void WindowFramework::
01674 st_forward_button(const Event *, void *data) {
01675 WindowFramework *self = (WindowFramework *)data;
01676 self->forward_button();
01677 }