gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r10373: Implement more Selection met


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10373: Implement more Selection methods.
Date: Tue, 02 Dec 2008 15:27:30 +0100
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10373
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Tue 2008-12-02 15:27:30 +0100
message:
  Implement more Selection methods.
  
  General cleaning up.
modified:
  libcore/Button.cpp
  libcore/MovieClip.cpp
  libcore/TextField.cpp
  libcore/TextField.h
  libcore/as_object.h
  libcore/as_prop_flags.h
  libcore/asobj/AsBroadcaster.cpp
  libcore/asobj/Key_as.cpp
  libcore/asobj/Selection.cpp
  libcore/asobj/Sound.cpp
  libcore/character.cpp
  libcore/character.h
  libcore/movie_root.cpp
  libcore/movie_root.h
  testsuite/actionscript.all/Selection.as
  testsuite/libcore.all/as_prop_flagsTest.cpp
  testsuite/swfdec/PASSING
    ------------------------------------------------------------
    revno: 10372.1.1
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Tue 2008-12-02 12:45:42 +0100
    message:
      Silence some debug logging.
      
      Drop onSetFocus and onKillFocus functions from TextField as these
      are now handled in movie_root.
            
      Drop unload() implementation in TextField, as it does nothing different
      from the default implementation in character. Don't remove focus on 
unload.
      
      Implement Selection.addListener, correct onSetFocus, onKillFocus events.
      
      Don't allow Buttons to receive focus, as it causes a test to fail. 
According
      to docs, they are able to, but this isn't yet tested.
    modified:
      libcore/Button.cpp
      libcore/MovieClip.cpp
      libcore/TextField.cpp
      libcore/TextField.h
      libcore/asobj/Key_as.cpp
      libcore/asobj/Selection.cpp
      libcore/asobj/Sound.cpp
      libcore/character.cpp
      libcore/character.h
      libcore/movie_root.cpp
      libcore/movie_root.h
    ------------------------------------------------------------
    revno: 10372.1.2
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Tue 2008-12-02 12:49:24 +0100
    message:
      Test passes after Selection implementation.
    modified:
      testsuite/actionscript.all/Selection.as
      testsuite/swfdec/PASSING
    ------------------------------------------------------------
    revno: 10372.1.3
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Tue 2008-12-02 14:28:29 +0100
    message:
      Split long lines.
    modified:
      libcore/as_object.h
    ------------------------------------------------------------
    revno: 10372.1.4
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Tue 2008-12-02 14:28:42 +0100
    message:
      Delegate listener handling to AsBroadcaster as required, instead of
      reimplementing.
      
      Make as_prop_flags simpler.
    modified:
      libcore/as_prop_flags.h
      libcore/asobj/AsBroadcaster.cpp
      libcore/asobj/Selection.cpp
    ------------------------------------------------------------
    revno: 10372.1.5
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Tue 2008-12-02 14:49:46 +0100
    message:
      Fix prop flags test.
    modified:
      testsuite/libcore.all/as_prop_flagsTest.cpp
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp        2008-12-01 15:16:02 +0000
+++ b/libcore/Button.cpp        2008-12-02 11:45:42 +0000
@@ -385,7 +385,7 @@
 bool
 Button::handleFocus() {
     /// Nothing to do, but can receive focus.
-    return true;
+    return false;
 }
 
 
@@ -438,7 +438,8 @@
         point  p(x, y);
         m.invert().transform(p);
 
-        for (Chars::reverse_iterator it=actChars.rbegin(), 
itE=actChars.rend(); it!=itE; ++it)
+        for (Chars::reverse_iterator it=actChars.rbegin(), itE=actChars.rend();
+                it!=itE; ++it)
         {
             character* ch = *it;
             if ( ! ch->get_visible() ) continue;
@@ -482,8 +483,7 @@
 {
     if ( isUnloaded() )
     {
-        // We dont' respond to events while unloaded
-        // See bug #22982
+        // We don't respond to events while unloaded. See bug #22982.
         log_debug("Button %s received %s button event while unloaded: ignored",
             getTarget(), event);
         return;
@@ -494,30 +494,29 @@
     // Set our mouse state (so we know how to render).
     switch (event.m_id)
     {
-    case event_id::ROLL_OUT:
-    case event_id::RELEASE_OUTSIDE:
-        new_state = UP;
-        break;
-
-    case event_id::RELEASE:
-    case event_id::ROLL_OVER:
-    case event_id::DRAG_OUT:
-    case event_id::MOUSE_UP:
-        new_state = OVER;
-        break;
-
-    case event_id::PRESS:
-    case event_id::DRAG_OVER:
-    case event_id::MOUSE_DOWN:
-        new_state = DOWN;
-        break;
-
-    default:
-        //abort();  // missed a case?
-        log_error(_("Unhandled button event %s"), event);
-        break;
-    };
-    
+        case event_id::ROLL_OUT:
+        case event_id::RELEASE_OUTSIDE:
+            new_state = UP;
+            break;
+
+        case event_id::RELEASE:
+        case event_id::ROLL_OVER:
+        case event_id::DRAG_OUT:
+        case event_id::MOUSE_UP:
+            new_state = OVER;
+            break;
+
+        case event_id::PRESS:
+        case event_id::DRAG_OVER:
+        case event_id::MOUSE_DOWN:
+            new_state = DOWN;
+            break;
+
+        default:
+            //abort();  // missed a case?
+            log_error(_("Unhandled button event %s"), event);
+            break;
+    }
     
     set_current_state(new_state);
     
@@ -606,20 +605,15 @@
     {
         //log_debug(_("Got statically-defined handler for event: %s"), event);
         mr.pushAction(code, movie_root::apDOACTION);
-        //code->execute();
     }
-    //else log_debug(_("No statically-defined handler for event: %s"), event);
 
     // Call conventional attached method.
     boost::intrusive_ptr<as_function> method =
         getUserDefinedEventHandler(event.get_function_key());
     if ( method )
     {
-        //log_debug(_("Got user-defined handler for event: %s"), event);
         mr.pushAction(method, this, movie_root::apDOACTION);
-        //call_method0(as_value(method.get()), &(get_environment()), this);
     }
-    //else log_debug(_("No statically-defined handler for event: %s"), event);
 }
 
 

=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2008-12-01 20:58:08 +0000
+++ b/libcore/MovieClip.cpp     2008-12-02 11:45:42 +0000
@@ -750,7 +750,7 @@
     }
 
     // Check for member function.
