gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10395: Fully implement Selection.


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10395: Fully implement Selection.
Date: Fri, 05 Dec 2008 13:52:48 +0100
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10395
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Fri 2008-12-05 13:52:48 +0100
message:
  Fully implement Selection.
modified:
  libcore/TextField.cpp
  libcore/TextField.h
  libcore/asobj/Selection_as.cpp
  testsuite/actionscript.all/Selection.as
  testsuite/swfdec/PASSING
    ------------------------------------------------------------
    revno: 10391.1.7
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Fri 2008-12-05 13:37:17 +0100
    message:
      Implement Selection.getEndIndex(), Selection.getBeginIndex(),
      Selection.setSelection(), Selection.getCaretIndex(). Correct TextField
      focus implementation. Add tests for new Selection methods. New passes in
      swfdec testsuite.
    modified:
      libcore/TextField.cpp
      libcore/TextField.h
      libcore/asobj/Selection_as.cpp
      testsuite/actionscript.all/Selection.as
=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2008-12-05 09:37:07 +0000
+++ b/libcore/TextField.cpp     2008-12-05 12:37:17 +0000
@@ -154,7 +154,8 @@
     _selectable(!def.noSelect()),
     _autoSize(autoSizeNone),
     _type(def.readOnly() ? typeDynamic : typeInput),
-    _bounds(def.get_bound())
+    _bounds(def.get_bound()),
+    _selection(0, 0)
 {
 
     // WARNING! remember to set the font *before* setting text value!
@@ -210,7 +211,8 @@
     _selectable(true),
     _autoSize(autoSizeNone),
     _type(typeDynamic),
-    _bounds(bounds)
+    _bounds(bounds),
+    _selection(0, 0)
 {
     // Use the default font (Times New Roman for Windows, Times for Mac
     // according to docs. They don't say what it is for Linux.
@@ -378,6 +380,31 @@
     ranges.add( bounds.getRange() );            
 }
 
+void
+TextField::setSelection(int start, int end)
+{
+
+    if (_text.empty()) {
+        _selection = std::make_pair(0, 0);
+        return;
+    }
+
+    const size_t textLength = _text.size();
+
+    if (start < 0) start = 0;
+    else start = std::min<size_t>(start, textLength);
+
+    if (end < 0) end = 0;
+    else end = std::min<size_t>(end, textLength);
+
+    // The cursor position is always set to the end value, even if the
+    // two values are swapped to obtain the selection. Equal values are
+    // fine.
+    m_cursor = end;
+    if (start > end) std::swap(start, end);
+
+    _selection = std::make_pair(start, end);
+}
 bool
 TextField::on_event(const event_id& id)
 {
@@ -1872,11 +1899,11 @@
 TextField::handleFocus()
 {
 
-    /// Only selectable TextFields can receive focus.
-    if (!_selectable) return false;
-
     set_invalidated();
 
+    /// Select the entire text on focus.
+    setSelection(0, _text.length());
+
     m_has_focus = true;
 
     // why should we add to the key listener list every time
@@ -2249,7 +2276,6 @@
         {
             std::string strval = arg.to_string();
             TextField::AutoSizeValue val = ptr->parseAutoSizeValue(strval);
-            //log_debug("%s => %d", strval, val);
             ptr->setAutoSize( val );
         }
     }

=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h       2008-12-02 11:45:42 +0000
+++ b/libcore/TextField.h       2008-12-05 12:37:17 +0000
@@ -128,6 +128,16 @@
        /// Return true if text is defined
        bool getTextDefined() const { return _textDefined; }
 
+    size_t getCaretIndex() const {
+        return m_cursor;
+    }
+
+    const std::pair<size_t, size_t>& getSelection() const {
+        return _selection;
+    }
+
+    void setSelection(int start, int end);
+
        /// We have a "text" member.
        bool set_member(string_table::key name, const as_value& val, 
                string_table::key nsname = 0, bool ifFound=false);
@@ -632,6 +642,8 @@
        ///
        rect _bounds;
 
+    std::pair<size_t, size_t> _selection;
+
 protected:
 
        /// Mark reachable reosurces (for GC)
@@ -649,4 +661,4 @@
 
 } // namespace gnash
 
-#endif // _GNASH_EDIT_TEXT_CHARACTER_H_
+#endif 

=== modified file 'libcore/asobj/Selection_as.cpp'
--- a/libcore/asobj/Selection_as.cpp    2008-12-05 07:35:49 +0000
+++ b/libcore/asobj/Selection_as.cpp    2008-12-05 12:37:17 +0000
@@ -30,6 +30,7 @@
 #include "Object.h" // for getObjectInterface
 #include "array.h"
 #include "AsBroadcaster.h"
+#include "TextField.h"
 
 // For getting and setting focus
 #include "VM.h"
@@ -103,23 +104,56 @@
 }
 
 as_value
