anim controls in pview
This commit is contained in:
parent
d9b6585a78
commit
5bf4f3557d
|
|
@ -186,6 +186,20 @@ get_num_frames(const string &anim_name) const {
|
|||
return control->get_num_frames();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControlCollection::get_num_frames
|
||||
// Access: Public
|
||||
// Description: Returns the total number of frames in the
|
||||
// last-started animation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AnimControlCollection::
|
||||
get_num_frames() const {
|
||||
if (_last_started_control == (AnimControl *)NULL) {
|
||||
return 0;
|
||||
}
|
||||
return _last_started_control->get_num_frames();
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const AnimControlCollection &collection) {
|
||||
collection.output(out);
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ play_all() {
|
|||
Controls::const_iterator ci;
|
||||
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
|
||||
(*ci)._control->play();
|
||||
_last_started_control = (*ci)._control;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,6 +199,7 @@ play_all(int from, int to) {
|
|||
Controls::const_iterator ci;
|
||||
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
|
||||
(*ci)._control->play(from, to);
|
||||
_last_started_control = (*ci)._control;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,6 +213,7 @@ loop_all(bool restart) {
|
|||
Controls::const_iterator ci;
|
||||
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
|
||||
(*ci)._control->loop(restart);
|
||||
_last_started_control = (*ci)._control;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,6 +227,7 @@ loop_all(bool restart, int from, int to) {
|
|||
Controls::const_iterator ci;
|
||||
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
|
||||
(*ci)._control->loop(restart, from, to);
|
||||
_last_started_control = (*ci)._control;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,6 +262,7 @@ pose_all(int frame) {
|
|||
Controls::const_iterator ci;
|
||||
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
|
||||
(*ci)._control->pose(frame);
|
||||
_last_started_control = (*ci)._control;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ PUBLISHED:
|
|||
INLINE int get_frame() const;
|
||||
|
||||
INLINE int get_num_frames(const string &anim_name) const;
|
||||
INLINE int get_num_frames() const;
|
||||
|
||||
INLINE bool is_playing(const string &anim_name) const;
|
||||
INLINE bool is_playing() const;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "textNode.h"
|
||||
#include "mouseAndKeyboard.h"
|
||||
#include "mouseRecorder.h"
|
||||
#include "throw_event.h"
|
||||
|
||||
LoaderOptions PandaFramework::_loader_options;
|
||||
|
||||
|
|
@ -747,6 +748,8 @@ do_frame() {
|
|||
nassertr(_is_open, false);
|
||||
DataGraphTraverser dg_trav;
|
||||
dg_trav.traverse(_data_root.node());
|
||||
|
||||
throw_event("NewFrame");
|
||||
_event_handler.process_events();
|
||||
|
||||
if (!_screenshot_text.is_empty()) {
|
||||
|
|
@ -834,6 +837,7 @@ do_enable_default_keys() {
|
|||
define_key("i", "invert (reverse) single-sided faces", event_i, this);
|
||||
define_key("l", "toggle lighting", event_l, this);
|
||||
define_key("c", "recenter view on object", event_c, this);
|
||||
define_key("a", "toggle animation controls", event_a, this);
|
||||
define_key("shift-c", "toggle collision surfaces", event_C, this);
|
||||
define_key("shift-b", "report bounding volume", event_B, this);
|
||||
define_key("shift-l", "list hierarchy", event_L, this);
|
||||
|
|
@ -1025,6 +1029,23 @@ event_c(CPT_Event event, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaFramework::event_a
|
||||
// Access: Public, Static
|
||||
// Description: Default handler for a key: toggle the animation
|
||||
// controls.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaFramework::
|
||||
event_a(CPT_Event event, void *data) {
|
||||
if (event->get_num_parameters() == 1) {
|
||||
EventParameter param = event->get_parameter(0);
|
||||
WindowFramework *wf;
|
||||
DCAST_INTO_V(wf, param.get_ptr());
|
||||
|
||||
wf->next_anim_control();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaFramework::event_C
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ public:
|
|||
static void event_i(CPT_Event, void *data);
|
||||
static void event_l(CPT_Event, void *data);
|
||||
static void event_c(CPT_Event, void *data);
|
||||
static void event_a(CPT_Event, void *data);
|
||||
static void event_C(CPT_Event, void *data);
|
||||
static void event_B(CPT_Event, void *data);
|
||||
static void event_L(CPT_Event, void *data);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,16 @@ get_camera(int n) const {
|
|||
return _cameras[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::get_anim_controls
|
||||
// Access: Public
|
||||
// Description: Returns the current state of the anim_controls flag.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool WindowFramework::
|
||||
get_anim_controls() const {
|
||||
return _anim_controls_enabled;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::get_wireframe
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "loaderFileTypeRegistry.h"
|
||||
#include "pnmImage.h"
|
||||
#include "virtualFileSystem.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
// This is generated data for the standard texture we apply to the
|
||||
// blue triangle.
|
||||
|
|
@ -79,6 +80,8 @@ WindowFramework(PandaFramework *panda_framework) :
|
|||
_got_keyboard = false;
|
||||
_got_trackball = false;
|
||||
_got_lights = false;
|
||||
_anim_controls_enabled = false;
|
||||
_anim_index = 0;
|
||||
_wireframe_enabled = false;
|
||||
_texture_enabled = true;
|
||||
_two_sided_enabled = false;
|
||||
|
|
@ -103,6 +106,8 @@ WindowFramework(const WindowFramework ©, DisplayRegion *display_region) :
|
|||
_got_keyboard = false;
|
||||
_got_trackball = false;
|
||||
_got_lights = false;
|
||||
_anim_controls_enabled = false;
|
||||
_anim_index = 0;
|
||||
_wireframe_enabled = false;
|
||||
_texture_enabled = true;
|
||||
_two_sided_enabled = false;
|
||||
|
|
@ -345,8 +350,8 @@ get_mouse() {
|
|||
// from get_mouse() is actually a MouseWatcher, but since it
|
||||
// presents the same interface as a Mouse, no one should mind.
|
||||
|
||||
// Another advantage to using a MouseWatcher is that it the PGTop
|
||||
// of aspect2d likes it better.
|
||||
// Another advantage to using a MouseWatcher is that the PGTop of
|
||||
// aspect2d likes it better.
|
||||
PT(MouseWatcher) mw = new MouseWatcher("watcher");
|
||||
mw->set_display_region(_display_region_3d);
|
||||
_mouse = mouse.attach_new_node(mw);
|
||||
|
|
@ -674,6 +679,50 @@ loop_animations(int hierarchy_match_flags) {
|
|||
_anim_controls.loop_all(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::next_anim_control
|
||||
// Access: Public
|
||||
// Description: Rotates the animation controls through all of the
|
||||
// available animations. If the animation controls are
|
||||
// not already enabled, enables them at sets to the
|
||||
// first animation; if they are already enabled, steps
|
||||
// to the next animation; if that is the last animation,
|
||||
// disables the animation controls.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowFramework::
|
||||
next_anim_control() {
|
||||
if (_anim_controls_enabled) {
|
||||
destroy_anim_controls();
|
||||
|
||||
++_anim_index;
|
||||
if (_anim_index >= _anim_controls.get_num_anims()) {
|
||||
set_anim_controls(false);
|
||||
} else {
|
||||
create_anim_controls();
|
||||
}
|
||||
} else {
|
||||
_anim_index = 0;
|
||||
set_anim_controls(true);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::set_anim_controls
|
||||
// Access: Public
|
||||
// Description: Creates an onscreen animation slider for
|
||||
// frame-stepping through the animations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowFramework::
|
||||
set_anim_controls(bool enable) {
|
||||
_anim_controls_enabled = enable;
|
||||
if (_anim_controls_enabled) {
|
||||
create_anim_controls();
|
||||
|
||||
} else {
|
||||
destroy_anim_controls();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::split_window
|
||||
// Access: Public
|
||||
|
|
@ -1060,3 +1109,121 @@ load_image_as_model(const Filename &filename) {
|
|||
|
||||
return card_node.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::create_anim_controls
|
||||
// Access: Private
|
||||
// Description: Creates an onscreen animation slider for
|
||||
// frame-stepping through the animations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowFramework::
|
||||
create_anim_controls() {
|
||||
destroy_anim_controls();
|
||||
|
||||
AnimControl *control = _anim_controls.get_anim(_anim_index);
|
||||
nassertv(control != (AnimControl *)NULL);
|
||||
|
||||
PT(PGItem) group = new PGItem("anim_controls_group");
|
||||
PGFrameStyle style;
|
||||
style.set_type(PGFrameStyle::T_flat);
|
||||
style.set_color(0.0f, 0.0f, 0.0f, 0.3f);
|
||||
group->set_frame(-1.0f, 1.0f, 0.0f, 0.2f);
|
||||
group->set_frame_style(0, style);
|
||||
group->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
|
||||
group->set_active(true);
|
||||
|
||||
_anim_controls_group = get_aspect_2d().attach_new_node(group);
|
||||
_anim_controls_group.set_pos(0.0f, 0.0f, -0.9f);
|
||||
|
||||
if (_anim_index >= _anim_controls.get_num_anims()) {
|
||||
PT(TextNode) label = new TextNode("label");
|
||||
label->set_align(TextNode::A_center);
|
||||
label->set_text("No animation.");
|
||||
NodePath tnp = _anim_controls_group.attach_new_node(label);
|
||||
tnp.set_pos(0.0f, 0.0f, 0.07f);
|
||||
tnp.set_scale(0.1f);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PT(TextNode) label = new TextNode("anim_name");
|
||||
label->set_align(TextNode::A_left);
|
||||
label->set_text(_anim_controls.get_anim_name(_anim_index));
|
||||
NodePath tnp = _anim_controls_group.attach_new_node(label);
|
||||
tnp.set_pos(-1.0f, 0.0f, 0.15f);
|
||||
tnp.set_scale(0.05f);
|
||||
|
||||
_anim_slider = new PGSliderBar("anim_slider");
|
||||
_anim_slider->setup_slider(false, 1.8f, 0.1f, 0.01f);
|
||||
_anim_slider->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
|
||||
_anim_slider->get_thumb_button()->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
|
||||
|
||||
_anim_slider->set_range(0.0f, (float)(control->get_num_frames() - 1));
|
||||
_anim_slider->set_scroll_size(0.0f);
|
||||
_anim_slider->set_page_size(1.0f);
|
||||
NodePath snp = _anim_controls_group.attach_new_node(_anim_slider);
|
||||
snp.set_pos(0.0f, 0.0f, 0.06f);
|
||||
|
||||
_frame_number = new TextNode("frame_number");
|
||||
_frame_number->set_text_color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_frame_number->set_align(TextNode::A_center);
|
||||
_frame_number->set_text(format_string(control->get_frame()));
|
||||
NodePath fnp = NodePath(_anim_slider->get_thumb_button()).attach_new_node(_frame_number);
|
||||
fnp.set_scale(0.05f);
|
||||
fnp.set_pos(0.0f, 0.0f, -0.01f);
|
||||
|
||||
_panda_framework->get_event_handler().add_hook("NewFrame", st_update_anim_controls, (void *)this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::destroy_anim_controls
|
||||
// Access: Private
|
||||
// Description: Removes the previously-created anim controls, if any.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowFramework::
|
||||
destroy_anim_controls() {
|
||||
if (!_anim_controls_group.is_empty()) {
|
||||
_anim_controls_group.remove_node();
|
||||
|
||||
_panda_framework->get_event_handler().remove_hook("NewFrame", st_update_anim_controls, (void *)this);
|
||||
|
||||
if (_anim_index < _anim_controls.get_num_anims()) {
|
||||
AnimControl *control = _anim_controls.get_anim(_anim_index);
|
||||
nassertv(control != (AnimControl *)NULL);
|
||||
control->loop(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::update_anim_controls
|
||||
// Access: Private
|
||||
// Description: A per-frame callback to update the anim slider for
|
||||
// the current frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowFramework::
|
||||
update_anim_controls() {
|
||||
AnimControl *control = _anim_controls.get_anim(_anim_index);
|
||||
nassertv(control != (AnimControl *)NULL);
|
||||
|
||||
if (_anim_slider->is_button_down()) {
|
||||
control->pose((int)(_anim_slider->get_value() + 0.5));
|
||||
} else {
|
||||
_anim_slider->set_value((float)control->get_frame());
|
||||
}
|
||||
|
||||
_frame_number->set_text(format_string(control->get_frame()));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowFramework::st_update_anim_controls
|
||||
// Access: Private, Static
|
||||
// Description: The static event handler function.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowFramework::
|
||||
st_update_anim_controls(CPT_Event, void *data) {
|
||||
WindowFramework *self = (WindowFramework *)data;
|
||||
self->update_anim_controls();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include "typedWritableReferenceCount.h"
|
||||
#include "graphicsWindow.h"
|
||||
#include "loaderOptions.h"
|
||||
#include "pgSliderBar.h"
|
||||
#include "textNode.h"
|
||||
|
||||
class PandaFramework;
|
||||
class AmbientLight;
|
||||
|
|
@ -92,6 +94,9 @@ public:
|
|||
void loop_animations(int hierarchy_match_flags =
|
||||
PartGroup::HMF_ok_part_extra |
|
||||
PartGroup::HMF_ok_anim_extra);
|
||||
void next_anim_control();
|
||||
void set_anim_controls(bool enable);
|
||||
INLINE bool get_anim_controls() const;
|
||||
|
||||
enum BackgroundType {
|
||||
BT_other = 0,
|
||||
|
|
@ -129,6 +134,10 @@ protected:
|
|||
|
||||
private:
|
||||
PT(PandaNode) load_image_as_model(const Filename &filename);
|
||||
void create_anim_controls();
|
||||
void destroy_anim_controls();
|
||||
void update_anim_controls();
|
||||
static void st_update_anim_controls(CPT_Event, void *data);
|
||||
|
||||
private:
|
||||
PandaFramework *_panda_framework;
|
||||
|
|
@ -143,7 +152,13 @@ private:
|
|||
NodePath _render;
|
||||
NodePath _render_2d;
|
||||
NodePath _aspect_2d;
|
||||
|
||||
AnimControlCollection _anim_controls;
|
||||
bool _anim_controls_enabled;
|
||||
int _anim_index;
|
||||
NodePath _anim_controls_group;
|
||||
PT(PGSliderBar) _anim_slider;
|
||||
PT(TextNode) _frame_number;
|
||||
|
||||
NodePath _mouse;
|
||||
PT(Trackball) _trackball;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ get_click_event(const ButtonHandle &button) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::is_button_down
|
||||
// Access: Published
|
||||
// Description: Returns if the value of button_down
|
||||
// Description: Returns true if the user is currently holding the
|
||||
// mouse button down on the button, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PGButton::
|
||||
is_button_down() {
|
||||
|
|
|
|||
|
|
@ -196,9 +196,9 @@ get_value() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGSliderBar::
|
||||
set_ratio(float ratio) {
|
||||
_ratio = max(min(ratio, 1.0f), 0.0f);
|
||||
_needs_reposition = true;
|
||||
adjust();
|
||||
if (!is_button_down()) {
|
||||
internal_set_ratio(ratio);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -212,6 +212,20 @@ get_ratio() const {
|
|||
return _ratio;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGSliderBar::is_button_down
|
||||
// Access: Published
|
||||
// Description: Returns true if the user is currently holding down
|
||||
// the mouse button to manipulate the slider. When
|
||||
// true, calls to set_ratio() or set_value() will have
|
||||
// no effect.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PGSliderBar::
|
||||
is_button_down() const {
|
||||
return _dragging || _mouse_button_page ||
|
||||
(_scroll_button_held != (PGItem *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGSliderBar::set_resize_thumb
|
||||
// Access: Published
|
||||
|
|
@ -433,3 +447,17 @@ INLINE string PGSliderBar::
|
|||
get_adjust_event() const {
|
||||
return get_adjust_prefix() + get_id();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGSliderBar::internal_set_ratio
|
||||
// Access: Private
|
||||
// Description: Sets the current value of the slider, expressed in
|
||||
// the range 0 .. 1, without checking whether the user
|
||||
// is currently manipulating the slider.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGSliderBar::
|
||||
internal_set_ratio(float ratio) {
|
||||
_ratio = max(min(ratio, 1.0f), 0.0f);
|
||||
_needs_reposition = true;
|
||||
adjust();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -713,10 +713,10 @@ reposition() {
|
|||
void PGSliderBar::
|
||||
advance_scroll() {
|
||||
if (_scroll_button_held == _left_button) {
|
||||
set_ratio(max(_ratio - _scroll_ratio, 0.0f));
|
||||
internal_set_ratio(max(_ratio - _scroll_ratio, 0.0f));
|
||||
|
||||
} else if (_scroll_button_held == _right_button) {
|
||||
set_ratio(min(_ratio + _scroll_ratio, 1.0f));
|
||||
internal_set_ratio(min(_ratio + _scroll_ratio, 1.0f));
|
||||
}
|
||||
|
||||
_next_advance_time =
|
||||
|
|
@ -744,7 +744,7 @@ advance_page() {
|
|||
} else {
|
||||
t = min(_ratio + _page_ratio - _scroll_ratio, target_ratio);
|
||||
}
|
||||
set_ratio(t);
|
||||
internal_set_ratio(t);
|
||||
if (t == target_ratio) {
|
||||
// We made it; begin dragging from now on until the user releases
|
||||
// the mouse.
|
||||
|
|
@ -786,7 +786,7 @@ continue_drag() {
|
|||
}
|
||||
if (_range_x != 0.0f) {
|
||||
float current_x = mouse_to_local(_mouse_pos).dot(_axis);
|
||||
set_ratio((current_x - _drag_start_x) / _range_x);
|
||||
internal_set_ratio((current_x - _drag_start_x) / _range_x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ PUBLISHED:
|
|||
INLINE void set_ratio(float ratio);
|
||||
INLINE float get_ratio() const;
|
||||
|
||||
INLINE bool is_button_down() const;
|
||||
|
||||
INLINE void set_resize_thumb(bool resize_thumb);
|
||||
INLINE bool get_resize_thumb() const;
|
||||
|
||||
|
|
@ -118,6 +120,8 @@ protected:
|
|||
virtual void item_move(PGItem *item, const MouseWatcherParameter ¶m);
|
||||
|
||||
private:
|
||||
INLINE void internal_set_ratio(float ratio);
|
||||
|
||||
void reposition();
|
||||
void advance_scroll();
|
||||
void advance_page();
|
||||
|
|
|
|||
|
|
@ -213,7 +213,8 @@ help() {
|
|||
|
||||
" -a\n"
|
||||
" Convert and play animations, if loading an external file type\n"
|
||||
" (like .mb) directly and if the converter supports animations.\n\n"
|
||||
" (like .mb) directly and if the converter supports animations.\n"
|
||||
" Also implicitly enables the animation controls.\n\n"
|
||||
|
||||
" -c\n"
|
||||
" Automatically center models within the viewing window on startup.\n"
|
||||
|
|
@ -252,6 +253,7 @@ main(int argc, char *argv[]) {
|
|||
framework.open_framework(argc, argv);
|
||||
framework.set_window_title("Panda Viewer");
|
||||
|
||||
bool anim_controls = false;
|
||||
bool auto_center = false;
|
||||
bool show_loading = false;
|
||||
bool auto_screenshot = false;
|
||||
|
|
@ -267,6 +269,7 @@ main(int argc, char *argv[]) {
|
|||
while (flag != EOF) {
|
||||
switch (flag) {
|
||||
case 'a':
|
||||
anim_controls = true;
|
||||
PandaFramework::_loader_options.set_flags(PandaFramework::_loader_options.get_flags() | LoaderOptions::LF_convert_anim);
|
||||
break;
|
||||
|
||||
|
|
@ -353,6 +356,10 @@ main(int argc, char *argv[]) {
|
|||
return(output_screenshot(screenshotfn) ? 0:1);
|
||||
}
|
||||
|
||||
if (anim_controls) {
|
||||
window->set_anim_controls(true);
|
||||
}
|
||||
|
||||
framework.enable_default_keys();
|
||||
framework.define_key("shift-w", "open a new window", event_W, NULL);
|
||||
framework.define_key("shift-f", "flatten hierarchy", event_F, NULL);
|
||||
|
|
|
|||
Loading…
Reference in New Issue