-    if( ! id.is_key_event ())
+    if (! id.is_key_event ())
     {
         boost::intrusive_ptr<as_function> method = 
             getUserDefinedEventHandler(id.get_function_key());
@@ -3121,7 +3121,7 @@
     boost::intrusive_ptr<MovieClip> movieclip =
         ensureType<MovieClip>(fn.this_ptr);
     UNUSED(movieclip);
-    log_unimpl(_("MovieClip.filters()"));
+    LOG_ONCE(log_unimpl(_("MovieClip.filters()")));
     return as_value();
 }
 

=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2008-12-01 17:19:03 +0000
+++ b/libcore/TextField.cpp     2008-12-02 11:45:42 +0000
@@ -250,15 +250,6 @@
 {
 }
 
-bool
-TextField::unload()
-{
-    // TODO: unregisterTextVariable() ?
-    on_event(event_id::KILLFOCUS);
-
-    return character::unload(); 
-}
-
 void
 TextField::removeTextField()
 {
@@ -394,14 +385,6 @@
 
     switch (id.m_id)
     {
-        case event_id::SETFOCUS:
-            onSetFocus();
-            break;
-
-        case event_id::KILLFOCUS:
-            onKillFocus();
-            break;
-
         case event_id::KEY_PRESS:
         {
             if ( getType() != typeInput ) break; // not an input field
@@ -1882,18 +1865,9 @@
     callMethod(NSV::PROP_BROADCAST_MESSAGE, met, targetVal);
 }
 
-void
-TextField::onSetFocus()
-{
-    callMethod(NSV::PROP_ON_SET_FOCUS);
-}
-
-void
-TextField::onKillFocus()
-{
-    callMethod(NSV::PROP_ON_KILL_FOCUS);
-}
-
+/// This is called by movie_root when focus is applied to this TextField.
+//
+/// The return value is true if the TextField can recieve focus.
 bool
 TextField::handleFocus()
 {
@@ -1914,13 +1888,14 @@
     return true;
 }
 
+/// This is called by movie_root when focus is removed from the
+/// current TextField.
 void
 TextField::killFocus()
 {
     if ( ! m_has_focus ) return; // nothing to do
 
     set_invalidated();
-
     m_has_focus = false;
 
     movie_root& root = _vm.getRoot();

=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h       2008-12-01 15:16:02 +0000
+++ b/libcore/TextField.h       2008-12-02 11:45:42 +0000
@@ -148,14 +148,6 @@
        // See dox in character.h
        bool pointInShape(boost::int32_t x, boost::int32_t y) const;
 
-       /// See dox in character::unload (character.h)
-       //
-       /// NOTE: TextField (TextField) never has
-       ///       an onUnload event, so we always return false
-       ///       here. (TODO: verify this)
-       ///
-       bool unload();
-
        /// Return true if the 'background' should be drawn
        bool getDrawBackground() const;
 
@@ -473,17 +465,11 @@
        virtual bool handleFocus();
 
        /// Kill focus 
-       void killFocus();
+       virtual void killFocus();
 
        /// Call this function when willing to invoke the onChanged event 
handler
        void onChanged();
 
-       /// Call this function when willing to invoke the onSetFocus event 
handler
-       void onSetFocus();
-
-       /// Call this function when willing to invoke the onKillFocus event 
handler
-       void onKillFocus();
-
        /// The actual text.
     //
     /// Because we have to deal with non-ascii characters (129-255), this

=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h       2008-10-27 19:52:42 +0000
+++ b/libcore/as_object.h       2008-12-02 13:28:29 +0000
@@ -139,21 +139,17 @@
        PropertyList _members;
 
        /// Don't allow implicit copy, must think about behaviour
-       as_object& operator=(const as_object&)
-       {
-               abort();
-               return *this;
-       }
+       as_object& operator=(const as_object&);
 
        /// \brief
-       /// Find an existing property for update, only scaning the inheritance 
chain for
-       /// getter/setters or statics.
+       /// Find an existing property for update, only scanning the
+    /// inheritance chain for getter/setters or statics.
        //
-       /// NOTE: updatable here doesn't mean the property isn't protected from 
update
-       ///       but only that a set_member will NOT create a new property 
(either
-       ///       completely new or as an override).
+       /// NOTE: updatable here doesn't mean the property isn't protected
+    /// from update but only that a set_member will NOT create a new
+    /// property (either completely new or as an override).
        ///
-       /// @returns a propery if found, NULL if not found
+       /// @returns a property if found, NULL if not found
        ///          or not visible in current VM version
        ///
        Property* findUpdatableProperty(string_table::key name, 
@@ -318,7 +314,7 @@
        /// The id of the namespace to which this member belongs. 0 is a 
wildcard
        /// and will be matched by anything not asking for a specific namespace.
        void init_member(const std::string& name, const as_value& val, 
-               int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum, 
+               int flags = as_prop_flags::dontDelete | 
as_prop_flags::dontEnum, 
                string_table::key nsname = 0);
 
        /// Initialize a member value by key
@@ -381,7 +377,8 @@
        /// The id of the namespace to which this member belongs. 0 is a 
wildcard
        /// and will be matched by anything not asking for a specific namespace.
        void init_property(const std::string& key, as_function& getter,
-               as_function& setter, int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+               as_function& setter,
+        int flags = as_prop_flags::dontDelete | as_prop_flags::dontEnum,
                string_table::key nsname = 0);
 
        /// \brief
@@ -411,7 +408,8 @@
        /// The id of the namespace to which this member belongs. 0 is a 
wildcard
        /// and will be matched by anything not asking for a specific namespace.
        void init_property(const std::string& key, as_c_function_ptr getter,
-               as_c_function_ptr setter, int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+               as_c_function_ptr setter,
+        int flags = as_prop_flags::dontDelete | as_prop_flags::dontEnum,
                string_table::key nsname = 0);
 
        /// \brief
@@ -440,7 +438,8 @@
        /// The id of the namespace to which this member belongs. 0 is a 
wildcard
        /// and will be matched by anything not asking for a specific namespace.
        void init_property(string_table::key key, as_function& getter,
-               as_function& setter, int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+               as_function& setter,
+        int flags = as_prop_flags::dontDelete | as_prop_flags::dontEnum,
                string_table::key nsname = 0);
 
        /// \brief
@@ -469,7 +468,8 @@
        /// The id of the namespace to which this member belongs. 0 is a 
wildcard
        /// and will be matched by anything not asking for a specific namespace.
        void init_property(string_table::key key, as_c_function_ptr getter,
-               as_c_function_ptr setter, int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+               as_c_function_ptr setter,
+        int flags = as_prop_flags::dontDelete | as_prop_flags::dontEnum,
                string_table::key nsname = 0);
 
 
@@ -498,8 +498,7 @@
        /// and will be matched by anything not asking for a specific namespace.
        ///
        bool init_destructive_property(string_table::key key, as_function& 
getter,
-               int flags=as_prop_flags::dontEnum,
-               string_table::key nsname = 0);
+               int flags = as_prop_flags::dontEnum, string_table::key nsname = 
0);
 
        /// \brief
        /// Initialize a destructive getter property
@@ -525,9 +524,9 @@
        /// The id of the namespace to which this member belongs. 0 is a 
wildcard
        /// and will be matched by anything not asking for a specific namespace.
        ///
-       bool init_destructive_property(string_table::key key, as_c_function_ptr 
getter,
-               int flags=as_prop_flags::dontEnum,
-               string_table::key nsname = 0);
+       bool init_destructive_property(string_table::key key,
+            as_c_function_ptr getter, int flags = as_prop_flags::dontEnum,
+                   string_table::key nsname = 0);
 
 
        /// \brief
@@ -557,11 +556,12 @@
     ///
     ///
        void init_readonly_property(const std::string& key, as_function& getter,
-                       int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+                       int flags = as_prop_flags::dontDelete | 
as_prop_flags::dontEnum,
                        string_table::key nsname = 0);
 
-       void init_readonly_property(const string_table::key& key, as_function& 
getter,
-                       int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+       void init_readonly_property(const string_table::key& key,
+            as_function& getter,
+                       int flags = as_prop_flags::dontDelete | 
as_prop_flags::dontEnum,
                        string_table::key nsname = 0);
 
        /// Use this method for read-only properties.
@@ -588,12 +588,14 @@
     ///     0 is a wildcard and will be matched by anything not asking
     ///     for a specific namespace.
     ///
-       void init_readonly_property(const std::string& key, as_c_function_ptr 
getter,
-                       int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+       void init_readonly_property(const std::string& key,
+            as_c_function_ptr getter,
+                       int flags = as_prop_flags::dontDelete | 
as_prop_flags::dontEnum,
                        string_table::key nsname = 0);
 
-       void init_readonly_property(const string_table::key& key, 
as_c_function_ptr getter,
-                       int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+       void init_readonly_property(const string_table::key& key,
+            as_c_function_ptr getter,
+            int flags = as_prop_flags::dontDelete | as_prop_flags::dontEnum,
                        string_table::key nsname = 0);
 
        /// \brief
@@ -727,9 +729,12 @@
        ///
        as_value callMethod(string_table::key name);
        as_value callMethod(string_table::key name, const as_value& arg0);
-       as_value callMethod(string_table::key name, const as_value& arg0, const 
as_value& arg1);
-       as_value callMethod(string_table::key name, const as_value& arg0, const 
as_value& arg1, const as_value& arg2);
-       as_value callMethod(string_table::key name, const as_value& arg0, const 
as_value& arg1, const as_value& arg2, const as_value& arg3);
+       as_value callMethod(string_table::key name, const as_value& arg0,
+            const as_value& arg1);
+       as_value callMethod(string_table::key name, const as_value& arg0,
+            const as_value& arg1, const as_value& arg2);
+       as_value callMethod(string_table::key name, const as_value& arg0,
+            const as_value& arg1, const as_value& arg2, const as_value& arg3);
 
        /// Delete a property of this object, unless protected from deletion.
        //
@@ -752,7 +757,8 @@
        ///     - (true, false) : property protected from deletion
        ///     - (true, true) : property successfully deleted
        ///
-       virtual std::pair<bool,bool> delProperty(string_table::key name, 
string_table::key nsname = 0);
+       virtual std::pair<bool,bool> delProperty(string_table::key name,
+            string_table::key nsname = 0);
 
        /// Get this object's own named property, if existing.
        //
@@ -771,7 +777,8 @@
        ///     a Property pointer, or NULL if this object doesn't
        ///     contain the named property.
        ///
-       Property* getOwnProperty(string_table::key name, string_table::key 
nsname = 0);
+       Property* getOwnProperty(string_table::key name,
+            string_table::key nsname = 0);
 
        /// Return true if this object has the named property
        //
@@ -781,13 +788,15 @@
        ///     case *sensitive* from SWF7 up.
        ///
        /// @param nsname
-       ///     The id of the namespace to which this member belongs. 0 is a 
wildcard
-       ///     and will be matched by anything not asking for a specific 
namespace.
+       ///     The id of the namespace to which this member belongs.
+    ///     0 is a wildcard and will be matched by anything not asking
+    ///     for a specific namespace.
        ///
        /// @return
        ///     true if the object has the property, false otherwise.
        ///
-       virtual bool hasOwnProperty(string_table::key name, string_table::key 
nsname = 0);
+       virtual bool hasOwnProperty(string_table::key name,
+            string_table::key nsname = 0);
 
        /// Get a property from this object (or a prototype) by ordering index.
        ///
@@ -840,7 +849,9 @@
        /// Cast to a sprite, or return NULL
        virtual MovieClip* to_movie() { return NULL; }
 
-       const MovieClip* to_movie() const { return 
const_cast<as_object*>(this)->to_movie(); }
+    const MovieClip* to_movie() const {
+        return const_cast<as_object*>(this)->to_movie();
+    }
 
        /// Cast to a as_function, or return NULL
        virtual as_function* to_function() { return NULL; }
@@ -848,7 +859,9 @@
        /// Cast to a character, or return NULL
        virtual character* to_character() { return NULL; }
 
-       const character* to_character() const { return 
const_cast<as_object*>(this)->to_character(); }
+       const character* to_character() const {
+        return const_cast<as_object*>(this)->to_character();
+    }
 
        /// Return true if this is a Date object.
        //
@@ -975,7 +988,8 @@
        ///     reference as first argument and a const as_value reference
        ///     as second argument.
        ///
-       virtual void visitNonHiddenPropertyValues(AbstractPropertyVisitor& 
visitor) const;
+       virtual void visitNonHiddenPropertyValues(AbstractPropertyVisitor& 
visitor)
+        const;
 
        /// \brief
        /// Add a getter/setter property, if no member already has
@@ -1023,7 +1037,8 @@
        /// public: set_member("__proto__", anyting)
        /// will do just the same
        ///
-       void set_prototype(boost::intrusive_ptr<as_object> proto, int 
flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum);
+       void set_prototype(boost::intrusive_ptr<as_object> proto,
+            int flags=as_prop_flags::dontDelete | as_prop_flags::dontEnum);
 
        std::string asPropName(string_table::key name);
        
@@ -1034,8 +1049,6 @@
 
        static as_value valueof_method(const fn_call& fn);
 
-       /// @} Common ActionScript getter-setters for characters
-       
 protected:
 
        /// Enumerate any non-proper properties

=== modified file 'libcore/as_prop_flags.h'
--- a/libcore/as_prop_flags.h   2008-05-06 07:39:53 +0000
+++ b/libcore/as_prop_flags.h   2008-12-02 13:28:42 +0000
@@ -75,7 +75,8 @@
        }
 
        /// Constructor
-       as_prop_flags(const bool read_only, const bool dont_delete, const bool 
dont_enum)
+       as_prop_flags(const bool read_only, const bool dont_delete,
+            const bool dont_enum)
                :
                _flags(((read_only) ? readOnly : 0) |
                                ((dont_delete) ? dontDelete : 0) |
@@ -102,7 +103,7 @@
        /// Get "static" flag
        bool get_static() const
        {
-           return (_flags & staticProp) ? true : false;
+           return (_flags & staticProp);
        }
 
        /// Set "static" flag
@@ -114,7 +115,7 @@
        /// Get "read-only" flag 
        bool get_read_only() const
        {
-           return (((_flags & readOnly) != 0) ? true : false);
+           return (_flags & readOnly);
        }
 
        /// Set "read-only" flag 
@@ -126,7 +127,7 @@
        /// Get "don't delete" flag
        bool get_dont_delete() const
        {
-           return (((_flags & dontDelete) != 0) ? true : false);
+           return (_flags & dontDelete);
        }
 
        /// Set "don't delete" flag
@@ -138,7 +139,7 @@
        /// Get "don't enum" flag
        bool get_dont_enum() const
        {
-           return (((_flags & dontEnum) != 0) ? true : false);
+           return (_flags & dontEnum);
        }
 
        /// Set "don't enum" flag
@@ -177,17 +178,9 @@
        int get_flags() const { return _flags; }
 
        /// Get "protected" flag
-       bool get_is_protected() const { return (_flags & isProtected) ? true : 
false; }
-
-       /// Set "protected" flag
-       //
-       void set_is_protected(const bool is_protected)
-       {
-               if (is_protected)
-                       _flags |= isProtected;
-               else
-                       _flags &= ~isProtected;
-       }
+       bool get_is_protected() const {
+        return (_flags & isProtected);
+    }
 
        /// set the numerical flags value (return the new value )
        /// If unlocked is false, you cannot un-protect from over-write,

=== modified file 'libcore/asobj/AsBroadcaster.cpp'
--- a/libcore/asobj/AsBroadcaster.cpp   2008-11-07 08:40:42 +0000
+++ b/libcore/asobj/AsBroadcaster.cpp   2008-12-02 13:28:42 +0000
@@ -103,22 +103,20 @@
 {
        as_object* asb = getAsBroadcaster();
 
-       //log_debug("Initializing object %p as an AsBroadcaster", (void*)&o);
-
        as_value tmp;
 
-       if ( asb->get_member(NSV::PROP_ADD_LISTENER, &tmp) )
-       {
-               o.set_member(NSV::PROP_ADD_LISTENER, tmp);
+       if (asb->get_member(NSV::PROP_ADD_LISTENER, &tmp)) {
+        o.set_member(NSV::PROP_ADD_LISTENER, tmp);
        }
 
-       if ( asb->get_member(NSV::PROP_REMOVE_LISTENER, &tmp) )
-       {
-               o.set_member(NSV::PROP_REMOVE_LISTENER, tmp);
+       if (asb->get_member(NSV::PROP_REMOVE_LISTENER, &tmp)) {
+        o.set_member(NSV::PROP_REMOVE_LISTENER, tmp);
        }
        
-       o.set_member(NSV::PROP_BROADCAST_MESSAGE, new 
builtin_function(AsBroadcaster::broadcastMessage_method));
-       o.set_member(NSV::PROP_uLISTENERS, new Array_as());
+    o.set_member(NSV::PROP_BROADCAST_MESSAGE,
+            new builtin_function(AsBroadcaster::broadcastMessage_method));
+
+    o.set_member(NSV::PROP_uLISTENERS, new Array_as());
 
 #ifndef NDEBUG
        assert(o.get_member(NSV::PROP_uLISTENERS, &tmp));
@@ -126,27 +124,19 @@
        assert(o.get_member(NSV::PROP_BROADCAST_MESSAGE, &tmp));
        assert(tmp.is_function());
 
-#if 0 // we can't rely on the following, due to possible override 
-      // of the AsBroadcaster properties used to intialize this
-      // object
-       assert(o.get_member(NSV::PROP_ADD_LISTENER, &tmp));
-       assert(tmp.is_function());
-       assert(o.get_member(NSV::PROP_REMOVE_LISTENER, &tmp));
-       assert(tmp.is_function());
-#endif // 0
-
+    // The following properties may be overridden in the AsBroadcaster object
+    // and thus unavailable: addListener, removeListener
 #endif
 }
 
 as_value
 AsBroadcaster::initialize_method(const fn_call& fn)
 {
-       // TODO: initialize first arg object as an AsBroadcaster
-       //       (call the AsBroadcaster::initialize(as_object*) static ?)
        if ( fn.nargs < 1 )
        {
                IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("AsBroadcaster.initialize() requires one 
argument, none given"));
+               log_aserror(_("AsBroadcaster.initialize() requires one 
argument, "
+                "none given"));
                );
                return as_value();
        }
@@ -156,7 +146,8 @@
        if ( ! tgtval.is_object() )
        {
                IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("AsBroadcaster.initialize(%s): first arg is not 
an object"), tgtval); 
+               log_aserror(_("AsBroadcaster.initialize(%s): first arg is "
+                "not an object"), tgtval); 
                );
                return as_value();
        }
@@ -173,8 +164,6 @@
 
        AsBroadcaster::initialize(*tgt);
 
-       //log_debug("AsBroadcaster.initialize(%s): TESTING", tgtval);
-
        return as_value();
 }
 
@@ -205,10 +194,11 @@
        }
 
        // assuming no automatic primitive-to-object cast will return an 
array...
-       if ( ! listenersValue.is_object() )
+       if (!listenersValue.is_object())
        {
                IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror(_("%p.addListener(%s): this object's _listener 
isn't an object: %s"),
+               log_aserror(_("%p.addListener(%s): this object's _listener 
isn't "
+                "an object: %s"),
                        (void*)fn.this_ptr.get(),
                        fn.dump_args(), listenersValue);
                );
@@ -400,25 +390,36 @@
 AsBroadcaster::getAsBroadcaster()
 {
        VM& vm = VM::get();
-       int swfVersion = vm.getSWFVersion();
 
        static boost::intrusive_ptr<as_object> obj = NULL;
        if ( ! obj )
        {
-               obj = new builtin_function(AsBroadcaster_ctor, 
getAsBroadcasterInterface()); 
-               VM::get().addStatic(obj.get()); // correct ?
-               if ( swfVersion >= 6 )
-               {
-                       // NOTE: we may add NSV::PROP_INITIALIZE, unavailable 
at time of writing.
-                       //       anyway, since AsBroadcaster is the only class 
we know using an 'initialize'
-                       //       method we might as well save the string_table 
size in case we'll not load
-                       //       the class.
-                       obj->init_member("initialize", new 
builtin_function(AsBroadcaster::initialize_method));
-
-                       obj->init_member(NSV::PROP_ADD_LISTENER, new 
builtin_function(AsBroadcaster::addListener_method));
-                       obj->init_member(NSV::PROP_REMOVE_LISTENER, new 
builtin_function(AsBroadcaster::removeListener_method));
-                       obj->init_member(NSV::PROP_BROADCAST_MESSAGE, new 
builtin_function(AsBroadcaster::broadcastMessage_method));
-               }
+               obj = new builtin_function(AsBroadcaster_ctor,
+                getAsBroadcasterInterface()); 
+               vm.addStatic(obj.get()); // correct ?
+
+        const int flags = as_prop_flags::dontEnum |
+                          as_prop_flags::dontDelete |
+                          as_prop_flags::readOnly |
+                          as_prop_flags::onlySWF6Up;
+
+        // NOTE: we may add NSV::PROP_INITIALIZE, unavailable at
+        // time of writing. Anyway, since AsBroadcaster is the only
+        // class we know using an 'initialize' method we might as
+        // well save the string_table size in case we'll not load
+        // the class.
+        obj->init_member("initialize",
+                new builtin_function(AsBroadcaster::initialize_method),
+                flags);
+        obj->init_member(NSV::PROP_ADD_LISTENER,
+                new builtin_function(AsBroadcaster::addListener_method),
+                flags);
+        obj->init_member(NSV::PROP_REMOVE_LISTENER,
+                new builtin_function(AsBroadcaster::removeListener_method),
+                flags);
+        obj->init_member(NSV::PROP_BROADCAST_MESSAGE,
+                new builtin_function( AsBroadcaster::broadcastMessage_method),
+                flags);
        }
 
        return obj.get();

=== modified file 'libcore/asobj/Key_as.cpp'
--- a/libcore/asobj/Key_as.cpp  2008-11-22 10:11:31 +0000
+++ b/libcore/asobj/Key_as.cpp  2008-12-02 11:45:42 +0000
@@ -119,7 +119,8 @@
 Key_as::notify_listeners(const event_id& key_event)
 {  
     // There is no user defined "onKeyPress" event handler
-    if( (key_event.m_id != event_id::KEY_DOWN) && (key_event.m_id != 
event_id::KEY_UP) ) return;
+    if((key_event.m_id != event_id::KEY_DOWN) &&
+            (key_event.m_id != event_id::KEY_UP)) return;
 
     as_value ev(key_event.get_function_name());
 

=== modified file 'libcore/asobj/Selection.cpp'
--- a/libcore/asobj/Selection.cpp       2008-12-01 20:58:08 +0000
+++ b/libcore/asobj/Selection.cpp       2008-12-02 13:28:42 +0000
@@ -28,6 +28,8 @@
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
 #include "Object.h" // for getObjectInterface
+#include "array.h"
+#include "AsBroadcaster.h"
 
 // For getting and setting focus
 #include "VM.h"
@@ -36,12 +38,10 @@
 namespace gnash {
 
 namespace {    
-    as_value selection_addlistener(const fn_call& fn);
     as_value selection_getbeginindex(const fn_call& fn);
     as_value selection_getcaretindex(const fn_call& fn);
     as_value selection_getendindex(const fn_call& fn);
     as_value selection_getfocus(const fn_call& fn);
-    as_value selection_removelistener(const fn_call& fn);
     as_value selection_setfocus(const fn_call& fn);
     as_value selection_setselection(const fn_call& fn);
 
@@ -68,19 +68,26 @@
 void
 attachSelectionInterface(as_object& o)
 {
-       o.init_member("addListener", new 
builtin_function(selection_addlistener));
+
+    const int flags = as_prop_flags::dontEnum |
+                      as_prop_flags::dontDelete |
+                      as_prop_flags::readOnly;
+
        o.init_member("getBeginIndex",
-            new builtin_function(selection_getbeginindex));
+            new builtin_function(selection_getbeginindex), flags);
        o.init_member("getCaretIndex",
-            new builtin_function(selection_getcaretindex));
+            new builtin_function(selection_getcaretindex), flags);
        o.init_member("getEndIndex",
-            new builtin_function(selection_getendindex));
+            new builtin_function(selection_getendindex), flags);
        o.init_member("getFocus",
-            new builtin_function(selection_getfocus));
-       o.init_member("removeListener",
-            new builtin_function(selection_removelistener));
-       o.init_member("setFocus", new builtin_function(selection_setfocus));
-       o.init_member("setSelection", new 
builtin_function(selection_setselection));
+            new builtin_function(selection_getfocus), flags);
+       o.init_member("setFocus", new builtin_function(selection_setfocus), 
flags);
+       o.init_member("setSelection",
+            new builtin_function(selection_setselection), flags);
+
+    /// Handles addListener, removeListener, and _listeners.
+    AsBroadcaster::initialize(o);
+ 
 }
 
 as_object*
@@ -96,13 +103,6 @@
 }
 
 as_value
-selection_addlistener(const fn_call& /*fn*/) {
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
-    return as_value();
-}
-
-
-as_value
 selection_getbeginindex(const fn_call& /*fn*/) {
     LOG_ONCE( log_unimpl (__FUNCTION__) );
     return as_value();
@@ -142,13 +142,6 @@
 }
 
 
-as_value
-selection_removelistener(const fn_call& /*fn*/) {
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
-    return as_value();
-}
-
-
 // Documented to return true when setFocus succeeds, but that seems like the
 // usual Adobe crap.
 //
@@ -182,8 +175,6 @@
         return as_value(false);
     }
 
-    bool ret = false;
-
     movie_root& mr = ptr->getVM().getRoot();
 
     const as_value& focus = fn.arg(0);
@@ -205,13 +196,13 @@
         ch = dynamic_cast<character*>(focus.to_object().get());
     }
 
-    // If the argument is not a character, do nothing.
+    // If the argument does not resolve to a character, do nothing.
     if (!ch) return as_value(false);
 
     // Will handle whether to set focus or not.
     mr.setFocus(ch);
 
-    return as_value(ret);
+    return as_value(false);
 }
 
 

=== modified file 'libcore/asobj/Sound.cpp'
--- a/libcore/asobj/Sound.cpp   2008-11-27 09:15:04 +0000
+++ b/libcore/asobj/Sound.cpp   2008-12-02 11:45:42 +0000
@@ -146,11 +146,12 @@
     //
     if ( attachedCharacter )
     {
-        log_debug("Sound has an attached character");
+        //log_debug("Sound has an attached character");
         character* ch = attachedCharacter->get();
         if ( ! ch )
         {
-            log_debug("Character attached to Sound was unloaded and couldn't 
rebind");
+            log_debug("Character attached to Sound was unloaded and "
+                    "couldn't rebind");
             return false;
         }
         volume = ch->getVolume();

=== modified file 'libcore/character.cpp'
--- a/libcore/character.cpp     2008-12-01 19:24:05 +0000
+++ b/libcore/character.cpp     2008-12-02 11:45:42 +0000
@@ -878,6 +878,7 @@
 bool
 character::unload()
 {
+
        if ( ! _unloaded )
        {
                queueEvent(event_id::UNLOAD, movie_root::apDOACTION);

=== modified file 'libcore/character.h'
--- a/libcore/character.h       2008-12-01 19:24:05 +0000
+++ b/libcore/character.h       2008-12-02 11:45:42 +0000
@@ -85,6 +85,11 @@
       return false;
   }
 
+  /// Some characters require actions on losing focus.
+  //
+  /// Default is a no-op. TextField implements this function.
+  virtual void killFocus() {}
+
 private:
 
   int m_id;

=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp    2008-12-01 20:58:08 +0000
+++ b/libcore/movie_root.cpp    2008-12-02 11:45:42 +0000
@@ -495,6 +495,20 @@
        setInvalidated();
 }
 
+as_object*
+movie_root::getSelectionObject() const
+{
+    as_object* global = _vm.getGlobal();
+    if (!global) return 0;
+
+    as_value s;
+    if (!global->get_member(NSV::CLASS_SELECTION, &s)) return 0;
+    
+    as_object* sel = s.to_object().get();
+   
+    return sel;
+}
+
 boost::intrusive_ptr<Stage_as>
 movie_root::getStageObject()
 {
@@ -798,15 +812,13 @@
                 // Try setting focus on the new character. This will handle
                 // all necessary events and removal of current focus.
                 // Do not set focus to NULL.
-                if (ms.activeEntity.get() && setFocus(ms.activeEntity)) {
-                    need_redisplay=true;
-                }
+                if (ms.activeEntity) {
+                    setFocus(ms.activeEntity);
 
-                       if (ms.activeEntity)
-                       {
                                
ms.activeEntity->on_button_event(event_id::PRESS);
                                need_redisplay=true;
                        }
+
                        ms.wasInsideActiveEntity = true;
                        ms.previousButtonState = MouseButtonState::DOWN;
                }
@@ -1322,35 +1334,49 @@
 }
 
 bool
-movie_root::setFocus(boost::intrusive_ptr<character> ch)
+movie_root::setFocus(boost::intrusive_ptr<character> to)
 {
 
     // Nothing to do if current focus is the same as the new focus. 
     // _level0 also seems unable to receive focus under any circumstances
     // TODO: what about _level1 etc ?
-    if (ch == _currentFocus || ch == static_cast<character*>(getRootMovie())) {
+    if (to == _currentFocus || to == static_cast<character*>(getRootMovie())) {
+        return false;
+    }
+
+    if (to && !to->handleFocus()) {
+        // TODO: not clear whether to remove focus in this case.
         return false;
     }
 
     // Undefined or NULL character removes current focus. Otherwise, try
     // setting focus to the new character. If it fails, remove current
     // focus anyway.
-    if (!ch) {
-        if (_currentFocus) _currentFocus->on_event(event_id::KILLFOCUS);
-        _currentFocus = 0;
-        return true;
-    }
-
-    if (!ch->handleFocus()) {
-        // TODO: not clear whether to remove focus in this case.
-        return false;
-    }
-
-    if (_currentFocus) _currentFocus->on_event(event_id::KILLFOCUS);
-    _currentFocus = ch;
-    _currentFocus->on_event(event_id::SETFOCUS);
-
-    log_debug("%s", ch->getTarget());
+
+    // Store previous focus, as the focus needs to change before onSetFocus
+    // is called and listeners are notified.
+    character* from = _currentFocus.get();
+
+    if (from) {
+
+        // Perform any actions required on killing focus (only TextField).
+        from->killFocus();
+        from->callMethod(NSV::PROP_ON_KILL_FOCUS, to.get());
+    }
+
+    _currentFocus = to;
+
+    if (to) {
+        to->callMethod(NSV::PROP_ON_SET_FOCUS, from);
+    }
+
+    as_object* sel = getSelectionObject();
+
+    /// Notify Selection listeners with previous and new focus as arguments.
+    if (sel) {
+        sel->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onSetFocus",
+                from, to.get());
+    }
 
        assert(testInvariant());
 

=== modified file 'libcore/movie_root.h'
--- a/libcore/movie_root.h      2008-12-01 17:19:03 +0000
+++ b/libcore/movie_root.h      2008-12-02 11:45:42 +0000
@@ -437,12 +437,12 @@
 
     /// Set the character having focus
     //
-    /// @param ch
-    /// The character having focus. NULL to kill focus.
+    /// @param to
+    /// The character to receive focus. NULL to kill focus.
     /// @return true if the focus operation succeeded, false if the passed
     /// character cannot receive focus. setFocus(0) is a valid operation, so
     /// returns true (always succeeds).
-    bool setFocus(boost::intrusive_ptr<character> ch);
+    bool setFocus(boost::intrusive_ptr<character> to);
     
     DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges,
             bool force);
@@ -947,6 +947,11 @@
     /// yet initialized.
     boost::intrusive_ptr<Stage_as> getStageObject();
 
+    /// Return the singleton Selection object
+    //
+    /// Can return 0 if it's been deleted.
+    as_object* getSelectionObject() const;
+
     typedef std::list<ExecutableCode*> ActionQueue;
 
     ActionQueue _actionQueue[apSIZE];

=== modified file 'testsuite/actionscript.all/Selection.as'
--- a/testsuite/actionscript.all/Selection.as   2008-12-01 20:58:08 +0000
+++ b/testsuite/actionscript.all/Selection.as   2008-12-02 11:49:24 +0000
@@ -79,10 +79,10 @@
  // See http://www.senocular.com/flash/tutorials/listenersasbroadcaster/?page=2
  check_equals (typeof(Selection.addListener), 'function');
  check_equals (typeof(Selection.removeListener), 'function'); 
- xcheck_equals(typeof(Selection.broadcastMessage), 'function');
- xcheck(Selection.hasOwnProperty("_listeners"));
- xcheck_equals(typeof(Selection._listeners), 'object');
- xcheck(Selection._listeners instanceof Array);
+ check_equals(typeof(Selection.broadcastMessage), 'function');
+ check(Selection.hasOwnProperty("_listeners"));
+ check_equals(typeof(Selection._listeners), 'object');
+ check(Selection._listeners instanceof Array);
 
  _root.createEmptyMovieClip("mc", getNextHighestDepth());
  check(mc instanceof MovieClip);

=== modified file 'testsuite/libcore.all/as_prop_flagsTest.cpp'
--- a/testsuite/libcore.all/as_prop_flagsTest.cpp       2008-01-21 23:26:48 
+0000
+++ b/testsuite/libcore.all/as_prop_flagsTest.cpp       2008-12-02 13:49:46 
+0000
@@ -46,9 +46,6 @@
 
        // Now set some flags and check result
 
-       flags.set_is_protected(true);
-       check(flags.get_is_protected());
-
        flags.set_read_only();
        check(flags.get_read_only());
 
@@ -60,9 +57,6 @@
 
        // Now clear the flags and check result
 
-       flags.set_is_protected(false);
-       check(!flags.get_is_protected());
-
        flags.clear_read_only();
        check(!flags.get_read_only());
 

=== modified file 'testsuite/swfdec/PASSING'
--- a/testsuite/swfdec/PASSING  2008-12-01 21:30:39 +0000
+++ b/testsuite/swfdec/PASSING  2008-12-02 11:49:24 +0000
@@ -924,6 +924,9 @@
 selection-focus-7.swf:a921151f59ae6746acfce846b2408111
 selection-focus-8.swf:65fed7eea65afbacd0ea030ac4799ce7
 selection-focus-events-5.swf:03ef025ff52765706b0154b972fce288
+selection-focus-events-6.swf:86fa669229be638ee97fe05b0f1dd6eb
+selection-focus-events-7.swf:19a92006c9abb7cce4780990db11a7a2
+selection-focus-events-8.swf:9d12f99e115d9f11bb65b7e8a8363b69
 setinterval2.swf:f2a17dbddcd0a72a672fbb9a63e0ea5b
 setinterval-arguments.swf:bf5653c905e58846b5a9ee8841c3bcb3
 setinterval-clear.swf:7897b1f201377d65dbffe1ae8182479a


reply via email to

[Prev in Thread] Current Thread [Next in Thread]