1 /*
2 * The Sciter Engine of Terra Informatica Software, Inc.
3 * http://sciter.com
4 *
5 * The code and information provided "as-is" without
6 * warranty of any kind, either expressed or implied.
7 *
8 * (C) 2003-2015, Terra Informatica Software, Inc.
9 */
10
11 /*
12 * Behaviors support (a.k.a windowless controls)
13 */
14
15 #ifndef __sciter_x_behavior_h__
16 #define __sciter_x_behavior_h__
17
26
27 #pragma pack(push,8)
28
32 {
53
55 };
56
67 // signature of the function exported from external behavior/dll.
69
71 {
73 SINKING = 0x8000,
// capture (immersion) phase, this flag is or'ed with EVENTS codes below 75 // see: http://www.w3.org/TR/xml-events/Overview.html#s_intro
76 };
77
79 {
83 };
84
86 {
90 };
91
92 // parameters of evtg == HANDLE_INITIALIZATION
93
95 {
98 };
99
101 {
102 UINT
cmd;
// INITIALIZATION_EVENTS 103 };
104
106 {
110 };
111
112 // parameters of evtg == HANDLE_MOUSE
113
115 {
125
126 DROP = 9,
// item dropped, target is that dropped item 127 DRAG_ENTER = 0xA,
// drag arrived to the target element that is one of current drop targets. 128 DRAG_LEAVE = 0xB,
// drag left one of current drop targets. target is the drop target element. 129 DRAG_REQUEST = 0xC,
// drag src notification before drag start. To cancel - return true from handler. 130
132
133 DRAGGING = 0x100,
// This flag is 'ORed' with MOUSE_ENTER..MOUSE_DOWN codes if dragging operation is in effect. 134 // E.g. event DRAGGING | MOUSE_MOVE is sent to underlying DOM elements while dragging.
135
136 };
137
139 {
142 POINT
pos;
// position of cursor, element relative 143 POINT
pos_view;
// position of cursor, view relative 147 BOOL
is_on_icon;
// mouse is over icon (foreground-image, foreground-repeat:no-repeat) 148
149 HELEMENT dragging;
// element that is being dragged over, this field is not NULL if (cmd & DRAGGING) != 0 151
152 };
153
155 {
172 };
173
174
175 // parameters of evtg == HANDLE_KEY
176
178 {
182 };
183
185 {
188 UINT
key_code;
// key scan code, or character unicode for KEY_CHAR 190 };
191
192 // parameters of evtg == HANDLE_FOCUS
193
195 {
196 FOCUS_LOST = 0,
// non-bubbling event, target is new focus element 197 FOCUS_GOT = 1,
// non-bubbling event, target is old focus element 198 FOCUS_IN = 2,
// bubbling event/notification, target is an element that got focus 199 FOCUS_OUT = 3,
// bubbling event/notification, target is an element that lost focus 200 };
201
203 {
205 HELEMENT target;
// target element, for FOCUS_LOST it is a handle of new focus element 206 // and for FOCUS_GOT it is a handle of old focus element, can be NULL
208 BOOL
cancel;
// in FOCUS_LOST phase setting this field to true will cancel transfer focus from old element to the new one. 209 };
210
211 // parameters of evtg == HANDLE_SCROLL
212
214 {
225 };
226
228 {
229 UINT
cmd;
// SCROLL_EVENTS 231 INT
pos;
// scroll position if SCROLL_POS 233 };
234
236 {
243 };
245 {
249 };
250
252 {
259
263 };
264
266 {
267 UINT
cmd;
// GESTURE_EVENTS 269 POINT
pos;
// position of cursor, element relative 270 POINT
pos_view;
// position of cursor, view relative 271 UINT
flags;
// for GESTURE_REQUEST combination of GESTURE_FLAGs. 272 // for others it is a combination of GESTURE_STATe's
274 SIZE
delta_xy;
// for GESTURE_PAN it is a direction vector 275 double delta_v;
// for GESTURE_ROTATE - delta angle (radians) 276 // for GESTURE_ZOOM - zoom value, is less or greater than 1.0
277 };
278
280 {
284 };
285
287
289 {
292 RECT
area;
// element area, to get invalid area to paint use GetClipBox, 293 UINT
reserved;
// for DRAW_BACKGROUND/DRAW_FOREGROUND - it is a border box 294 // for DRAW_CONTENT - it is a content box
295 };
296
300 };
301
303 {
311
313 // here DOM of popup element can be modifed.
314 POPUP_READY = 8,
// popup element has been measured and ready to be shown on screen, 315 // here you can use functions like ScrollToView.
317 // here DOM of popup element can be modifed again - e.g. some items can be removed
318 // to free memory.
319
322 // BEHAVIOR_EVENT_PARAMS structure layout
323 // BEHAVIOR_EVENT_PARAMS.cmd - MENU_ITEM_CLICK/MENU_ITEM_ACTIVE
324 // BEHAVIOR_EVENT_PARAMS.heTarget - owner(anchor) of the menu
325 // BEHAVIOR_EVENT_PARAMS.he - the menu item, presumably <li> element
326 // BEHAVIOR_EVENT_PARAMS.reason - BY_MOUSE_CLICK | BY_KEY_CLICK
327
328
329 CONTEXT_MENU_REQUEST = 0x10,
// "right-click", BEHAVIOR_EVENT_PARAMS::he is current popup menu HELEMENT being processed or NULL. 330 // application can provide its own HELEMENT here (if it is NULL) or modify current menu element.
331
333 DISABLED_STATUS_CHANGED = 0x12,
// broadcast notification, sent to all elements of some container that got new value of :disabled state 334
336
337 CONTENT_CHANGED = 0x15,
// content has been changed, is posted to the element that gets content changed, reason is combination of CONTENT_CHANGE_BITS. 338 // target == NULL means the window got new document and this event is dispatched only to the window.
339
342
343 // "grey" event codes - notfications from behaviors from this SDK
345
346 //TABLE_HEADER_CLICK, // click on some cell in table header,
347 // // target = the cell,
348 // // reason = index of the cell (column number, 0..n)
349 //TABLE_ROW_CLICK, // click on data row in the table, target is the row
350 // // target = the row,
351 // // reason = index of the row (fixed_rows..n)
352 //TABLE_ROW_DBL_CLICK, // mouse dbl click on data row in the table, target is the row
353 // // target = the row,
354 // // reason = index of the row (fixed_rows..n)
355
356 ELEMENT_COLLAPSED = 0x90,
// element was collapsed, so far only behavior:tabs is sending these two to the panels 358
360 // used for example by accesskeys behaviors to send activation request, e.g. tab on behavior:tabs.
361
362 //DO_SWITCH_TAB = ACTIVATE_CHILD,// command to switch tab programmatically, handled by behavior:tabs
363 // // use it as SciterPostEvent(tabsElementOrItsChild, DO_SWITCH_TAB, tabElementToShow, 0);
364
366
367 ROWS_DATA_REQUEST,
// request from virtual grid to data source behavior to fill data in the table 368 // parameters passed throug DATA_ROWS_PARAMS structure.
369
371 // is sent for example by behavior:richtext when caret position/selection has changed.
372
373 FORM_SUBMIT,
// behavior:form detected submission event. BEHAVIOR_EVENT_PARAMS::data field contains data to be posted. 374 // BEHAVIOR_EVENT_PARAMS::data is of type T_MAP in this case key/value pairs of data that is about
375 // to be submitted. You can modify the data or discard submission by returning true from the handler.
376 FORM_RESET,
// behavior:form detected reset event (from button type=reset). BEHAVIOR_EVENT_PARAMS::data field contains data to be reset. 377 // BEHAVIOR_EVENT_PARAMS::data is of type T_MAP in this case key/value pairs of data that is about
378 // to be rest. You can modify the data or discard reset by returning true from the handler.
379
381
387
390
391 ANIMATION = 0xA0,
// animation started (reason=1) or ended(reason=0) on the element. 392
393 DOCUMENT_CREATED = 0xC0,
// document created, script namespace initialized. target -> the document 394 DOCUMENT_CLOSE_REQUEST = 0xC1,
// document is about to be closed, to cancel closing do: evt.data = sciter::value("cancel"); 396 DOCUMENT_READY = 0xC3,
// document has got DOM structure, styles and behaviors of DOM elements. Script loading run is complete at this moment. 397
402 // If you want to provide your own video frames source for the given target <video> element do the following:
403 // 1. Handle and consume this VIDEO_BIND_RQ request
404 // 2. You will receive second VIDEO_BIND_RQ request/event for the same <video> element
405 // but this time with the 'reason' field set to an instance of sciter::video_destination interface.
406 // 3. add_ref() it and store it for example in worker thread producing video frames.
407 // 4. call sciter::video_destination::start_streaming(...) providing needed parameters
408 // call sciter::video_destination::render_frame(...) as soon as they are available
409 // call sciter::video_destination::stop_streaming() to stop the rendering (a.k.a. end of movie reached)
410
414
416 // all custom event codes shall be greater
417 // than this number. All codes below this will be used
418 // solely by application - Sciter will not intrepret it
419 // and will do just dispatching.
420 // To send event notifications with these codes use
421 // SciterSend/PostEvent API.
422
423 };
424
426 {
430 };
431
433 {
438 };
439
441 {
442 UINT
cmd;
// BEHAVIOR_EVENTS 443 HELEMENT heTarget;
// target element handler, in MENU_ITEM_CLICK this is owner element that caused this menu - e.g. context menu owner 444 // In scripting this field named as Event.owner
445 HELEMENT he;
// source element e.g. in SELECTION_CHANGED it is new selected <option>, in MENU_ITEM_CLICK it is menu item (LI) element 446 UINT_PTR
reason;
// EVENT_REASON or EDIT_CHANGED_REASON - UI action causing change. 447 // In case of custom event notifications this may be any
448 // application specific value.
450 data;
// auxiliary data accompanied with the event. E.g. FORM_SUBMIT event is using this field to pass collection of values. 452
454 {
455 UINT_PTR
timerId;
// timerId that was used to create timer by using SciterSetTimer 457
458
459
460 // identifiers of methods currently supported by intrinsic behaviors,
461 // see function SciterCallBehaviorMethod
462
464 {
468 // p - TEXT_VALUE_PARAMS
469
471 // p - TEXT_EDIT_SELECTION_PARAMS
472
474 // p - TEXT_EDIT_SELECTION_PARAMS
475
476 // Replace selection content or insert text at current caret position.
477 // Replaced text will be selected.
479 // p - TEXT_EDIT_REPLACE_SELECTION_PARAMS
480
481 // Set value of type="vscrollbar"/"hscrollbar"
484
489
490 IS_EMPTY = 0xFC,
// p - IS_EMPTY_PARAMS // set VALUE_PARAMS::is_empty (false/true) reflects :empty state of the element. 493
495 };
496
498 {
504
506 {
510 // parameters are accessible through tiscript::args.
512
513 // GET_VALUE/SET_VALUE methods params
515 {
518 #ifdef __cplusplus
520 #endif
521 };
522
523 // IS_EMPTY method params
525 {
528 #ifdef __cplusplus
530 #endif
531 };
532
533 // see SciterRequestElementData
534
536 {
540 UINT
dataType;
// data type passed "as is" from SciterRequestElementData 541 UINT
status;
// status = 0 (dataSize == 0) - unknown error. 542 // status = 100..505 - http response status, Note: 200 - OK!
543 // status > 12000 - wininet error code, see ERROR_INTERNET_*** in wininet.h
544 LPCWSTR
uri;
// requested url 546
547
548
549 #pragma pack(pop)
550
551 #ifdef __cplusplus
552
553 #pragma warning(disable:4786) //identifier was truncated...
554 #pragma warning(disable:4100) //unreferenced formal parameter
555
557 {
558
559 // event handler which can be attached to any DOM element.
560 // event handler can be attached to the element as a "behavior" (see below)
561 // or by sciter::dom::element::attach( event_handler* eh )
562
563 struct event_handler
564 {
565 event_handler() // EVENT_GROUPS flags
566 {
567 }
568
569 virtual void detached (
HELEMENT /*he*/ ) { }
570 virtual void attached (
HELEMENT /*he*/ ) { }
571
572 // defines list of event groups this event_handler is subscribed to
573 virtual bool subscription(
HELEMENT he, UINT& event_groups )
574 {
576 return true;
577 }
578
579 // handlers with extended interface
580 // by default they are calling old set of handlers (for compatibility with legacy code)
581
582 /*virtual bool handle_mouse (HELEMENT he, MOUSE_PARAMS& params ) { return false; }
583 virtual bool handle_key (HELEMENT he, KEY_PARAMS& params ) { return false; }
584 virtual bool handle_focus (HELEMENT he, FOCUS_PARAMS& params ) { return false; }
585 virtual bool handle_timer (HELEMENT he ) { return false; }
586 virtual void handle_size (HELEMENT he ) { }
587 virtual bool handle_draw (HELEMENT he, DRAW_PARAMS& params ) { return false; }
588 virtual bool handle_method_call (HELEMENT he, METHOD_PARAMS& params ) { return false; }
589 virtual bool handle_event (HELEMENT he, BEHAVIOR_EVENT_PARAMS& params ) { return false; }
590 virtual bool handle_data_arrived (HELEMENT he, DATA_ARRIVED_PARAMS& params ) { return false; }
591
592 virtual bool handle_scripting_call(HELEMENT he, SCRIPTING_METHOD_PARAMS& params )
593 {
594 return false;
595 }*/
596
598 {
600 }
602 {
604 }
606 {
607 return on_focus( he, params.
target, params.
cmd );
608 }
610 {
612 return on_timer( he, params.
timerId );
613 return on_timer( he );
614 }
615
616 virtual void handle_size (
HELEMENT he )
617 {
618 on_size( he );
619 }
621 {
623 }
624
626 {
627 return false;
628 }
629
631 {
632 return on_draw(he, params.
cmd, params.
gfx, params.
area );
633 }
634
636 {
637 return on_method_call(he, UINT(params.
methodID), ¶ms );
638 }
639
640 // notification events from builtin behaviors - synthesized events: BUTTON_CLICK, VALUE_CHANGED
641 // see enum BEHAVIOR_EVENTS
643 {
645 }
646
647 // notification event: data requested by SciterRequestElementData just delivered
649 {
651 }
652
654 {
656 }
657
659 {
660 return on_script_call(he, params.
vm, params.
tag, params.
result);
661 }
662
663
664 //
665 // alternative set of event handlers (aka old set).
666 //
667 virtual bool on_mouse (
HELEMENT he,
HELEMENT target, UINT event_type, POINT pt, UINT mouseButtons, UINT keyboardStates ) {
return false; }
668 virtual bool on_key (
HELEMENT he,
HELEMENT target, UINT event_type, UINT code, UINT keyboardStates ) {
return false; }
669 virtual bool on_focus (
HELEMENT he,
HELEMENT target, UINT event_type ) {
return false; }
670 virtual bool on_timer (
HELEMENT he ) {
return false;
/*stop this timer*/ }
671 virtual bool on_timer (
HELEMENT he, UINT_PTR extTimerId ) {
return false;
/*stop this timer*/ }
672 virtual bool on_draw (
HELEMENT he, UINT draw_type,
HGFX hgfx,
const RECT& rc ) {
return false;
/*do default draw*/ }
673 virtual void on_size (
HELEMENT he ) { }
674
675 virtual bool on_method_call (
HELEMENT he, UINT methodID,
METHOD_PARAMS* params ) {
return false;
/*not handled*/ }
676
677 // calls from CSSS! script and TIScript (if it was not handled by method below). Override this if you want your own methods to the CSSS! namespace.
678 // Follwing declaration:
679 // #my-active-on {
680 // when-click: r = self.my-method(1,"one");
681 // }
682 // will end up with on_script_call(he, "my-method" , 2, argv, retval );
683 // where argv[0] will be 1 and argv[1] will be "one".
685
686 // Calls from TIScript. Override this if you want your own methods accessible directly from tiscript engine.
687 // Use tiscript::args to access parameters.
689
690 // notification events from builtin behaviors - synthesized events: BUTTON_CLICK, VALUE_CHANGED
691 // see enum BEHAVIOR_EVENTS
693
694 // notification event: data requested by SciterRequestElementData just delivered
695 virtual bool on_data_arrived (
HELEMENT he,
HELEMENT initiator,
LPCBYTE data, UINT dataSize, UINT dataType ) {
return false; }
696
698
699 // ElementEventProc implementeation
700 static BOOL SC_CALLBACK element_proc(LPVOID tag,
HELEMENT he, UINT evtg, LPVOID prms )
701 {
702 event_handler* pThis = static_cast<event_handler*>(tag);
703 if( pThis ) switch( evtg )
704 {
706 {
707 UINT *p = (UINT *)prms;
708 return pThis->subscription( he, *p );
709 }
711 {
714 pThis->detached(he);
716 pThis->attached(he);
717 return true;
718 }
728 case HANDLE_SIZE: { pThis->handle_size(he);
return false; }
729 // call using sciter::value's (from CSSS!)
731 // call using tiscript::value's (from the script)
734 default:
735 assert(false);
736 }
737 return false;
738 }
739 };
740
741
742 //
743 // "behavior" is a named event_handler
744 // behaviors organized into one global list to be processed
745 // automaticly while handling HLN_ATTACH_BEHAVIOR notification
746 //
747
748 struct behavior_factory
749 {
750 behavior_factory(const char* external_name)
751 :next(0),name(external_name)
752 {
753 // add this implementation to the list (singleton)
754 next = root();
755 root(this);
756 }
757
758 // needs to be overriden
759 virtual event_handler* create(
HELEMENT he) = 0;
760
761 // behavior list support
762 behavior_factory* next;
763 const char* name; // name must be a pointer to a static string
764
765 // returns behavior implementation by name.
766 static event_handler* create(
const char* name,
HELEMENT he)
767 {
768 for(behavior_factory* t = root(); t; t = t->next)
769 if(strcmp(t->name,name)==0)
770 {
771 return t->create(he);
772 }
773 return 0; // not found
774 }
775 // implementation of static list of behaviors
776 static behavior_factory* root(behavior_factory* to_set = 0)
777 {
778 static behavior_factory* _root = 0;
779 if(to_set) _root = to_set;
780 return _root;
781 }
782
783 };
784
785 inline void attach_dom_event_handler(HWINDOW hwnd, event_handler* ph)
786 {
789 }
790 inline void detach_dom_event_handler(HWINDOW hwnd, event_handler* ph)
791 {
794 }
795
796 #define BEGIN_FUNCTION_MAP \
797 virtual bool on_script_call(HELEMENT he, LPCSTR name, UINT argc, sciter::value* argv, sciter::value& retval) \
798 { \
799 aux::chars _name = aux::chars_of(name);
800
801 #define FUNCTION_V(name, method) \
802 if( const_chars(name) == _name ) \
803 { retval = method(argc,argv); return true; }
804 #define FUNCTION_0(name, method) \
805 if( const_chars(name) == _name && argc == 0) \
806 { retval = method(); return true; }
807 #define FUNCTION_1(name, method) \
808 if( const_chars(name) == _name && argc == 1) \
809 { retval = method(argv[0]); return true; }
810 #define FUNCTION_2(name, method) \
811 if( const_chars(name) == _name && argc == 2) \
812 { retval = method(argv[0],argv[1]); return true; }
813 #define FUNCTION_3(name, method) \
814 if( const_chars(name) == _name && argc == 3) \
815 { retval = method(argv[0],argv[1],argv[2]); return true; }
816 #define FUNCTION_4(name, method) \
817 if( const_chars(name) == _name && argc == 4) \
818 { retval = method(argv[0],argv[1],argv[2],argv[3]); return true; }
819 #define FUNCTION_5(name, method) \
820 if( const_chars(name) == _name && argc == 5) \
821 { retval = method(argv[0],argv[1],argv[2],argv[3],argv[4]); return true; }
822 #define CHAIN_FUNCTION_MAP(SUPER_T) \
823 if(SUPER_T::on_script_call(he, name, argc, argv, retval)) return true;
824
825 #define END_FUNCTION_MAP \
826 return false; }
827
828
829 } //namespace sciter
830
831 #endif //__cplusplus
832
833
834
835
836 #endif
837
BOOL SC_CALLBACK ElementEventProc(LPVOID tag, HELEMENT he, UINT evtg, LPVOID prms)
struct TIMER_PARAMS TIMER_PARAMS
SCDOM_RESULT SCAPI SciterWindowDetachEventHandler(HWINDOW hwndLayout, LPELEMENT_EVENT_PROC pep, LPVOID tag)
struct DATA_ARRIVED_PARAMS DATA_ARRIVED_PARAMS
ElementEventProc * LPElementEventProc
struct BEHAVIOR_EVENT_PARAMS BEHAVIOR_EVENT_PARAMS
struct TISCRIPT_METHOD_PARAMS TISCRIPT_METHOD_PARAMS
struct SCRIPTING_METHOD_PARAMS SCRIPTING_METHOD_PARAMS
SCDOM_RESULT SCAPI SciterWindowAttachEventHandler(HWINDOW hwndLayout, LPELEMENT_EVENT_PROC pep, LPVOID tag, UINT subscription)
BEHAVIOR_METHOD_IDENTIFIERS
struct SCITER_GRAPHICS SCITER_GRAPHICS
struct tiscript_VM tiscript_VM
BOOL SC_CALLBACK SciterBehaviorFactory(LPCSTR, HELEMENT, LPElementEventProc *, LPVOID *)
const std::vector< sciter::string > & argv()