-selection_getbeginindex(const fn_call& /*fn*/) {
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
-    return as_value();
-}
-
-
-as_value
-selection_getcaretindex(const fn_call& /*fn*/) {
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
-    return as_value();
-}
-
-
-as_value
-selection_getendindex(const fn_call& /*fn*/) {
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
-    return as_value();
+selection_getbeginindex(const fn_call& fn)
+{
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
+    
+    movie_root& mr = ptr->getVM().getRoot();
+    character* focus = mr.getFocus().get();
+
+    TextField* tf = dynamic_cast<TextField*>(focus);
+
+    if (!tf) return as_value(-1);
+
+    return as_value(tf->getSelection().first);
+
+}
+
+/// Return -1 if focus is not a TextField, otherwise the 0-based index of the
+/// selection.
+//
+/// An alternative implementation would have a getCaretIndex in the character
+/// base class, with a default implementation returning -1. We would still
+/// have to check for no-focus events here, though.
+as_value
+selection_getcaretindex(const fn_call& fn)
+{
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
+
+    movie_root& mr = ptr->getVM().getRoot();
+    character* focus = mr.getFocus().get();
+
+    TextField* tf = dynamic_cast<TextField*>(focus);
+
+    if (!tf) return as_value(-1);
+
+    return as_value(tf->getCaretIndex());
+}
+
+
+as_value
+selection_getendindex(const fn_call& fn)
+{
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
+
+    movie_root& mr = ptr->getVM().getRoot();
+    character* focus = mr.getFocus().get();
+
+    TextField* tf = dynamic_cast<TextField*>(focus);
+
+    if (!tf) return as_value(-1);
+
+    return as_value(tf->getSelection().second);
 }
 
 /// Returns null when there is no focus, otherwise the target of the
@@ -207,8 +241,27 @@
 
 
 as_value
-selection_setselection(const fn_call& /*fn*/) {
-    LOG_ONCE( log_unimpl (__FUNCTION__) );
+selection_setselection(const fn_call& fn)
+{
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
+
+    movie_root& mr = ptr->getVM().getRoot();
+    character* focus = mr.getFocus().get();
+
+    TextField* tf = dynamic_cast<TextField*>(focus);
+
+    if (!tf) return as_value();
+
+    if (fn.nargs != 2) {
+        // Only two arguments are acceptable.
+        return as_value();
+    }
+
+    int start = fn.arg(0).to_int();
+    int end = fn.arg(1).to_int();
+
+    tf->setSelection(start, end);
+
     return as_value();
 }
 

=== modified file 'testsuite/actionscript.all/Selection.as'
--- a/testsuite/actionscript.all/Selection.as   2008-12-02 11:49:24 +0000
+++ b/testsuite/actionscript.all/Selection.as   2008-12-05 12:37:17 +0000
@@ -90,7 +90,7 @@
  check_equals(ret, false);
  check_equals(Selection.getFocus(), null);
 
- mc.createTextField("tx", getNextHighestDepth(), 400, 400, 10, 10);
+ tx = undefined;
 
  check_equals(Selection.getFocus(), null);
  ret = Selection.setFocus(tx);
@@ -155,6 +155,14 @@
  Selection.setFocus(mc);
  check_equals(Selection.getFocus(), "_level0.mc");
 
+ // Indices of MovieClip focus.
+ ret = Selection.getBeginIndex();
+ check_equals(ret, -1);
+ ret = Selection.getEndIndex();
+ check_equals(ret, -1);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, -1);
+
 
  Selection.setFocus(tx);
  check_equals(Selection.getFocus(), null);
@@ -165,6 +173,127 @@
  check_equals(ret, true);
  check_equals(Selection.getFocus(), null);
 
+ // Indices of null focus.
+ ret = Selection.getBeginIndex();
+ check_equals(ret, -1);
+ ret = Selection.getEndIndex();
+ check_equals(ret, -1);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, -1);
+
+ createTextField('text1', 99, 10, 10, 10, 10);
+ ret = Selection.setFocus(text1);
+ check_equals(ret, false);
+ check_equals(Selection.getFocus(), '_level0.text1');
+
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 0);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 0);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 0);
+
+ // setSelection
+ ret = Selection.setSelection(0, 1);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 0);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 0);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 0);
+ 
+ text1.text = "Some Text";
+ ret = Selection.setSelection(0, 1);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 0);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 1);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 1);
+
+ ret = Selection.setSelection(4, -5);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 0);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 4);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 0);
+
+ ret = Selection.setSelection(6, 3);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 3);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 6);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 3);
+
+ ret = Selection.setSelection(1, 0);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 0);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 1);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 0);
+
+ ret = Selection.setSelection(2, 6);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 2);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 6);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 6);
+
+ ret = Selection.setSelection(3);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 2);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 6);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 6);
+
+ ret = Selection.setSelection(2, 25);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 2);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 9);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 9);
+
+ ret = Selection.setSelection(-1, 4);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 0);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 4);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 4);
+
+ ret = Selection.setSelection(1, 1);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 1);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 1);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 1);
+
+ ret = Selection.setSelection(1, 2, 3);
+ check_equals(ret, undefined);
+ ret = Selection.getBeginIndex();
+ check_equals(ret, 1);
+ ret = Selection.getEndIndex();
+ check_equals(ret, 1);
+ ret = Selection.getCaretIndex();
+ check_equals(ret, 1);
+
 #endif // OUTPUT_VERSION >= 6
 
 totals();

=== modified file 'testsuite/swfdec/PASSING'
--- a/testsuite/swfdec/PASSING  2008-12-03 11:25:33 +0000
+++ b/testsuite/swfdec/PASSING  2008-12-05 12:52:48 +0000
@@ -928,6 +928,10 @@
 selection-focus-events-6.swf:86fa669229be638ee97fe05b0f1dd6eb
 selection-focus-events-7.swf:19a92006c9abb7cce4780990db11a7a2
 selection-focus-events-8.swf:9d12f99e115d9f11bb65b7e8a8363b69
+selection-setFocus-textfields-5.swf:2caede2dd8e2f964bb61828ed26c4d28
+selection-setFocus-textfields-6.swf:77ced014dd1b15624cdfb77538b13631
+selection-setFocus-textfields-7.swf:f891bcaf4fa3b8ce7d0d22140e7674fb
+selection-setFocus-textfields-8.swf:fe44c7768eda9e43fc60210cfa2d9354
 setinterval2.swf:f2a17dbddcd0a72a672fbb9a63e0ea5b
 setinterval-arguments.swf:bf5653c905e58846b5a9ee8841c3bcb3
 setinterval-clear.swf:7897b1f201377d65dbffe1ae8182479a


reply via email to

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