When converting the floating point allocation width to an integer
multiple of PANGO_SCALE to give to the PangoLayout it can sometimes
end up slightly short of the allocated size due to rounding
errors. This can cause some of the lines to be wrapped differently
when a non-integer-aligned position is used (such as when animating
text). It works better to round the number to the nearest integer by
adding 0.5 instead of letting the default float cast truncate it
downwards.
http://bugzilla.openedhand.com/show_bug.cgi?id=2170
The marshallers we use for the signals are declared in a private header,
and it stands to reason that they should also be hidden in the shared
object by using the common '_' prefix. We are also using some direct
g_cclosure_marshal_* symbol from GLib, instead of consistently use the
clutter_marshal_* symbol.
If a cached layout didn't actually match the layout we're looking for,
it would be returned anyway. Remove this return so that it can correctly
continue looking and get a cache miss if appropriate.
http://bugzilla.openedhand.com/show_bug.cgi?id=2109
This patch combines a number of fixes and improvements to the
layout caching logic in ClutterText.
* Fix: The width must always be set on the PangoLayout when painting.
This is necessary because the layout aligns in the width, and
even when we think we are left-aligned, the auto-dir feature
of PangoLayout may result in right-alignment.
* Fix: We should only ever try to reuse a cached layout based
on its logical width if layout.width was -1 when computing
that logical width. If the layout was already ellipsized,
then comparing the logical width to the new width we are
trying to wrap to doesn't make sense. (If "abc" ellipsizes
to a 15-pixel wide "..." for a width of 1 pixel, that doesn't
mean that we should use "..." for a width of 15 pixels. Maybe
"abc" itself is 15 pixels wide.)
* Improvement: rather than looking up cached layouts based on the
input allocation_width/allocation_height, look them up based
on the actual width/height/ellipsize that we pass to create
a layout. This is simpler and improves the chance we'll get
a cache hit when appropriate even if there are small floating
point differences.
Note because of the first fix this is less aggressive than dd40732
in caching layouts; get_preferred_width() and painting can't share
a layout since get_preferred_width() needs to pass a width of -1
to Pango and painting needs to pass the real width.
The patch has been updated from the clutter-1.2 branch to current
master; using the profiling instrumentation it is possible to verify
with test-text-field that the hit/miss counters go from:
Name Total Per Frame
---- ----- ---------
Text layout cache hit counter 13 6
Text layout cache miss counter 11 5
before applying the patch, to:
Name Total Per Frame
---- ----- ---------
Text layout cache miss counter 4 2
Text layout cache hit counter 3 1
after applying the patch.
https://bugzilla.gnome.org/show_bug.cgi?id=618104http://bugzilla.openedhand.com/show_bug.cgi?id=2109
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Currently, each ClutterText caches 3 Pango layouts:
» one for the preferred, unbounded width
» one for the preferred height for a given width
» one for the allocated size
Some layout managers do a double pass that could flush the whole cache
before it has a chance of actually storing relevant data, resulting in
a continuous series of misses.
We can try to counteract this by doubling the size of the cache, from
three slots to six. More than six would be pointless, as well as too
memory consuming; but we might get down to a number between 3 and 6 at
any later point.
By comparing the requested size against the computed sized for existing
Pango layouts we can avoid creating layouts where the requested size
matches that of a previously computed one.
In particular this optimisation means that when working with a fixed
positioning based layout (with no constraints on the size of the
ClutterText) the same PangoLayout can be used to calculate the preferred
width, height and also the layout used for the actual painting.
http://bugzilla.openedhand.com/show_bug.cgi?id=2078
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This replaces code like this:
if (CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (self);
with:
clutter_actor_queue_redraw (self);
clutter_actor_queue_redraw internally knows what can be optimized when
the actor is not visible, but it also knows that the queue_redraw signal
must always be sent in case a ClutterClone is cloning a hidden actor.
Instead of returning a sub-pixel height round up the preferred height to
the nearest integral value that is not less than the size reported by
Pango, once converted in pixels.
Bind ctrl-backspace and ctrl-del to functions that delete a word before
or after the cursor, respectively.
Selection does not affect the deletion, but current selection is
preserved. This mimicks GTK+ functionality in GtkTextView and GtkEntry.
http://bugzilla.openedhand.com/show_bug.cgi?id=1767
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
High level toolkits might wish to construct a PangoFontDescription and
then set it directly on a ClutterText actor proxy or sub-class.
ClutterText should have a :font-description property to set (and get)
the PangoFontDescription.
http://bugzilla.openedhand.com/show_bug.cgi?id=1960
The commit ecbb7ce41a exposed some issues
when positioning the cursor with the mouse pointer: the selection is
not moved along with the cursor when inserting a single character or a
string.
Also, some freeze_notify() are called too early, leading to decoupling
from their respective thaw_notify().
http://bugzilla.openedhand.com/show_bug.cgi?id=1955
Added a "selection-bound" notify on clutter_text_clear_selection as it
changes the value.
Added utility function clutter_text_set_positions, in order to
change both cursor position and selection bound inside a
g_object_[freeze/thaw]_notify block
Added g_object_[freeze/thaw]_notify in other functions that changes
both cursor position and selection bound
Solves http://bugzilla.openedhand.com/show_bug.cgi?id=1955
Previously when the markup property is set it would generate an
attribute list from the markup and then merge it with the attributes
from the attribute property and store it as the effective
attributes. The markup attributes and the marked up text would then be
forgotten. This breaks if the application then later changes the
attributes property because it would try to regenerate the effective
attributes from the markup text but the stored text no longer contains
any markup. If the original markup text happened to contain entities
like '<' they would end up causing parse errors because they would
be converted to the actual symbols.
To fix this the attributes from the markup are now stored
independently from the effective attributes. The effective attributes
are now regenerated if either set of attributes changes right before a
layout is created.
http://bugzilla.openedhand.com/show_bug.cgi?id=1940
Both the ::insert-text and ::delete-text are "action" signals, that is
signals that are safe to (and should) be emitted using g_signal_emit()
directly.
* text-direction:
docs: Add text-direction accessors
Set the default language on the Pango context
actor: Set text direction on parenting
tests: Display the index inside text-box-layout
box-layout: Honour :text-direction
text: Dirty layout cache on text direction changes
actor: Add :text-direction property
Use the newly added ClutterTextDirection enumeration
Add ClutterTextDirection enumeration
When the text direction changes we should evict the cached layouts
to avoid stale entries in case the direction change produces a layout
with the same size.
cogl_clip_push, and cogl_clip_push_window_rect which are now deprecated were
used in various places internally so this just switches to using the
replacement functions.
The change in commit 3bbc96e17e moved the
:text property setter to use set_text_internal(); this function does not
invalidate the Layout cache and does not queue a relayout, thus breaking
the behaviour of ClutterText when setting the contents of the actor using
the property.
http://bugzilla.openedhand.com/show_bug.cgi?id=1851
Input Methods require to be able to set a "pre-edit string", that is
a string that it's just displayed into the Text actor without being
committed to the actor's buffer. The string might require custom Pango
attributes, and an update of the cursor position.
Currently, setting the :text property has the side-effect of
setting the :use-markup property to FALSE. This prevents
constructing a Text actor, or setting its properties, like:
g_object_set (text,
"use-markup", TRUE,
"text", some_string,
NULL);
as the ordering becomes important. Unfortunately, the ordering
of the properties cannot be enforced with ClutterScript or
with language bindings.
The documentation of the clutter_text_set_text() method should
be expanded to properly specify that the set_text() method will
change the :use-markup property to FALSE as a side effect.
clutter_text_move_word_backward/forward() calls did not use the
start argument consistently. Also, clutter_text_move_word_forward()
bound check checked the wrong end.
Fixes#1765
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
When a letter key is pressed with the control key held down one of
three things will happen :-
a) If the stage is embedded within a GtkClutterEmbed the unicode value
will be filled from gdk_keyval_to_unicode. This will be the same
value as if control was not pressed (so Ctrl+V will be 'v').
b) If the stage is not in a GtkClutterEmbed and Clutter is running on
the X11 backend then it will try to fill in the unicode value from
XLookupString. This *will* take into account the control so the
unicode value will represent a control character (Ctrl+V will be
'\x16').
c) Most other backends will not bother to fill in the unicode
value. Therefore clutter_keysym_to_unicode will be used which also
does not take into account the control key (so Ctrl+V will be 'v').
For cut and paste to work in Nbtk, the control keys need to bubble up
to the parent NbtkEntry container. This works fine for 'b' but not 'a'
and 'c'.
This patch makes ClutterText always allow the event to bubble if the
key is not handled by the binding pool and the control modifier is
down.
Ideally ClutterText would always get a unicode value that takes into
account the modifiers but this is probably best left up to the input
methods.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
If you select all the text in a ClutterText, there is an invisible
cursor position either at the beginning or end. If it's at the beginning,
the bug is that left arrow won't clear the selection. If it's at the end,
the bug is that the right arrow won't.
Here are the ways to reproduce it:
a. Ctrl-A selects all and moves the hidden cursor position to the left.
b. For single line: End, Shift-Home does the same.
c. Or manually moving to the end and doing Shift-Left Arrow to the
beginning.
These all put it in the state where right arrow will properly clear
selection and move to cursor position 1, but left arrow fails to clear
the selection.
For b and c above, the opposite will give you the end case where right
arrow doesn't work.
Anyway, it turns out clear_selection is getting called, it just doesn't
show up because it's not doing a queue_redraw. So the attached patch
seems to fix things.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
ClutterEvent is not really gobject-introspection friendly because
of the whole discriminated union thing. In particular, if you get
a ClutterEvent in a signal handler, you probably can't access the
event-type-specific fields, and you probably can't call methods
like clutter_key_event_symbol() either, because you can't cast the
ClutterEvent to a ClutterKeyEvent.
The cleanest solution is to turn every accessor into ClutterEvent
methods, accepting a ClutterEvent* and internally checking the event
type.
Fixes bug:
http://bugzilla.openedhand.com/show_bug.cgi?id=1585
Instead of passing a boolean value, the ::allocate virtual function
should use a bitmask and flags. This gives us room for expansion
without breaking API/ABI, and allows to encode more information to
the allocation process instead of just changes of absolute origin.
Add a method for deleting the current selection inside a Text actor.
This is useful for subclasses.
See bug:
http://bugzilla.openedhand.com/show_bug.cgi?id=1521
Based on a patch by: Raymond Liu <raymond.liu@intel.com>
The cursor x position is already translated, so we do not need to take the
actors allocation into account when calculating scrolling.
Additionally, we need to update the text_x value before running
clutter_text_ensure_cursor_position.
Add any scrolling offset to the x value when in single line mode.
Now that the offset is taken into account in the position_to_coords
function, we do not need to adjust the cursor x manually in
clutter_text_paint.
If the cursor is already at the end of the Text contents then we
need to maintain its position when deleting the previous character
using the relative key binding.
If text is set, ClutterText should never return less than the layout
height for minimum and preferred heights.
This holds unless ellipsize and wrap are enabled, in which case the
minimum height should be the height of the first line -- which is
the height needed to at the very least show the ellipsization.
Based on a patch by: Thomas Wood <thomas@openedhand.com>
Fixes bug:
http://bugzilla.openedhand.com/show_bug.cgi?id=1598
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
I was seeing clutter_text_get_selection trying to malloc up to 4Gb due to
unexpected negative arithmetic for the start/end offsets which resulted
in a crash.
This just tests for positions of -1 before deciding if the start/end
positions need to be swapped. The conversion from position to byte offset
already works with -1.
Add a method for deleting the current selection inside a Text actor.
This is useful for subclasses.
See bug:
http://bugzilla.openedhand.com/show_bug.cgi?id=1521
Based on a patch by: Raymond Liu <raymond.liu@intel.com>
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
Setting the wrap mode on the PangoLayout seems to have disappeared
during the text-actor-layout-height branch merge so this brings it
back. The test for this in test-text-cache no longer needs to be
disabled.
We also shouldn't set the width on the layout if there is no wrapping
or ellipsizing because otherwise it implicitly enables wrapping. This
only matters if the actor gets allocated smaller than its natural
size.
The documentation for the ::cursor-event says that the signal
is emitted only when the cursor position changes. Right now it
is being emitted every time we ensure the cursor position during
the Text paint sequence.
The clutter_text_ensure_cursor_position() function should check
whether the stored cursor position has changed since the last
paint, and emit the ::cursor-event signal only when there has
been a change.
We only want to eschew the pango_layout_set_width() on editable,
single-line Text actors because they can "scroll" the PangoLayout.
This fixes the ellipsization on entries.
Editable ClutterText will scroll when allocated less width than is
necessary to lay out the entire layout on a single line, so return 1 for
the minimum width in this case.
Approved by Emmanuele Bassi, fixes bug #1555.
Ellipsizing was effectively broken for two reasons. There was a typo
in the code to set the width so it always ended up being some massive
value. If no height should be set on the layout it was being set to
G_MAXINT. Setting a height greater than 0 enables wrapping which so
ellipsizing is not performed. It should be left at the default of -1
instead.
Adds a new property so that the selection color can be different from
the cursor color. If no selection color is specified it will use the
cursor color as before. If no cursor color is specified either it will
use the text color.
Bug 1518 - [Patch] Widget derivied from ClutterText will crash on
key_press_event
In clutter_text_key_press() we are using G_OBJECT_TYPE_NAME to find
out the actor's type name. However, if some widget is derived from
ClutterText, when the key press handler is called, G_OBJECT_TYPE_NAME
will return the name of the derived widget.
The default implementation should get the binding pool for the base
class.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
ClutterText should offer multiple selection modes depending on the
number of pointer clicks.
Following the GTK+ conventions:
- double click selects the current word
- triple click selects the current line
Bug 1529 - Selection bound out of sync with an empty Text actor
When the user clicks on a Text actor the cursor position and the
selection bound are set using bytes_to_offset(); if the Text is
empty, this means placing them both to 0. Setting the selection
bound to 0 means that when the user inserts a character by typing
it into the Text, the selection will be [0,1]; this will select
the first character, which will then be overwritten when typing
a new character.
The Text actor should, instead, check if there are no contents
and set the cursor position and the selection bound to -1.
The clutter_text_set_selection_bound() method should also validate
the value passed, in case it's bigger than the text lenght, or
smaller than -1.
As a convenience, if NULL is passed for the text argument of
clutter_text_set_text() (and for consistency,
clutter_text_set_markup()), treat that the same as "".
Bug 1501 - clutter_text_insert_text not working right with non-onebyte
character
In clutter_text_insert_text(), the position is expressed in characters, not
in bytes.
Actually, it turns out to be working on bytes, so when there are already
multi-byte character in the text buffer, insert text at the position after
the multi-byte character will not work right.
Also, the position is not updated after the insert work is done.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Bug 1500 - [Patch] clutter_text crash with non one-byte utf8 text exceed
max_length
In clutter_text_set_text_internal(), when text length in character is greater
than max_length, and there are multi-byte character in it, then the new text
string buffer is not malloc()'ed with right length. This will cause the app to
crash with segmention fault.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Add annotations such as (transfer-none) (out) (element-type ClutterActor),
and so forth to the doc comments as appropriate.
The annotations added here are a combination of the annotations previously
in gir-repository for Clutter and annotations found in a review of all
return values with that were being parsed with a transfer of "full".
http://bugzilla.openedhand.com/show_bug.cgi?id=1452
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
The :alignment property is prone to generate confusion: developers
will set it thinking that the contents of a ClutterText will
automagically align themselves.
Instead of using the generic term :alignment, and following the
GTK+ convention, we should use a more specific term, conveying the
actual effect of the property: alignment of the lines with respect
to each other, and not to the overall allocated area.
See bug 1428:
http://bugzilla.openedhand.com/show_bug.cgi?id=1428
ClutterText should merge the PangoAttributes set by using
clutter_text_set_attributes() with the attributes generated by
parsing Pango markup.
For this to work we must parse the markup and merge the attributes
we get out of pango_parse_markup() with the attributes set by
the user.
Setting the markup or the attributes on an editable text should
not work for the time being.
This makes it consistent with cogl_rectangle_with_{multi,}texture_coords.
Notably the reason cogl_rectangle_with_{multi,}texture_coords wasn't changed
instead is that the former approach lets you describe back facing rectangles.
(though technically you could pass negative width/height values to achieve
this; it doesn't seem as neat.)
Whenever a ClutterText is created it now connects to the font-changed
signal. When it is emitted the layout cache is dirtied and a relayout
is queued. That way changes to the font options or resolution will
cause an immediate update to the labels in the scene.
ClutterText already has code to try to preserve the x position when
moving up or down. A target x-position is stored and the cursor is
positioned at the nearest point to that in the appropriate line when
up or down is pressed. However the target position was never cleared
so it would always target the x-position of the cursor from the first
time you pressed up or down.
To fix this the patch clears the target position in set_position and
then sets it after the call in real_move_up/down. That way pressing
up or down sets the target position and any other movement will clear
it.
To get an index for the pixel position in the line
pango_layout_line_x_to_index is used. However when x is greater than
the length of the line then the index before the last grapheme is
returned which was causing it to jump to the penultimate
character. The patch makes it add on the trailing value so that it
will jump to the last character.
The old function ended up returning the length of the string when pos
was zero. This caused it to insert characters at the end when the
cursor was at the beginning of the string.
If an unbound control key is pressed (such as Ctrl+R) it would insert
a rectangle into the text.
Also zero is considered a valid unicode character by
g_unichar_validate so pressing a key such as shift would cause the
current selection to be deleted. The character isn't actually inserted
because insert_unichar disallows zeroes.
Some of the read-write properties of ClutterText were missing
an implementation in clutter_text_get_property(), as well as
the :position and :selection-bound properties being wrongly
converted from fixed point to integer, passing through floating
point values.
An editable ClutterText should not use pango_layout_set_markup(),
as the contents of the text actor will not match the text.
Only read-only text actors should parse the contents for Pango
markup.
If the Text actor is neither editable nor has its cursor set
to visible, then we should not be ensuring the cursor position.
This fixes a failure in the conformance test unit for the
layout cache.
Merge branch 'text-actor'
* text-actor: (108 commits)
Re-align ClutterText header file
[text] Fix cursor sizing
Comments and whitespace fixes to ClutterText
[docs] Add newly added :single-line-mode accessors
Update the ignore file
[tests] Add text field interactive test
[text] Add single-line-mode to ClutterText
[text] Fix the deletion actions
[text] Use cached length when possible
[tests] Add unit for the ClutterText:password-char property
[docs] Update the Text section
[text] Coalesce text visibility and password character
Allow localizations to change the text direction
Clean up the update_pango_context() function
Pass the PangoContext, not the MainContext
Revert the logic of the PangoContext check
Remove the binding pool entry from the list
Remove BindingPool::list_actions()
Add ClutterActor::create_pango_context()
Rename the PangoContext creation functions
...
The cursor should be slightly smaller than the height of the actor, to
allow for painting a border. Let's pad it by 1 pixel on the top and 1
on the bottom.
Also, we should use the cursor size everywhere and not use hardcoded
magic numbers.
Allow using ClutterText as a single line text field. This is useful for
text fields that accept just a single line of contents by default, and
respond to the Enter key press to execute some action.
The :single-line-mode property enables this behaviour inside ClutterText
by clipping and scrolling the contents of the PangoLayout if they do
not fit the allocated width of the Text actor.
When using the delete-prev action from the end of the text we end
up either missing the first glyph we have to delete or falling
through the last one in the text.
This commit fixes both issues.
Since clutter_text_set_text() measures the length of the text
each time, we should use the cached length instead of recomputing
the text length each time. This should save us some time when
dealing with long, multi-byte texts.