Support
Contribute
Contact
Tracker
Navigation
Personal tools
 

EWL Release 0.5.1

Contents

DND Support

There is now DND support for dropping data onto widgets with registered types, and dragging widgets with registered types. Ecore_X has been modified to support flexible data transfer but does not handle incremental transfers yet. Also there is debugging to be done related to cursors and giving this support time to mature. There may also be extra callbacks added at a later time if we need to support more events.

Engine Cursor Support

We currently rely on the X cursor directly, this needs to be pushed out to the engine in the form of two API calls. The first is to lookup a cursor handle by id/name, the second is to create a cursor handle from ARGB data. In order to make it easy to create custom cursors, there should be a cursor class that provides an Ewl_Window for packing widgets into, in order to do this each embed/window will need to support having it's engine overridden.

The basic widget has been written and added to CVS, but it requires additional handling to map a specific cursor handle for an engine to all widgets currently referencing that cursor.

Ewl_Popup

At the moment tooltips and combos use a floater to place their content on the screen. This has to be replaced by a (override) window solution. But the use of a window has some difficults. When you build a window you don't know its size it will have. This very bad when you want to support some sort of smart placing, e.g. be sure the hole tooltip is visible. There for I've written a small Widget called Ewl_Popup which does the dirty work for you.

You give it all the necessary facts it has to know (the type of placement, e.g. menu, tooltip; the mouse position in the case of a tooltip; the follow widget, e.g. the menu base). And it will search a place for the window to place it on a nice place.

You can find a preview .diff here:

www.mowem.de/ewl/popup.diff

It is not complete and needs some clean-ups, but it works more or less.

Any ideas or suggestions are very welcome. Pfritz 15:17, 28 October 2006 (MDT)

Embed Engine Targets

Right now the engine is set globally per applicaiton at startup time. This is generally a good thing as it allows the programmer to not worry about which engine they're using, and centralizes the options necessary for the user to start with a different engine. The problem is, there are some cases where we want different engines used at the same time in one application.

The current example is the cursor. It would be nice to simply treat the cursor as a small window that widgets can be packed into. This would allow people to easily create custom cursors using the same tools they currently use for theming. For this to work, the cursor "window" would need to be use the buffer engine, regardless of the engine being used for the parent window.

API proposal:

   int ewl_embed_engine_name_set(Ewl_Embed *embed, const char *engine);
   const char *ewl_embed_engine_name_get(Ewl_Embed *embed);

While the API seems simple, the implementation may be subtle. The windows will still need to be able to auto-determine the correct engine when none is specified. The case of setting an engine after a window has been realized will also need to be handled.

   1. No engine override set - currently what we have.
   2. Engine override set before realize, don't bother checking the global config value.
   3. Engine override after realize, unrealize and re-realize window with new engine.

The third case will require abstracting out the imenu/menu to handle the case at the window level. This could be accomplished in engines such as evas_fb by providing a smart object inside of the evas to represent the window.

MVC Selection Support

There is basic selection support in the Ewl_MVC code to support Ewl_List and Ewl_Combo. Currently Ewl_Tree2 doesn't have any real selection handling, only users registering click callbacks on the cells.

This will basiclly be a discussion of how to add the selection handling to Ewl_Tree2 and the modifications that will be made to Ewl_MVC, Ewl_Combo and Ewl_List along the way.

We will add the ability to set the selection mode of the tree2 to NONE, ROW or CELL selection mode. This setting will alter the way that tree2 will do highlighting as items are selected along with how the selected info is populated.

When the user clicks on a row or cell, and selection is enabled, a VALUE_CHANGED callback will be triggered. The user app can listen to VALUE_CHANGED callbacks on widget and react as needed. Question will this be an issue with multi-select? The app will get a calback for each selection the user makes, or if in multiselect do we hold of sending the VALUE_CHANGED? In this case, how do we know when to send it? Sending the value change callback on select is probably the best way as it's the only time we can sanely hook into. It should not be a frequent callback as clicks are relatively slow, multiselects should only send one event for a bulk selection and not one per row/column selected.

The Ewl_MVC selection code will be changed to support:

 Ewl_Pair **ewl_mvc_selected_get(Ewl_MVC);
 void ewl_mvc_selected_set(Ewl_MVC, Ewl_Pair **selected);

Where Ewl_Pair ** is a NULL terminated array of Ewl_Pair structs.

 struct Ewl_Pair 
 {
    int a;
    int b;
 }

For ROW select mode only the a item will be popluated, b will always be set to -1. a will contain the index of the selected row.

For CELL select a will be the row selected and b will be the column selected within the row.

For both cases a and b will be 0 based.

How should we store these Ewl_Pair structs? Do we determine them on the fly? [ewl_container_child_index(tree2, row); ewl_container_child_index(row, cell);] or do we store them in the cells as their created?

The Ewl_Combo code will always set b to -1 and the selected row will be placed in a.

The Ewl_List code will always set b to -1 and the selected item will be placed in a. Question Will this be confusing when working with a hlist or vlist? We may want to switch the value we set to indicate the direction of selection.

Text Widget Optimization

Reduced temporary allocations

A frequent call for the IO manager is ewl_text_text_insert_private. This is efficient relative to the load from ewl_text_char_to_byte, but it's seeing a significant hit from allocating and freeing a temporary buffer passed to ewl_text_text_utf8_validate. This function simply copies the passed string and replaces unknown characters with a '?' character. The results are then copied into the destination string and the buffer is freed. This could be done in a single step of walking the source text and copying to the destination replacing the appropriate characters as the contents are walked.

I was thinking of doing this slightly differently, just copying to the destination buffer, passing that into the validation routine along with a start index and char length.

Cached walking

After converting to a straight linked list, the IO manager test case has improved considerably, but there is still a big performance hit coming from ewl_text_char_to_byte, in fact it accounts for 65% of the load when formatting a large C file. This is because it resets the formatting list to the beginning each lookup. This could be improved if the text widget caches the last node walked, along with it's indexes. Frequent changes are often performed in localized regions, so walking relative to the last walk result should improve performance considerably. Also, we could walk relative to the cached node, the first node or the last node, depending on which is closer to the specified index.

This caching is done partially at the moment. The tree has t->formatting.current.char_idx which is the character index at the start of the node returned with ecore_dlist_curernt(t->formatting.nodes). This needs to be updated to have a current.byte_idx along side the char_idx that is updated whenever the char_idx is updated. We can then use these two indexes to track the char_to_byte and byte_to_char functions.

The first part of this is in place. The char_to_byte() and byte_to_char() functions will walk from the current node to the new position. (This made my test about 50% faster.) The piece that's missing from this is walking from the beginning/end if it will be closer.