Context API
This adds the context API as described here. The main practical change
now is that C is not longer directly accessible but has to be accessed
through accessor functions. This basically adds the implementation of
the API and adaption of existing code with some minor changes. The next
task of course is to actually use this design to cleanup of bad level
calls and global access, in blenkernel, blenloader.
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/Context
Error, Warning and Debug Info Reporting
This adds the error reporting API as described here. It should help
clean up error() calls in non-ui code, but eventually can become used
for gathering messages for a console window, and throwing exceptions
in python scripts when an error happens executing something.
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/Reports
* Added support for defining properties for operator buttons, with
uiButGetOperatorPtrRNA. Needed to cleanup a hack that was there
for operator properties in RNA, now a separate OperatorProperties
type is used for storing operator properties, instead of being part
of the Operator type itself.
* Allow selecting menu items with mouse release instead of press again.
* Fix some cases with hanging tooltips in the UI.
which context to run the operator: WM_OP_DEFAULT, WM_OP_REGION_WIN,
WM_OP_AREA or WM_OP_SCREEN. This also replaces WM_operator_call_rwin
since it is more general.
This is useful for buttons and popup menus to run operators, and also
used by a new function to lookup the keymap item for that operator in
the right context.
and event handling code still, how it integrates with operators and
handlers is not worked out yet. For testing, Ctrl+Q quit now shows
a confirmation popup using the following call:
okee_operator(C, "WM_OT_exit_blender", "Quit Blender");
Mouse cursors now work again
- centralized screen-level cursor changes, no more operator
running for it.
- spacetypes have callback to check/set individual cursor
types. Use notifier SCREEN_CHANGED to make sure it works
on mode changes etc.
- new calls WM_cursor_modal() and WM_cursor_restore() to
make temporarily cursor types during modes.
- used above for view2d cursors.
which will then be set when the operator is called, example:
kmi= WM_keymap_add_item(keymap, "ED_SCR_OT_region_split", SKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "dir", 'h');
kmi= WM_keymap_add_item(keymap, "ED_SCR_OT_region_split", SKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "dir", 'v');
There is a hack I had to do here, since properties are defined
as member of wmOperator, will try to fix later, committing now
so it can be used already.
funtion WM_keymap_add_item() now returns keymap-item, so you can use it
to set default properties for operators with WM_keymap_property_set().
Brecht will fill in this function, requires rna magic!
Example: an operator ED_OB_OT_add_primitive can be configured with
keymap like this:
WM_keymap_property_set(keymapitem, "Primitivetype", "Sphere");
Similar conventions we can use later for button/menu calls.
This will make creating operators easier, allowing a developer to group
tools functionality nicely.
TimeLine window pulldowns work sorta (for the options that were coded :)
Still trying to bring back code without recoding uiDefButs. In future these
will get directly operator stuff linked. For time being made a simple
operator call function, like:
WM_operator_call(C, "ED_MARKER_OT_add");
and for forcing operator to run in the main region-window:
WM_operator_call_rwin(C, "ED_MARKER_OT_add");
These calls also work for modal operators, like marker grab in this case.
Cleanup in area/region management
- more intelligence in area management for adding handlers and setting
data correct. Space/Region type callbacks only have to do own things.
- added option for adding default handlers to areas/regions. (flag in
type definition)
- ensured that region-types store the minsizes for regions.
- added boundbox check for handlers; note that it accepts pointer to
boundbox, because handlers don't get reset on area-resizing or
view changes. Example: view2d handlers use mask rect.
- handlers get now added on correct context levels (example frame change
also worked in header)
- removed ->refresh() callback. Context refreshing is Listener.
- the ->init() is being called on all WM level actions, also after a
file read, moving areas, re-opening areas etc.
- fixed bug: crash on exit was caused by cleaning up Screen too late.
- UI_view2d_size_update() removed from draw callback, is init()
- regions now store (winx, winy) subwindow size.
a special UI handler which makes the code clearer. This UI handler is attached
to the region along with other handlers, and also gets a callback when all
handlers for the region are removed to ensure things are properly cleaned up.
This should fix XXX's in the UI code related to events and context switching.
Most of the changes are in interface_handlers.c, which was renamed from
interface_ops.c, to convert operators to the UI handler. UI code notes:
* uiBeginBlock/uiEndBlock/uiFreeBlocks now takes a context argument, this is
required to properly cancel things like timers or tooltips when the region
gets removed.
* UI_add_region_handlers will add the region level UI handlers, to be used
when adding keymap handlers etc. This replaces the UI keymap.
* When the UI code starts a modal interaction (number sliding, text editing,
opening a menu, ..), it will add an UI handler at the window level which
will block events.
Windowmanager changes:
* Added an UI handler next to the existing keymap and operator modal handlers.
It has an event handling and remove callback, and like operator modal handlers
will remember the area and region if it is registered at the window level.
* Removed the MESSAGE event.
* Operator cancel and UI handler remove callbacks now get the
window/area/region restored in the context, like the operator modal and UI
handler event callbacks.
* Regions now receive MOUSEMOVE events for the mouse going outside of the
region. This was already happening for areas, but UI buttons are at the region
level so we need it there.
Issues:
* Tooltips and menus stay open when switching to another window, and button
highlight doesn't work without moving the mouse first when Blender starts up.
I tried using some events like Q_FIRSTTIME, WINTHAW, but those don't seem to
arrive..
* Timeline header buttons seem to be moving one pixel or so sometimes when
interacting with them.
* Seems not due to this commit, but UI and keymap handlers are leaking. It
seems that handlers are being added to regions in all screens, also in regions
of areas that are not visible, but these handlers are not removed. Probably
there should only be handlers in visible regions?
Part one of wrapping up area/region management.
Read design doc here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/AreaManager
This commit:
- brings keymap storage to WM, based on names/types. This structure
allows rna-ifying it too, so you can browse keymaps etc.
- creating areas and regions works slightly different now, wich
regiontypes stored in areatype.
Todo:
- better callbacks and structure for defining which handlers need to
be added.
- using region types to validate regions
- proper implementation of local region data
- code method for customizing keymaps. Current idea is that you have
to indicate an entire keymap to be custom, to prevent too complicated
merging problems of default and custom maps (like order, multiple keys
for same operator, disabling options, etc).
- Made view2d manipulations redraw on area level
- simplified call to send Notifiers:
WM_event_add_notifier(bContext *C, int type, int value, void *data)
This brings back more control to WM, no context messing within
operators. :) Handlers that execute operators will be responsible
for delivering correct contextes.
In general: should lead to making context not exposed, but only
readable via some callbacks.
- after closing button (having used it), it sends empty mousemove for
invoking new modal handler on same button. Don't know better solution
for now, at least this way WM handles everything. :)
- experiment: moved button handlers to area level, that way it respects
handlers on higher hierarchical level, like moving area edges.
Als interesting is that you can have a button active (texteditor) and
use a similar button in other area.
This can also be done on region level even.
On todo: proper notifier events for redraw! Don't want all areas to draw
on simple refreshes
* Changes in interface/ module
This commit brings back the way how buttons/menus work under control
of WM event system. The previous implementation extended usage of
handlers and operators in an interesting but confusing way. Better to
try it first according the design specs. :)
Most obviously:
- modal-handler operators are not stored anymore in regions/areas/windows.
such modal handlers own their operator, and should remove it themselves.
- removed code to move handlers from one queue to another.
(needs review with brecht!)
- WM fix: the API call to remove a modal handler got removed. This was a
dangerous thing anyway, and you should leave that to the event system.
Now, if a handler modal() call gets a cancel/finish return, it frees
itself in event system. WM_event_remove_modal_handler was a confusing
call anyway!
Todo:
- allow button-activate to refresh after using button
- re-enable arrow keys for menus
(do both after commit)
- review return values of operator callbacks in interface_ops.c
* Fixes in WM system
- Freeing areas/regions/windows, also on quit, now correctly closes
running modal handlers
- On starting a modal handler, the handler now stores previous area
and region context, so they send proper notifiers etc.
* Other fixes
- Area-split operator had bug, wrong minimal size checking. This
solves error when trying to split a very narrow area.
- removed DNA_USHORT_FIX from screen_types.h, gave warning
- operators didn't get ID name copied when activated, needed for
later re-use or saving.
- Added standard "tweak" gesture operator, which can be set per region, to
generate EVT_TWEAK events. You can configure tweaks for any mouse button
and have handlers for such events check for modifiers etc.
It even stores tweak direction (8 directions). Might be fun to experiment
with tweak gestures N, S, etc. :)
In general it can be used to replace the current tweak code in 2.48
(std_rmouse_transform).
Test added: on screen level it now adds LMB tweaks, if tweak-South it splits
the area. Will be removed of course.
- Added to Border operator a property to store event used to end border with.
- Moved the "AZone" triangle drawing to the right context (area). It was on
screen level, not respecting area-redraws. Also cleaned up drawing for it,
and moved the "swap buffers indicator" square to look nicer. Those squares
are only for test!
- event-match function had bad code for checking for event-value. Made a
"KM_ANY" define so keymaps can be defined ignoring event values.
- Gesture todo: lasso, "real gesture" (like blender now has)
* Added RNA for operators. This still uses ID properties internally,
but through the RNA API now. The OP_get/set_* API that was used is
replaced by the RNA API. Currently RNA properties for operators are
defined at runtime since it means operator registration can be done
in a single function.
* Changed the existing operators to use this system, I haven't defined
user interface names yet though. I also think there need to be some
conventions on which properties to expose to make these operators
usable in macros, for example if mouse coordinates should be stored
or not.
* When using ID properties through defined RNA properties, it now
checks that the ID property actually matches the RNA property and
removes/overwrites it otherwise. This ensures that you can safely
get/set arrays for example without having to worry that some
external thing may have changed the length.
* Documentation now has some information on RNA + ID properties.
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/RNA
- operator definitions, callbacks, registry to WM and handlers for it are
now always in a file xxxx_ops.c or xxxx_operators.c, in the bottom you
will find the registry and handler code.
- fixed some confusing naming conventions "rip_area vs area_join" etc. Now
stick to convention to first name subject, then operation (like UI :).
So it's area_rip, screen_add, and so on.
- Nicely put exported calls (outside module) together in bottom: this using
names such as ED_screen_duplicate().
- Moved Operator-Property API to new C file.
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
- moved from WM to Screen code (it uses active area)
- less code :) result of cleaning some calls
- added WM_window_open() to WM API for this
- now opens new window on top of area, and leaves old screen unaffected
(simple, atomic, the 'do not think for user' convention :)
- cleaned up join and split operations. Most noticable is operator callback
design, which should make a design based on user-less exec() first, then
wrap invoke() and modal() around it. The exec() should be callable with
only Context and properties.
- split now works again; and inversed as previously, if you drag from a
triangle (action zone) inside area it subdivides area as expected.
- dragging from triangle outside area, over an edge, joins areas
- split has been simplified, it had too many options... it could just work
simpler (now)
- 'action zone' now is an operator itself, a widget sending an ACTIONZONE event,
which can be handled by others (so other gestures can be added in action zone
too)
Still evaluating:
- context gets set where?
- code structure confuses... what are proper functions for operators?
- what is WM... should low level screen stuff more there?
- when do you send event, notifier?
- files grow to large, will clean
Oh yeah and docs, docs, docs. Coming! :)
* Added functions to generate Timer events. There was some unfinished code to
create one timer per window, this replaces that with a way to let operators
or other handlers add/remove their own timers as needed. This is currently
delivered as an event with the timer handle, perhaps this should be a notifier
instead? Also includes some fixes in ghost for timer events that were not
delivered in time, due to passing negative timeout.
* Added a Message event, which is a generic event that can be added by any
operator. This is used in the UI code to communicate the results of opened
blocks. Again, this may be better as a notifier.
* These two events should not be blocked as they are intended for a specific
operator or handler, so there were exceptions added for this, which is one
of the reasons they might work better as notifiers, but currently these
things can't listen to notifier yet.
* Added an option to events to indicate if the customdata should be freed or
not.
* Added a free() callback for area regions, and added a free function for
area regions in blenkernel since it was already there for screens and areas.
* Added ED_screen/area/region_exit functions to clean up things like operators
and handlers when they are closed.
* Added screen level regions, these will draw over areas boundaries, with the
last created region on top. These are useful for tooltips, menus, etc, and
are not saved to file. It's using the same ARegion struct as areas to avoid
code duplication, but perhaps that should be renamed then. Note that redraws
currently go correct, because only full window redraws are used, for partial
redraws without any frontbuffer drawing, the window manager needs to get
support for compositing subwindows.
* Minor changes in the subwindow code to retrieve the matrix, and moved
setlinestyle to glutil.c.
* Reversed argument order in WM_event_add/remove_keymap_handler to be consistent
with modal_handler.
* Operators can now block events but not necessarily cancel/finish.
* Modal operators are now stored in a list in the window/area/region they were
created in. This means for example that when a transform operator is invoked
from a region but registers a handler at the window level (since mouse motion
across areas should work), it will still get removed when the region is closed
while the operator is running.
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
After check this a little more I make some changes to the
API and now work on the following form:
WM_gesture_init(C, type);
while() {
/* handler event, etc */
/* if something change. */
if(need_update) {
/* update the gesture data and notify about it. */
WM_gesture_update(C, data);
WM_event_add_notifier (.. WM_NOTE_GESTURE_CHANGE ..);
}
}
WM_gesture_end(C, type);
Another of the change is that now the gesture data is a link list
in the window struct, so we can have multiples "gestures" (but
of different type) at the same time.
Also take care that the "gesture data" is reusable, that mean that
only alloc it 1 time and use in all the place, that is
why don't support multiple gesture of the same type, but of course
that can be change.
This is a first implementation of the "gesture manager" system,
the idea is put the WM in a automatic draw mode so we can
implement different "Gesture types" to draw different class
of data (lasso, bound box, etc).
The gesture data is passed through the data field of the notifiers,
i think that we can change this to something like:
WM_gesture_init(C, data); /* put the data in the context. */
while() {
/* send WM_NOTE_GESTURE_CHANGED to update screen */
}
/* send event and free the data in the context. */
WM_gesture_end(C);
Also i add a new operator and event to test the gesture manager.
The new operator is the "border select" function, just press BKEY
in the window and LMB or ESCKEY to exit.
In the case of LMB you can see a print in the console about the
BORDERSELECT event.
All this still need a lot of work, comment are welcome.
Now you can set/get: float, arrays (int and float) and string.
The only special function is OP_get_string, it is special
because return a pointer to the IDProperty data, so you can't
change/resize/free the string.
It's possible "fix" this with:
1) Return a "const char"
2) Return a duplicate string
All this new function are not in use yet, but i make a simple test
with the "move areas" operator (add a property of every type and then
print the result in the other size) and work fine, more test are welcome.
Other thing to check is the new OP_free_property function, because this
properties are only local to the operator, i choice free all this in the
"exit callback" of every operator (only move areas have property now),
so comment about this are welcome too :)
Also add some notes to the WM_api.h file.
This is a simple API around IDProperty to store properties
in the Operator, it is really simple and this first commit
just add support for IDP_INT data type.
Take care that this "properties" are not save yet and you get
some "Error totblock" more with this.
I add some notes to the WM_api.h file, please check this,
comment and ideas are welcome.
- on mouse-over edge, you can drag area borders around.
- note it's a handerized system now, so it updates UI while you
move mouse.
Feedback needed:
- read bottom part of the screen_edit.c file. It's the proposed
method for adding tools and handlers. I think it's close, but
might need some tweaks.
- removed editors/area and put this all in screen
- added first python calls (note, a new c file for scriptlinks)
- added view3d editor callbacks (no drawing yet)
- added files in editors/interface
(Cmake and Scons has to be fixed, help welcome!)
- now areas/headers are being converted on file read
- note: previously saved 2.50 files will crash!!! (.B.blend)
- area regions are being drawn, first handler for cursor added (on edge)
- window duplicate and scale works correct for screen subdiv
Todos for me:
- need to fix things in syntax (function names) a bit still
- more operators for screen
- define how Context will work... still unresolved when it gets set
- docs!
Reviews of code structure is welcome!
There are also more todos now for others, but it can wait a couple of days
- first work on getting area/screen handling back
- added structure for where to put stuff, is still under
review, wait a bit for docs?
Campbell is working on removing every bad level include from
sources, so we can safely rebuild the src/ directory.