[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10395: Fully implement Selection.,
Benjamin Wolsey <=