Blender  V2.93
screen_ops.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 #include <string.h>
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_blenlib.h"
30 #include "BLI_dlrbTree.h"
31 #include "BLI_math.h"
32 #include "BLI_utildefines.h"
33 
34 #include "BLT_translation.h"
35 
36 #include "DNA_anim_types.h"
37 #include "DNA_armature_types.h"
38 #include "DNA_curve_types.h"
39 #include "DNA_lattice_types.h"
40 #include "DNA_mask_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meta_types.h"
43 #include "DNA_node_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_userdef_types.h"
47 #include "DNA_workspace_types.h"
48 
49 #include "BKE_context.h"
50 #include "BKE_editmesh.h"
51 #include "BKE_fcurve.h"
52 #include "BKE_global.h"
53 #include "BKE_icons.h"
54 #include "BKE_lib_id.h"
55 #include "BKE_main.h"
56 #include "BKE_mask.h"
57 #include "BKE_object.h"
58 #include "BKE_report.h"
59 #include "BKE_scene.h"
60 #include "BKE_screen.h"
61 #include "BKE_sound.h"
62 #include "BKE_workspace.h"
63 
64 #include "WM_api.h"
65 #include "WM_types.h"
66 
67 #include "DEG_depsgraph.h"
68 #include "DEG_depsgraph_query.h"
69 
70 #include "ED_anim_api.h"
71 #include "ED_armature.h"
72 #include "ED_clip.h"
73 #include "ED_image.h"
74 #include "ED_keyframes_draw.h"
75 #include "ED_mesh.h"
76 #include "ED_object.h"
77 #include "ED_screen.h"
78 #include "ED_screen_types.h"
79 #include "ED_sequencer.h"
80 #include "ED_undo.h"
81 #include "ED_util.h"
82 #include "ED_view3d.h"
83 
84 #include "RNA_access.h"
85 #include "RNA_define.h"
86 #include "RNA_enum_types.h"
87 
88 #include "UI_interface.h"
89 #include "UI_resources.h"
90 #include "UI_view2d.h"
91 
92 #include "GPU_capabilities.h"
93 
94 #include "screen_intern.h" /* own module include */
95 
96 #define KM_MODAL_CANCEL 1
97 #define KM_MODAL_APPLY 2
98 #define KM_MODAL_SNAP_ON 3
99 #define KM_MODAL_SNAP_OFF 4
100 
101 /* -------------------------------------------------------------------- */
106 {
107  if (CTX_wm_window(C) == NULL) {
108  return false;
109  }
110  if (CTX_wm_screen(C) == NULL) {
111  return false;
112  }
113  if (CTX_wm_region(C) == NULL) {
114  return false;
115  }
116  return true;
117 }
118 
120 {
121  if (CTX_wm_window(C) == NULL) {
122  return false;
123  }
124  if (CTX_wm_screen(C) == NULL) {
125  return false;
126  }
127  if (CTX_wm_area(C) == NULL) {
128  return false;
129  }
130  return true;
131 }
132 
134 {
135  if (CTX_wm_window(C) == NULL) {
136  return false;
137  }
138  if (CTX_wm_screen(C) == NULL) {
139  return false;
140  }
141  return true;
142 }
143 
145 {
146  if (G.background) {
147  return false;
148  }
149  return ED_operator_screenactive(C);
150 }
151 
152 /* XXX added this to prevent anim state to change during renders */
154 {
155  if (G.is_rendering) {
156  return false;
157  }
158  if (CTX_wm_window(C) == NULL) {
159  return false;
160  }
161  if (CTX_wm_screen(C) == NULL) {
162  return false;
163  }
164  return true;
165 }
166 
167 /* when mouse is over area-edge */
169 {
170  if (CTX_wm_window(C) == NULL) {
171  return false;
172  }
173  bScreen *screen = CTX_wm_screen(C);
174  if (screen == NULL) {
175  return false;
176  }
177  if (screen->active_region != NULL) {
178  return false;
179  }
180  return true;
181 }
182 
184 {
186  if (scene) {
187  return true;
188  }
189  return false;
190 }
191 
193 {
195  if (scene && !ID_IS_LINKED(scene)) {
196  return true;
197  }
198  return false;
199 }
200 
202 {
204  Object *obact = CTX_data_active_object(C);
205 
206  if (scene == NULL || ID_IS_LINKED(scene)) {
207  return false;
208  }
209  if (CTX_data_edit_object(C)) {
210  return false;
211  }
212 
213  /* add a check for ob->mode too? */
214  if (obact && (obact->mode != OB_MODE_OBJECT)) {
215  return false;
216  }
217 
218  return true;
219 }
220 
221 static bool ed_spacetype_test(bContext *C, int type)
222 {
223  if (ED_operator_areaactive(C)) {
225  return sl && (sl->spacetype == type);
226  }
227  return false;
228 }
229 
231 {
233 }
234 
236 {
237  if (CTX_wm_region_view3d(C)) {
238  return true;
239  }
240 
241  CTX_wm_operator_poll_msg_set(C, "expected a view3d region");
242  return false;
243 }
244 
245 /* generic for any view2d which uses anim_ops */
247 {
248  if (ED_operator_areaactive(C)) {
250  if (sl && (ELEM(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH))) {
251  return true;
252  }
253  }
254 
255  CTX_wm_operator_poll_msg_set(C, "expected a timeline/animation area to be active");
256  return false;
257 }
258 
260 {
262 }
263 
265 {
268  Object *obedit = CTX_data_edit_object(C);
269  if (ob && ob == obedit) {
270  return false;
271  }
272  return true;
273  }
274  return false;
275 }
276 
278 {
279  return ed_spacetype_test(C, SPACE_FILE);
280 }
281 
283 {
285 }
286 
288 {
290 }
291 
293 {
294  SpaceNode *snode = CTX_wm_space_node(C);
295 
296  if (snode && snode->edittree) {
297  return true;
298  }
299 
300  return false;
301 }
302 
304 {
305  SpaceNode *snode = CTX_wm_space_node(C);
306 
307  if (snode && snode->edittree && !ID_IS_LINKED(snode->edittree)) {
308  return true;
309  }
310 
311  return false;
312 }
313 
315 {
317 }
318 
320 {
321  return ed_spacetype_test(C, SPACE_SEQ);
322 }
323 
325 {
327 }
328 
330 {
332 }
333 
335 {
336  return ed_spacetype_test(C, SPACE_NLA);
337 }
338 
340 {
341  return ed_spacetype_test(C, SPACE_INFO);
342 }
343 
345 {
347 }
348 
349 static bool ed_object_hidden(const Object *ob)
350 {
351  /* if hidden but in edit mode, we still display, can happen with animation */
352  return ((ob->restrictflag & OB_RESTRICT_VIEWPORT) && !(ob->mode & OB_MODE_EDIT));
353 }
354 
356 {
358  return ((ob != NULL) && !ed_object_hidden(ob));
359 }
360 
362 {
363  return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob));
364 }
365 
367 {
370 }
371 
374 {
376 }
377 
379 {
382 }
383 
385 {
387  return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && (ob->type == OB_MESH) &&
389 }
390 
392 {
394  return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && (ob->type == OB_FONT) &&
396 }
397 
399 {
401  return (mesh != NULL) && !ID_IS_LINKED(mesh) && !ID_IS_OVERRIDE_LIBRARY(mesh);
402 }
403 
405 {
406  Object *obedit = CTX_data_edit_object(C);
407  if (obedit && obedit->type == OB_MESH) {
408  return NULL != BKE_editmesh_from_object(obedit);
409  }
410  return false;
411 }
412 
414 {
416 }
417 
419 {
421  return true;
422  }
423 
424  CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editmesh");
425  return false;
426 }
427 
429 {
430  Object *obedit = CTX_data_edit_object(C);
431  if (obedit && obedit->type == OB_MESH && (((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH)) {
432  return NULL != BKE_editmesh_from_object(obedit);
433  }
434  return false;
435 }
436 
438 {
439  Object *obedit = CTX_data_edit_object(C);
440  if (obedit && obedit->type == OB_ARMATURE) {
441  return NULL != ((bArmature *)obedit->data)->edbo;
442  }
443  return false;
444 }
445 
454 {
455  Object *obact = CTX_data_active_object(C);
456 
457  if (obact && !(obact->mode & OB_MODE_EDIT)) {
458  Object *obpose = BKE_object_pose_armature_get(obact);
459  if (obpose != NULL) {
460  if (obact == obpose) {
461  return true;
462  }
463  }
464  }
465 
466  return false;
467 }
468 
469 /* allows for pinned pose objects to be used in the object buttons
470  * and the non-active pose object to be used in the 3D view */
472 {
474 
475  if (obpose && !(obpose->mode & OB_MODE_EDIT)) {
476  if (BKE_object_pose_context_check(obpose)) {
477  return true;
478  }
479  }
480 
481  return false;
482 }
483 
485 {
486  Object *obact = CTX_data_active_object(C);
487 
488  if (obact && !(obact->mode & OB_MODE_EDIT)) {
489  Object *obpose = BKE_object_pose_armature_get(obact);
490  if (obpose != NULL) {
491  if ((obact == obpose) || (obact->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
492  return true;
493  }
494  }
495  }
496 
497  return false;
498 }
499 
501 {
502  if (ED_operator_posemode(C)) {
504  bArmature *arm = ob->data;
505  return !(ID_IS_LINKED(&ob->id) || ID_IS_LINKED(&arm->id));
506  }
507  return false;
508 }
509 
510 /* wrapper for ED_space_image_show_uvedit */
512 {
514  Object *obedit = CTX_data_edit_object(C);
515  return ED_space_image_show_uvedit(sima, obedit);
516 }
517 
519 {
521  Object *obedit = CTX_data_edit_object(C);
522  return sima && ED_space_image_show_uvedit(sima, obedit);
523 }
524 
526 {
527  Object *obedit = CTX_data_edit_object(C);
528  BMEditMesh *em = NULL;
529 
530  if (obedit && obedit->type == OB_MESH) {
531  em = BKE_editmesh_from_object(obedit);
532  }
533 
534  if (em && (em->bm->totface)) {
535  return true;
536  }
537 
538  return false;
539 }
540 
542 {
543  Object *obedit = CTX_data_edit_object(C);
544  if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) {
545  return NULL != ((Curve *)obedit->data)->editnurb;
546  }
547  return false;
548 }
549 
551 {
553  return true;
554  }
555 
556  CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editcurve");
557  return false;
558 }
559 
561 {
562  Object *obedit = CTX_data_edit_object(C);
563  if (obedit && obedit->type == OB_CURVE) {
564  return NULL != ((Curve *)obedit->data)->editnurb;
565  }
566  return false;
567 }
568 
570 {
571  Object *obedit = CTX_data_edit_object(C);
572  if (obedit && obedit->type == OB_CURVE) {
573  Curve *cu = (Curve *)obedit->data;
574 
575  return (cu->flag & CU_3D) && (NULL != cu->editnurb);
576  }
577  return false;
578 }
579 
581 {
582  Object *obedit = CTX_data_edit_object(C);
583  if (obedit && obedit->type == OB_SURF) {
584  return NULL != ((Curve *)obedit->data)->editnurb;
585  }
586  return false;
587 }
588 
590 {
591  Object *obedit = CTX_data_edit_object(C);
592  if (obedit && obedit->type == OB_FONT) {
593  return NULL != ((Curve *)obedit->data)->editfont;
594  }
595  return false;
596 }
597 
599 {
600  Object *obedit = CTX_data_edit_object(C);
601  if (obedit && obedit->type == OB_LATTICE) {
602  return NULL != ((Lattice *)obedit->data)->editlatt;
603  }
604  return false;
605 }
606 
608 {
609  Object *obedit = CTX_data_edit_object(C);
610  if (obedit && obedit->type == OB_MBALL) {
611  return NULL != ((MetaBall *)obedit->data)->editelems;
612  }
613  return false;
614 }
615 
617 {
619  if (area && area->spacedata.first) {
620  switch (area->spacetype) {
621  case SPACE_CLIP: {
622  SpaceClip *screen = area->spacedata.first;
623  return ED_space_clip_check_show_maskedit(screen);
624  }
625  case SPACE_SEQ: {
626  SpaceSeq *sseq = area->spacedata.first;
629  }
630  case SPACE_IMAGE: {
631  SpaceImage *sima = area->spacedata.first;
632  ViewLayer *view_layer = CTX_data_view_layer(C);
633  Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
634  return ED_space_image_check_show_maskedit(sima, obedit);
635  }
636  }
637  }
638 
639  return false;
640 }
641 
643 {
644  struct Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
645  return (cam != NULL);
646 }
647 
650 /* -------------------------------------------------------------------- */
655 {
657  /* no full window splitting allowed */
658  if (CTX_wm_screen(C)->state != SCREENNORMAL) {
659  return false;
660  }
661  return true;
662  }
663  return false;
664 }
665 
668 /* -------------------------------------------------------------------- */
672 /* operator state vars used:
673  * none
674  *
675  * functions:
676  *
677  * apply() set action-zone event
678  *
679  * exit() free customdata
680  *
681  * callbacks:
682  *
683  * exec() never used
684  *
685  * invoke() check if in zone
686  * add customdata, put mouseco and area in it
687  * add modal handler
688  *
689  * modal() accept modal events while doing it
690  * call apply() with gesture info, active window, nonactive window
691  * call exit() and remove handler when LMB confirm
692  */
693 
694 typedef struct sActionzoneData {
699 
700 /* quick poll to save operators to be created and handled */
702 {
703  wmWindow *win = CTX_wm_window(C);
704  bScreen *screen = WM_window_get_active_screen(win);
705 
706  if (screen && win && win->eventstate) {
707  const int *xy = &win->eventstate->x;
708 
709  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
710  LISTBASE_FOREACH (AZone *, az, &area->actionzones) {
711  if (BLI_rcti_isect_pt_v(&az->rect, xy)) {
712  return true;
713  }
714  }
715  }
716  }
717  return false;
718 }
719 
720 /* the debug drawing of the click_rect is in area_draw_azone_fullscreen, keep both in sync */
722  rcti *rect, const short UNUSED(x1), const short UNUSED(y1), const short x2, const short y2)
723 {
724  BLI_rcti_init(rect, x2 - U.widget_unit, x2, y2 - U.widget_unit, y2);
725 }
726 
727 static bool azone_clipped_rect_calc(const AZone *az, rcti *r_rect_clip)
728 {
729  const ARegion *region = az->region;
730  *r_rect_clip = az->rect;
731  if (az->type == AZONE_REGION) {
732  if (region->overlap && (region->v2d.keeptot != V2D_KEEPTOT_STRICT) &&
733  /* Only when this isn't hidden (where it's displayed as an button that expands). */
734  ((az->region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) == 0)) {
735  /* A floating region to be resized, clip by the visible region. */
736  switch (az->edge) {
738  case AE_BOTTOM_TO_TOPLEFT: {
739  r_rect_clip->xmin = max_ii(
740  r_rect_clip->xmin,
741  (region->winrct.xmin +
742  UI_view2d_view_to_region_x(&region->v2d, region->v2d.tot.xmin)) -
744  r_rect_clip->xmax = min_ii(
745  r_rect_clip->xmax,
746  (region->winrct.xmin +
747  UI_view2d_view_to_region_x(&region->v2d, region->v2d.tot.xmax)) +
749  return true;
750  }
751  case AE_LEFT_TO_TOPRIGHT:
752  case AE_RIGHT_TO_TOPLEFT: {
753  r_rect_clip->ymin = max_ii(
754  r_rect_clip->ymin,
755  (region->winrct.ymin +
756  UI_view2d_view_to_region_y(&region->v2d, region->v2d.tot.ymin)) -
758  r_rect_clip->ymax = min_ii(
759  r_rect_clip->ymax,
760  (region->winrct.ymin +
761  UI_view2d_view_to_region_y(&region->v2d, region->v2d.tot.ymax)) +
763  return true;
764  }
765  }
766  }
767  }
768  return false;
769 }
770 
771 static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const bool test_only)
772 {
773  AZone *az = NULL;
774 
775  for (az = area->actionzones.first; az; az = az->next) {
776  rcti az_rect_clip;
777  if (BLI_rcti_isect_pt_v(&az->rect, xy) &&
778  /* Check clipping if this is clipped */
779  (!azone_clipped_rect_calc(az, &az_rect_clip) || BLI_rcti_isect_pt_v(&az_rect_clip, xy))) {
780 
781  if (az->type == AZONE_AREA) {
782  break;
783  }
784  if (az->type == AZONE_REGION) {
785  break;
786  }
787  if (az->type == AZONE_FULLSCREEN) {
788  rcti click_rect;
789  fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2);
790  const bool click_isect = BLI_rcti_isect_pt_v(&click_rect, xy);
791 
792  if (test_only) {
793  if (click_isect) {
794  break;
795  }
796  }
797  else {
798  if (click_isect) {
799  az->alpha = 1.0f;
800  }
801  else {
802  const int mouse_sq = square_i(xy[0] - az->x2) + square_i(xy[1] - az->y2);
803  const int spot_sq = square_i(AZONESPOTW);
804  const int fadein_sq = square_i(AZONEFADEIN);
805  const int fadeout_sq = square_i(AZONEFADEOUT);
806 
807  if (mouse_sq < spot_sq) {
808  az->alpha = 1.0f;
809  }
810  else if (mouse_sq < fadein_sq) {
811  az->alpha = 1.0f;
812  }
813  else if (mouse_sq < fadeout_sq) {
814  az->alpha = 1.0f -
815  ((float)(mouse_sq - fadein_sq)) / ((float)(fadeout_sq - fadein_sq));
816  }
817  else {
818  az->alpha = 0.0f;
819  }
820 
821  /* fade in/out but no click */
822  az = NULL;
823  }
824 
825  /* XXX force redraw to show/hide the action zone */
827  break;
828  }
829  }
830  else if (az->type == AZONE_REGION_SCROLL) {
831  ARegion *region = az->region;
832  View2D *v2d = &region->v2d;
833  int scroll_flag = 0;
834  const int isect_value = UI_view2d_mouse_in_scrollers_ex(
835  region, v2d, xy[0], xy[1], &scroll_flag);
836 
837  /* Check if we even have scroll bars. */
838  if (((az->direction == AZ_SCROLL_HOR) && !(scroll_flag & V2D_SCROLL_HORIZONTAL)) ||
839  ((az->direction == AZ_SCROLL_VERT) && !(scroll_flag & V2D_SCROLL_VERTICAL))) {
840  /* no scrollbars, do nothing. */
841  }
842  else if (test_only) {
843  if (isect_value != 0) {
844  break;
845  }
846  }
847  else {
848  bool redraw = false;
849 
850  if (isect_value == 'h') {
851  if (az->direction == AZ_SCROLL_HOR) {
852  az->alpha = 1.0f;
853  v2d->alpha_hor = 255;
854  redraw = true;
855  }
856  }
857  else if (isect_value == 'v') {
858  if (az->direction == AZ_SCROLL_VERT) {
859  az->alpha = 1.0f;
860  v2d->alpha_vert = 255;
861  redraw = true;
862  }
863  }
864  else {
865  const int local_xy[2] = {xy[0] - region->winrct.xmin, xy[1] - region->winrct.ymin};
866  float dist_fac = 0.0f, alpha = 0.0f;
867 
868  if (az->direction == AZ_SCROLL_HOR) {
869  dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN;
870  CLAMP(dist_fac, 0.0f, 1.0f);
871  alpha = 1.0f - dist_fac;
872 
873  v2d->alpha_hor = alpha * 255;
874  }
875  else if (az->direction == AZ_SCROLL_VERT) {
876  dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN;
877  CLAMP(dist_fac, 0.0f, 1.0f);
878  alpha = 1.0f - dist_fac;
879 
880  v2d->alpha_vert = alpha * 255;
881  }
882  az->alpha = alpha;
883  redraw = true;
884  }
885 
886  if (redraw) {
888  }
889  /* Don't return! */
890  }
891  }
892  }
893  else if (!test_only && !IS_EQF(az->alpha, 0.0f)) {
894  if (az->type == AZONE_FULLSCREEN) {
895  az->alpha = 0.0f;
898  }
899  else if (az->type == AZONE_REGION_SCROLL) {
900  if (az->direction == AZ_SCROLL_VERT) {
901  az->alpha = az->region->v2d.alpha_vert = 0;
904  }
905  else if (az->direction == AZ_SCROLL_HOR) {
906  az->alpha = az->region->v2d.alpha_hor = 0;
909  }
910  else {
911  BLI_assert(false);
912  }
913  }
914  }
915  }
916 
917  return az;
918 }
919 
920 /* Finds an action-zone by position in entire screen so azones can overlap. */
921 static AZone *screen_actionzone_find_xy(bScreen *screen, const int xy[2])
922 {
923  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
924  AZone *az = area_actionzone_refresh_xy(area, xy, true);
925  if (az != NULL) {
926  return az;
927  }
928  }
929  return NULL;
930 }
931 
932 /* Returns the area that the azone belongs to */
933 static ScrArea *screen_actionzone_area(bScreen *screen, const AZone *az)
934 {
935  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
936  LISTBASE_FOREACH (AZone *, zone, &area->actionzones) {
937  if (zone == az) {
938  return area;
939  }
940  }
941  }
942  return NULL;
943 }
944 
946 {
947  return area_actionzone_refresh_xy(area, xy, true);
948 }
949 
951 {
952  return area_actionzone_refresh_xy(area, xy, false);
953 }
954 
955 static void actionzone_exit(wmOperator *op)
956 {
957  if (op->customdata) {
958  MEM_freeN(op->customdata);
959  }
960  op->customdata = NULL;
961 
962  G.moving &= ~G_TRANSFORM_WM;
963 }
964 
965 /* send EVT_ACTIONZONE event */
966 static void actionzone_apply(bContext *C, wmOperator *op, int type)
967 {
968  wmWindow *win = CTX_wm_window(C);
969  sActionzoneData *sad = op->customdata;
970 
971  sad->modifier = RNA_int_get(op->ptr, "modifier");
972 
973  wmEvent event;
974  wm_event_init_from_window(win, &event);
975 
976  if (type == AZONE_AREA) {
977  event.type = EVT_ACTIONZONE_AREA;
978  }
979  else if (type == AZONE_FULLSCREEN) {
980  event.type = EVT_ACTIONZONE_FULLSCREEN;
981  }
982  else {
983  event.type = EVT_ACTIONZONE_REGION;
984  }
985 
986  event.val = KM_NOTHING;
987  event.is_repeat = false;
988  event.customdata = op->customdata;
989  event.customdatafree = true;
990  op->customdata = NULL;
991 
992  wm_event_add(win, &event);
993 }
994 
995 static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
996 {
997  bScreen *screen = CTX_wm_screen(C);
998  AZone *az = screen_actionzone_find_xy(screen, &event->x);
999 
1000  /* Quick escape - Scroll azones only hide/unhide the scroll-bars,
1001  * they have their own handling. */
1002  if (az == NULL || ELEM(az->type, AZONE_REGION_SCROLL)) {
1003  return OPERATOR_PASS_THROUGH;
1004  }
1005 
1006  /* ok we do the action-zone */
1007  sActionzoneData *sad = op->customdata = MEM_callocN(sizeof(sActionzoneData), "sActionzoneData");
1008  sad->sa1 = screen_actionzone_area(screen, az);
1009  sad->az = az;
1010  sad->x = event->x;
1011  sad->y = event->y;
1012 
1013  /* region azone directly reacts on mouse clicks */
1014  if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) {
1015  actionzone_apply(C, op, sad->az->type);
1016  actionzone_exit(op);
1017  return OPERATOR_FINISHED;
1018  }
1019 
1021 
1022  /* add modal handler */
1023  G.moving |= G_TRANSFORM_WM;
1025  return OPERATOR_RUNNING_MODAL;
1026 }
1027 
1028 static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
1029 {
1030  bScreen *screen = CTX_wm_screen(C);
1031  sActionzoneData *sad = op->customdata;
1032 
1033  switch (event->type) {
1034  case MOUSEMOVE: {
1035  const int delta_x = (event->x - sad->x);
1036  const int delta_y = (event->y - sad->y);
1037 
1038  /* Movement in dominant direction. */
1039  const int delta_max = max_ii(abs(delta_x), abs(delta_y));
1040 
1041  /* Movement in dominant direction before action taken. */
1042  const int join_threshold = (0.6 * U.widget_unit);
1043  const int split_threshold = (1.2 * U.widget_unit);
1044  const int area_threshold = (0.1 * U.widget_unit);
1045 
1046  /* Calculate gesture cardinal direction. */
1047  if (delta_y > abs(delta_x)) {
1048  sad->gesture_dir = 'n';
1049  }
1050  else if (delta_x >= abs(delta_y)) {
1051  sad->gesture_dir = 'e';
1052  }
1053  else if (delta_y < -abs(delta_x)) {
1054  sad->gesture_dir = 's';
1055  }
1056  else {
1057  sad->gesture_dir = 'w';
1058  }
1059 
1060  bool is_gesture;
1061  if (sad->az->type == AZONE_AREA) {
1062  wmWindow *win = CTX_wm_window(C);
1063 
1064  rcti screen_rect;
1065  WM_window_screen_rect_calc(win, &screen_rect);
1066 
1067  /* Have we dragged off the zone and are not on an edge? */
1068  if ((ED_area_actionzone_find_xy(sad->sa1, &event->x) != sad->az) &&
1070  AREAMAP_FROM_SCREEN(screen), &screen_rect, event->x, event->y) == NULL)) {
1071  /* Are we still in same area? */
1072  if (BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y) == sad->sa1) {
1073  /* Same area, so possible split. */
1074  WM_cursor_set(
1075  win, (ELEM(sad->gesture_dir, 'n', 's')) ? WM_CURSOR_H_SPLIT : WM_CURSOR_V_SPLIT);
1076  is_gesture = (delta_max > split_threshold);
1077  }
1078  else {
1079  /* Different area, so possible join. */
1080  if (sad->gesture_dir == 'n') {
1082  }
1083  else if (sad->gesture_dir == 's') {
1085  }
1086  else if (sad->gesture_dir == 'e') {
1088  }
1089  else {
1091  }
1092  is_gesture = (delta_max > join_threshold);
1093  }
1094  }
1095  else {
1097  is_gesture = false;
1098  }
1099  }
1100  else {
1101  is_gesture = (delta_max > area_threshold);
1102  }
1103 
1104  /* gesture is large enough? */
1105  if (is_gesture) {
1106  /* second area, for join when (sa1 != sa2) */
1107  sad->sa2 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y);
1108  /* apply sends event */
1109  actionzone_apply(C, op, sad->az->type);
1110  actionzone_exit(op);
1111 
1112  return OPERATOR_FINISHED;
1113  }
1114  break;
1115  }
1116  case EVT_ESCKEY:
1117  actionzone_exit(op);
1118  return OPERATOR_CANCELLED;
1119  case LEFTMOUSE:
1120  actionzone_exit(op);
1121  return OPERATOR_CANCELLED;
1122  }
1123 
1124  return OPERATOR_RUNNING_MODAL;
1125 }
1126 
1128 {
1129  actionzone_exit(op);
1130 }
1131 
1133 {
1134  /* identifiers */
1135  ot->name = "Handle Area Action Zones";
1136  ot->description = "Handle area action zones for mouse actions/gestures";
1137  ot->idname = "SCREEN_OT_actionzone";
1138 
1143 
1144  /* flags */
1146 
1147  RNA_def_int(ot->srna, "modifier", 0, 0, 2, "Modifier", "Modifier state", 0, 2);
1148 }
1149 
1152 /* -------------------------------------------------------------------- */
1157  const int cursor[2],
1158  ScrArea **r_sa1,
1159  ScrArea **r_sa2)
1160 {
1161  wmWindow *win = CTX_wm_window(C);
1162  bScreen *screen = CTX_wm_screen(C);
1163  rcti window_rect;
1164  WM_window_rect_calc(win, &window_rect);
1166  AREAMAP_FROM_SCREEN(screen), &window_rect, cursor[0], cursor[1]);
1167  *r_sa1 = NULL;
1168  *r_sa2 = NULL;
1169  if (actedge == NULL) {
1170  return NULL;
1171  }
1172  int borderwidth = (4 * UI_DPI_FAC);
1173  ScrArea *sa1, *sa2;
1174  if (screen_geom_edge_is_horizontal(actedge)) {
1175  sa1 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, cursor[0], cursor[1] + borderwidth);
1176  sa2 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, cursor[0], cursor[1] - borderwidth);
1177  }
1178  else {
1179  sa1 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, cursor[0] + borderwidth, cursor[1]);
1180  sa2 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, cursor[0] - borderwidth, cursor[1]);
1181  }
1182  bool isGlobal = ((sa1 && ED_area_is_global(sa1)) || (sa2 && ED_area_is_global(sa2)));
1183  if (!isGlobal) {
1184  *r_sa1 = sa1;
1185  *r_sa2 = sa2;
1186  }
1187  return actedge;
1188 }
1189 
1192 /* -------------------------------------------------------------------- */
1196 /* operator state vars used:
1197  * sa1 start area
1198  * sa2 area to swap with
1199  *
1200  * functions:
1201  *
1202  * init() set custom data for operator, based on action-zone event custom data
1203  *
1204  * cancel() cancel the operator
1205  *
1206  * exit() cleanup, send notifier
1207  *
1208  * callbacks:
1209  *
1210  * invoke() gets called on shift+lmb drag in action-zone
1211  * exec() execute without any user interaction, based on properties
1212  * call init(), add handler
1213  *
1214  * modal() accept modal events while doing it
1215  */
1216 
1217 typedef struct sAreaSwapData {
1220 
1221 static bool area_swap_init(wmOperator *op, const wmEvent *event)
1222 {
1223  sActionzoneData *sad = event->customdata;
1224 
1225  if (sad == NULL || sad->sa1 == NULL) {
1226  return false;
1227  }
1228 
1229  sAreaSwapData *sd = MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData");
1230  sd->sa1 = sad->sa1;
1231  sd->sa2 = sad->sa2;
1232  op->customdata = sd;
1233 
1234  return true;
1235 }
1236 
1238 {
1240  if (op->customdata) {
1241  MEM_freeN(op->customdata);
1242  }
1243  op->customdata = NULL;
1244 }
1245 
1247 {
1248  area_swap_exit(C, op);
1249 }
1250 
1251 static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1252 {
1253  if (!area_swap_init(op, event)) {
1254  return OPERATOR_PASS_THROUGH;
1255  }
1256 
1257  /* add modal handler */
1260 
1261  return OPERATOR_RUNNING_MODAL;
1262 }
1263 
1264 static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
1265 {
1266  sActionzoneData *sad = op->customdata;
1267 
1268  switch (event->type) {
1269  case MOUSEMOVE:
1270  /* second area, for join */
1271  sad->sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y);
1272  break;
1273  case LEFTMOUSE: /* release LMB */
1274  if (event->val == KM_RELEASE) {
1275  if (!sad->sa2 || sad->sa1 == sad->sa2) {
1276  area_swap_cancel(C, op);
1277  return OPERATOR_CANCELLED;
1278  }
1279 
1280  ED_area_tag_redraw(sad->sa1);
1281  ED_area_tag_redraw(sad->sa2);
1282 
1283  ED_area_swapspace(C, sad->sa1, sad->sa2);
1284 
1285  area_swap_exit(C, op);
1286 
1288 
1289  return OPERATOR_FINISHED;
1290  }
1291  break;
1292 
1293  case EVT_ESCKEY:
1294  area_swap_cancel(C, op);
1295  return OPERATOR_CANCELLED;
1296  }
1297  return OPERATOR_RUNNING_MODAL;
1298 }
1299 
1301 {
1302  ScrArea *sa1, *sa2;
1303  int cursor[2];
1304  RNA_int_get_array(op->ptr, "cursor", cursor);
1305  screen_area_edge_from_cursor(C, cursor, &sa1, &sa2);
1306  if (sa1 == NULL || sa2 == NULL) {
1307  return OPERATOR_CANCELLED;
1308  }
1309  ED_area_swapspace(C, sa1, sa2);
1310  return OPERATOR_FINISHED;
1311 }
1312 
1314 {
1315  ot->name = "Swap Areas";
1316  ot->description = "Swap selected areas screen positions";
1317  ot->idname = "SCREEN_OT_area_swap";
1318 
1321  ot->exec = area_swap_exec;
1324 
1325  ot->flag = OPTYPE_BLOCKING;
1326 
1327  /* rna */
1329  ot->srna, "cursor", 2, NULL, INT_MIN, INT_MAX, "Cursor", "", INT_MIN, INT_MAX);
1330 }
1331 
1334 /* -------------------------------------------------------------------- */
1340 /* operator callback */
1341 static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1342 {
1343  ScrArea *area = CTX_wm_area(C);
1344 
1345  if (event && event->customdata) {
1346  sActionzoneData *sad = event->customdata;
1347  if (sad == NULL) {
1348  return OPERATOR_PASS_THROUGH;
1349  }
1350  area = sad->sa1;
1351  }
1352 
1353  /* Create new window. No need to set space_type since it will be copied over. */
1354  wmWindow *newwin = WM_window_open(C,
1355  "Blender",
1356  area->totrct.xmin,
1357  area->totrct.ymin,
1358  area->winx,
1359  area->winy,
1360  SPACE_EMPTY,
1361  true,
1362  false,
1364 
1365  if (newwin) {
1366  /* copy area to new screen */
1367  bScreen *newsc = WM_window_get_active_screen(newwin);
1368  ED_area_data_copy((ScrArea *)newsc->areabase.first, area, true);
1370 
1371  /* screen, areas init */
1373  }
1374  else {
1375  BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
1376  }
1377 
1378  if (event && event->customdata) {
1379  actionzone_exit(op);
1380  }
1381 
1382  return newwin ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1383 }
1384 
1386 {
1387  ot->name = "Duplicate Area into New Window";
1388  ot->description = "Duplicate selected area into new window";
1389  ot->idname = "SCREEN_OT_area_dupli";
1390 
1393 }
1394 
1397 /* -------------------------------------------------------------------- */
1401 /* operator state vars used:
1402  * x, y mouse coord near edge
1403  * delta movement of edge
1404  *
1405  * functions:
1406  *
1407  * init() set default property values, find edge based on mouse coords, test
1408  * if the edge can be moved, select edges, calculate min and max movement
1409  *
1410  * apply() apply delta on selection
1411  *
1412  * exit() cleanup, send notifier
1413  *
1414  * cancel() cancel moving
1415  *
1416  * callbacks:
1417  *
1418  * exec() execute without any user interaction, based on properties
1419  * call init(), apply(), exit()
1420  *
1421  * invoke() gets called on mouse click near edge
1422  * call init(), add handler
1423  *
1424  * modal() accept modal events while doing it
1425  * call apply() with delta motion
1426  * call exit() and remove handler
1427  */
1428 
1429 typedef struct sAreaMoveData {
1431  char dir;
1433  /* Snapping disabled */
1435  /* Snap to an invisible grid with a unit defined in AREAGRID */
1437  /* Snap to fraction (half, third.. etc) and adjacent edges. */
1439  /* Snap to either bigger or smaller, nothing in-between (used for
1440  * global areas). This has priority over other snap types, if it is
1441  * used, toggling SNAP_FRACTION_AND_ADJACENT doesn't work. */
1445 
1446 /* helper call to move area-edge, sets limits
1447  * need window bounds in order to get correct limits */
1449  bScreen *screen,
1450  int dir,
1451  int *bigger,
1452  int *smaller,
1453  bool *use_bigger_smaller_snap)
1454 {
1455  /* we check all areas and test for free space with MINSIZE */
1456  *bigger = *smaller = 100000;
1457 
1458  if (use_bigger_smaller_snap != NULL) {
1459  *use_bigger_smaller_snap = false;
1461  int size_min = ED_area_global_min_size_y(area) - 1;
1462  int size_max = ED_area_global_max_size_y(area) - 1;
1463 
1464  size_min = max_ii(size_min, 0);
1465  BLI_assert(size_min <= size_max);
1466 
1467  /* logic here is only tested for lower edge :) */
1468  /* left edge */
1469  if ((area->v1->editflag && area->v2->editflag)) {
1470  *smaller = area->v4->vec.x - size_max;
1471  *bigger = area->v4->vec.x - size_min;
1472  *use_bigger_smaller_snap = true;
1473  return;
1474  }
1475  /* top edge */
1476  if ((area->v2->editflag && area->v3->editflag)) {
1477  *smaller = area->v1->vec.y + size_min;
1478  *bigger = area->v1->vec.y + size_max;
1479  *use_bigger_smaller_snap = true;
1480  return;
1481  }
1482  /* right edge */
1483  if ((area->v3->editflag && area->v4->editflag)) {
1484  *smaller = area->v1->vec.x + size_min;
1485  *bigger = area->v1->vec.x + size_max;
1486  *use_bigger_smaller_snap = true;
1487  return;
1488  }
1489  /* lower edge */
1490  if ((area->v4->editflag && area->v1->editflag)) {
1491  *smaller = area->v2->vec.y - size_max;
1492  *bigger = area->v2->vec.y - size_min;
1493  *use_bigger_smaller_snap = true;
1494  return;
1495  }
1496  }
1497  }
1498 
1499  rcti window_rect;
1500  WM_window_rect_calc(win, &window_rect);
1501 
1502  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1503  if (dir == 'h') {
1504  int areamin = ED_area_headersize();
1505 
1506  if (area->v1->vec.y > window_rect.ymin) {
1507  areamin += U.pixelsize;
1508  }
1509  if (area->v2->vec.y < (window_rect.ymax - 1)) {
1510  areamin += U.pixelsize;
1511  }
1512 
1513  int y1 = screen_geom_area_height(area) - areamin;
1514 
1515  /* if top or down edge selected, test height */
1516  if (area->v1->editflag && area->v4->editflag) {
1517  *bigger = min_ii(*bigger, y1);
1518  }
1519  else if (area->v2->editflag && area->v3->editflag) {
1520  *smaller = min_ii(*smaller, y1);
1521  }
1522  }
1523  else {
1524  int areamin = AREAMINX;
1525 
1526  if (area->v1->vec.x > window_rect.xmin) {
1527  areamin += U.pixelsize;
1528  }
1529  if (area->v4->vec.x < (window_rect.xmax - 1)) {
1530  areamin += U.pixelsize;
1531  }
1532 
1533  int x1 = screen_geom_area_width(area) - areamin;
1534 
1535  /* if left or right edge selected, test width */
1536  if (area->v1->editflag && area->v2->editflag) {
1537  *bigger = min_ii(*bigger, x1);
1538  }
1539  else if (area->v3->editflag && area->v4->editflag) {
1540  *smaller = min_ii(*smaller, x1);
1541  }
1542  }
1543  }
1544 }
1545 
1546 /* validate selection inside screen, set variables OK */
1547 /* return false: init failed */
1549 {
1550  bScreen *screen = CTX_wm_screen(C);
1551  wmWindow *win = CTX_wm_window(C);
1552 
1553  /* required properties */
1554  int x = RNA_int_get(op->ptr, "x");
1555  int y = RNA_int_get(op->ptr, "y");
1556 
1557  /* setup */
1558  ScrEdge *actedge = screen_geom_find_active_scredge(win, screen, x, y);
1559  if (actedge == NULL) {
1560  return false;
1561  }
1562 
1563  sAreaMoveData *md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData");
1564  op->customdata = md;
1565 
1566  md->dir = screen_geom_edge_is_horizontal(actedge) ? 'h' : 'v';
1567  if (md->dir == 'h') {
1568  md->origval = actedge->v1->vec.y;
1569  }
1570  else {
1571  md->origval = actedge->v1->vec.x;
1572  }
1573 
1574  screen_geom_select_connected_edge(win, actedge);
1575  /* now all vertices with 'flag == 1' are the ones that can be moved. Move this to editflag */
1576  ED_screen_verts_iter(win, screen, v1)
1577  {
1578  v1->editflag = v1->flag;
1579  }
1580 
1581  bool use_bigger_smaller_snap = false;
1582  area_move_set_limits(win, screen, md->dir, &md->bigger, &md->smaller, &use_bigger_smaller_snap);
1583 
1584  md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_AREAGRID;
1585 
1586  return true;
1587 }
1588 
1589 static int area_snap_calc_location(const bScreen *screen,
1590  const enum AreaMoveSnapType snap_type,
1591  const int delta,
1592  const int origval,
1593  const int dir,
1594  const int bigger,
1595  const int smaller)
1596 {
1597  BLI_assert(snap_type != SNAP_NONE);
1598  int m_cursor_final = -1;
1599  const int m_cursor = origval + delta;
1600  const int m_span = (float)(bigger + smaller);
1601  const int m_min = origval - smaller;
1602  // const int axis_max = axis_min + m_span;
1603 
1604  switch (snap_type) {
1605  case SNAP_AREAGRID:
1606  m_cursor_final = m_cursor;
1607  if (!ELEM(delta, bigger, -smaller)) {
1608  m_cursor_final -= (m_cursor % AREAGRID);
1609  CLAMP(m_cursor_final, origval - smaller, origval + bigger);
1610  }
1611  break;
1612 
1613  case SNAP_BIGGER_SMALLER_ONLY:
1614  m_cursor_final = (m_cursor >= bigger) ? bigger : smaller;
1615  break;
1616 
1617  case SNAP_FRACTION_AND_ADJACENT: {
1618  const int axis = (dir == 'v') ? 0 : 1;
1619  int snap_dist_best = INT_MAX;
1620  {
1621  const float div_array[] = {
1622  /* Middle. */
1623  1.0f / 2.0f,
1624  /* Thirds. */
1625  1.0f / 3.0f,
1626  2.0f / 3.0f,
1627  /* Quarters. */
1628  1.0f / 4.0f,
1629  3.0f / 4.0f,
1630  /* Eighth. */
1631  1.0f / 8.0f,
1632  3.0f / 8.0f,
1633  5.0f / 8.0f,
1634  7.0f / 8.0f,
1635  };
1636  /* Test the snap to the best division. */
1637  for (int i = 0; i < ARRAY_SIZE(div_array); i++) {
1638  const int m_cursor_test = m_min + round_fl_to_int(m_span * div_array[i]);
1639  const int snap_dist_test = abs(m_cursor - m_cursor_test);
1640  if (snap_dist_best >= snap_dist_test) {
1641  snap_dist_best = snap_dist_test;
1642  m_cursor_final = m_cursor_test;
1643  }
1644  }
1645  }
1646 
1647  LISTBASE_FOREACH (const ScrVert *, v1, &screen->vertbase) {
1648  if (!v1->editflag) {
1649  continue;
1650  }
1651  const int v_loc = (&v1->vec.x)[!axis];
1652 
1653  LISTBASE_FOREACH (const ScrVert *, v2, &screen->vertbase) {
1654  if (v2->editflag) {
1655  continue;
1656  }
1657  if (v_loc == (&v2->vec.x)[!axis]) {
1658  const int v_loc2 = (&v2->vec.x)[axis];
1659  /* Do not snap to the vertices at the ends. */
1660  if ((origval - smaller) < v_loc2 && v_loc2 < (origval + bigger)) {
1661  const int snap_dist_test = abs(m_cursor - v_loc2);
1662  if (snap_dist_best >= snap_dist_test) {
1663  snap_dist_best = snap_dist_test;
1664  m_cursor_final = v_loc2;
1665  }
1666  }
1667  }
1668  }
1669  }
1670  break;
1671  }
1672  case SNAP_NONE:
1673  break;
1674  }
1675 
1676  BLI_assert(ELEM(snap_type, SNAP_BIGGER_SMALLER_ONLY) ||
1677  IN_RANGE_INCL(m_cursor_final, origval - smaller, origval + bigger));
1678 
1679  return m_cursor_final;
1680 }
1681 
1682 /* moves selected screen edge amount of delta, used by split & move */
1683 static void area_move_apply_do(const bContext *C,
1684  int delta,
1685  const int origval,
1686  const int dir,
1687  const int bigger,
1688  const int smaller,
1689  const enum AreaMoveSnapType snap_type)
1690 {
1691  wmWindow *win = CTX_wm_window(C);
1692  bScreen *screen = CTX_wm_screen(C);
1693  short final_loc = -1;
1694  bool doredraw = false;
1695 
1696  if (snap_type != SNAP_BIGGER_SMALLER_ONLY) {
1697  CLAMP(delta, -smaller, bigger);
1698  }
1699 
1700  if (snap_type == SNAP_NONE) {
1701  final_loc = origval + delta;
1702  }
1703  else {
1704  final_loc = area_snap_calc_location(screen, snap_type, delta, origval, dir, bigger, smaller);
1705  }
1706 
1707  BLI_assert(final_loc != -1);
1708  short axis = (dir == 'v') ? 0 : 1;
1709 
1710  ED_screen_verts_iter(win, screen, v1)
1711  {
1712  if (v1->editflag) {
1713  short oldval = (&v1->vec.x)[axis];
1714  (&v1->vec.x)[axis] = final_loc;
1715 
1716  if (oldval == final_loc) {
1717  /* nothing will change to the other vertices either. */
1718  break;
1719  }
1720  doredraw = true;
1721  }
1722  }
1723 
1724  /* only redraw if we actually moved a screen vert, for AREAGRID */
1725  if (doredraw) {
1726  bool redraw_all = false;
1727  ED_screen_areas_iter (win, screen, area) {
1728  if (area->v1->editflag || area->v2->editflag || area->v3->editflag || area->v4->editflag) {
1729  if (ED_area_is_global(area)) {
1730  /* Snap to minimum or maximum for global areas. */
1732  if (abs(height - area->global->size_min) < abs(height - area->global->size_max)) {
1733  area->global->cur_fixed_height = area->global->size_min;
1734  }
1735  else {
1736  area->global->cur_fixed_height = area->global->size_max;
1737  }
1738 
1739  screen->do_refresh = true;
1740  redraw_all = true;
1741  }
1743  }
1744  }
1745  if (redraw_all) {
1746  ED_screen_areas_iter (win, screen, area) {
1748  }
1749  }
1750 
1752 
1753  WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */
1754  /* Update preview thumbnail */
1755  BKE_icon_changed(screen->id.icon_id);
1756  }
1757 }
1758 
1760 {
1761  sAreaMoveData *md = op->customdata;
1762  int delta = RNA_int_get(op->ptr, "delta");
1763 
1764  area_move_apply_do(C, delta, md->origval, md->dir, md->bigger, md->smaller, md->snap_type);
1765 }
1766 
1768 {
1769  if (op->customdata) {
1770  MEM_freeN(op->customdata);
1771  }
1772  op->customdata = NULL;
1773 
1774  /* this makes sure aligned edges will result in aligned grabbing */
1777 
1778  G.moving &= ~G_TRANSFORM_WM;
1779 }
1780 
1782 {
1783  if (!area_move_init(C, op)) {
1784  return OPERATOR_CANCELLED;
1785  }
1786 
1787  area_move_apply(C, op);
1788  area_move_exit(C, op);
1789 
1790  return OPERATOR_FINISHED;
1791 }
1792 
1793 /* interaction callback */
1794 static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1795 {
1796  RNA_int_set(op->ptr, "x", event->x);
1797  RNA_int_set(op->ptr, "y", event->y);
1798 
1799  if (!area_move_init(C, op)) {
1800  return OPERATOR_PASS_THROUGH;
1801  }
1802 
1803  /* add temp handler */
1804  G.moving |= G_TRANSFORM_WM;
1806 
1807  return OPERATOR_RUNNING_MODAL;
1808 }
1809 
1811 {
1812 
1813  RNA_int_set(op->ptr, "delta", 0);
1814  area_move_apply(C, op);
1815  area_move_exit(C, op);
1816 }
1817 
1818 /* modal callback for while moving edges */
1819 static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
1820 {
1821  sAreaMoveData *md = op->customdata;
1822 
1823  /* execute the events */
1824  switch (event->type) {
1825  case MOUSEMOVE: {
1826  int x = RNA_int_get(op->ptr, "x");
1827  int y = RNA_int_get(op->ptr, "y");
1828 
1829  int delta = (md->dir == 'v') ? event->x - x : event->y - y;
1830  RNA_int_set(op->ptr, "delta", delta);
1831 
1832  area_move_apply(C, op);
1833  break;
1834  }
1835  case EVT_MODAL_MAP: {
1836  switch (event->val) {
1837  case KM_MODAL_APPLY:
1838  area_move_exit(C, op);
1839  return OPERATOR_FINISHED;
1840 
1841  case KM_MODAL_CANCEL:
1842  area_move_cancel(C, op);
1843  return OPERATOR_CANCELLED;
1844 
1845  case KM_MODAL_SNAP_ON:
1846  if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) {
1847  md->snap_type = SNAP_FRACTION_AND_ADJACENT;
1848  }
1849  break;
1850 
1851  case KM_MODAL_SNAP_OFF:
1852  if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) {
1853  md->snap_type = SNAP_AREAGRID;
1854  }
1855  break;
1856  }
1857  break;
1858  }
1859  }
1860 
1861  return OPERATOR_RUNNING_MODAL;
1862 }
1863 
1865 {
1866  /* identifiers */
1867  ot->name = "Move Area Edges";
1868  ot->description = "Move selected area edges";
1869  ot->idname = "SCREEN_OT_area_move";
1870 
1871  ot->exec = area_move_exec;
1875  ot->poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */
1876 
1877  /* flags */
1879 
1880  /* rna */
1881  RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
1882  RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
1883  RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
1884 }
1885 
1888 /* -------------------------------------------------------------------- */
1892 /*
1893  * operator state vars:
1894  * fac spit point
1895  * dir direction 'v' or 'h'
1896  *
1897  * operator customdata:
1898  * area pointer to (active) area
1899  * x, y last used mouse pos
1900  * (more, see below)
1901  *
1902  * functions:
1903  *
1904  * init() set default property values, find area based on context
1905  *
1906  * apply() split area based on state vars
1907  *
1908  * exit() cleanup, send notifier
1909  *
1910  * cancel() remove duplicated area
1911  *
1912  * callbacks:
1913  *
1914  * exec() execute without any user interaction, based on state vars
1915  * call init(), apply(), exit()
1916  *
1917  * invoke() gets called on mouse click in action-widget
1918  * call init(), add modal handler
1919  * call apply() with initial motion
1920  *
1921  * modal() accept modal events while doing it
1922  * call move-areas code with delta motion
1923  * call exit() or cancel() and remove handler
1924  */
1925 
1926 typedef struct sAreaSplitData {
1927  int origval; /* for move areas */
1928  int bigger, smaller; /* constraints for moving new edge */
1929  int delta; /* delta move edge */
1930  int origmin, origsize; /* to calculate fac, for property storage */
1931  int previewmode; /* draw previewline, then split */
1932  void *draw_callback; /* call `ED_screen_draw_split_preview` */
1933  bool do_snap;
1934 
1935  ScrEdge *nedge; /* new edge */
1936  ScrArea *sarea; /* start area */
1937  ScrArea *narea; /* new area */
1938 
1940 
1941 static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdata)
1942 {
1943  const wmOperator *op = userdata;
1944 
1945  sAreaSplitData *sd = op->customdata;
1946  if (sd->sarea) {
1947  int dir = RNA_enum_get(op->ptr, "direction");
1948  float fac = RNA_float_get(op->ptr, "factor");
1949 
1950  ED_screen_draw_split_preview(sd->sarea, dir, fac);
1951  }
1952 }
1953 
1954 /* generic init, menu case, doesn't need active area */
1956 {
1957  /* custom data */
1958  sAreaSplitData *sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split");
1959  op->customdata = sd;
1960 
1961  sd->sarea = CTX_wm_area(C);
1962 
1963  return true;
1964 }
1965 
1966 /* generic init, no UI stuff here, assumes active area */
1968 {
1969  ScrArea *area = CTX_wm_area(C);
1970 
1971  /* required context */
1972  if (area == NULL) {
1973  return false;
1974  }
1975 
1976  /* required properties */
1977  int dir = RNA_enum_get(op->ptr, "direction");
1978 
1979  /* minimal size */
1980  if (dir == 'v' && area->winx < 2 * AREAMINX) {
1981  return false;
1982  }
1983  if (dir == 'h' && area->winy < 2 * ED_area_headersize()) {
1984  return false;
1985  }
1986 
1987  /* custom data */
1988  sAreaSplitData *sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split");
1989  op->customdata = sd;
1990 
1991  sd->sarea = area;
1992  if (dir == 'v') {
1993  sd->origmin = area->v1->vec.x;
1994  sd->origsize = area->v4->vec.x - sd->origmin;
1995  }
1996  else {
1997  sd->origmin = area->v1->vec.y;
1998  sd->origsize = area->v2->vec.y - sd->origmin;
1999  }
2000 
2001  return true;
2002 }
2003 
2004 /* with area as center, sb is located at: 0=W, 1=N, 2=E, 3=S */
2005 /* used with split operator */
2007 {
2008  ScrVert *sav1 = area->v1;
2009  ScrVert *sav2 = area->v2;
2010  ScrVert *sav3 = area->v3;
2011  ScrVert *sav4 = area->v4;
2012  ScrVert *sbv1 = sb->v1;
2013  ScrVert *sbv2 = sb->v2;
2014  ScrVert *sbv3 = sb->v3;
2015  ScrVert *sbv4 = sb->v4;
2016 
2017  if (sav1 == sbv4 && sav2 == sbv3) { /* area to right of sb = W */
2018  return BKE_screen_find_edge(screen, sav1, sav2);
2019  }
2020  if (sav2 == sbv1 && sav3 == sbv4) { /* area to bottom of sb = N */
2021  return BKE_screen_find_edge(screen, sav2, sav3);
2022  }
2023  if (sav3 == sbv2 && sav4 == sbv1) { /* area to left of sb = E */
2024  return BKE_screen_find_edge(screen, sav3, sav4);
2025  }
2026  if (sav1 == sbv2 && sav4 == sbv3) { /* area on top of sb = S*/
2027  return BKE_screen_find_edge(screen, sav1, sav4);
2028  }
2029 
2030  return NULL;
2031 }
2032 
2033 /* do the split, return success */
2035 {
2036  const wmWindow *win = CTX_wm_window(C);
2037  bScreen *screen = CTX_wm_screen(C);
2039 
2040  float fac = RNA_float_get(op->ptr, "factor");
2041  int dir = RNA_enum_get(op->ptr, "direction");
2042 
2043  sd->narea = area_split(win, screen, sd->sarea, dir, fac, 0); /* 0 = no merge */
2044 
2045  if (sd->narea == NULL) {
2046  return false;
2047  }
2048 
2049  sd->nedge = area_findsharededge(screen, sd->sarea, sd->narea);
2050 
2051  /* select newly created edge, prepare for moving edge */
2052  ED_screen_verts_iter(win, screen, sv)
2053  {
2054  sv->editflag = 0;
2055  }
2056 
2057  sd->nedge->v1->editflag = 1;
2058  sd->nedge->v2->editflag = 1;
2059 
2060  if (dir == 'h') {
2061  sd->origval = sd->nedge->v1->vec.y;
2062  }
2063  else {
2064  sd->origval = sd->nedge->v1->vec.x;
2065  }
2066 
2069 
2071  /* Update preview thumbnail */
2072  BKE_icon_changed(screen->id.icon_id);
2073 
2074  return true;
2075 }
2076 
2078 {
2079  if (op->customdata) {
2081  if (sd->sarea) {
2083  }
2084  if (sd->narea) {
2086  }
2087 
2088  if (sd->draw_callback) {
2090  }
2091 
2092  MEM_freeN(op->customdata);
2093  op->customdata = NULL;
2094  }
2095 
2098 
2099  /* this makes sure aligned edges will result in aligned grabbing */
2102 
2103  G.moving &= ~G_TRANSFORM_WM;
2104 }
2105 
2107 {
2108  wmWindow *win = CTX_wm_window(C);
2109  int dir = RNA_enum_get(op->ptr, "direction");
2110  WM_cursor_set(win, dir == 'h' ? WM_CURSOR_H_SPLIT : WM_CURSOR_V_SPLIT);
2111 }
2112 
2113 /* UI callback, adds new handler */
2114 static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
2115 {
2116  wmWindow *win = CTX_wm_window(C);
2117  bScreen *screen = CTX_wm_screen(C);
2118 
2119  /* no full window splitting allowed */
2120  BLI_assert(screen->state == SCREENNORMAL);
2121 
2122  PropertyRNA *prop_dir = RNA_struct_find_property(op->ptr, "direction");
2123  PropertyRNA *prop_factor = RNA_struct_find_property(op->ptr, "factor");
2124  PropertyRNA *prop_cursor = RNA_struct_find_property(op->ptr, "cursor");
2125 
2126  int dir;
2127  if (event->type == EVT_ACTIONZONE_AREA) {
2128  sActionzoneData *sad = event->customdata;
2129 
2130  if (sad == NULL || sad->modifier > 0) {
2131  return OPERATOR_PASS_THROUGH;
2132  }
2133 
2134  /* verify *sad itself */
2135  if (sad->sa1 == NULL || sad->az == NULL) {
2136  return OPERATOR_PASS_THROUGH;
2137  }
2138 
2139  /* is this our *sad? if areas not equal it should be passed on */
2140  if (CTX_wm_area(C) != sad->sa1 || sad->sa1 != sad->sa2) {
2141  return OPERATOR_PASS_THROUGH;
2142  }
2143 
2144  /* The factor will be close to 1.0f when near the top-left and the bottom-right corners. */
2145  const float factor_v = ((float)(event->y - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy;
2146  const float factor_h = ((float)(event->x - sad->sa1->v1->vec.x)) / (float)sad->sa1->winx;
2147  const bool is_left = factor_v < 0.5f;
2148  const bool is_bottom = factor_h < 0.5f;
2149  const bool is_right = !is_left;
2150  const bool is_top = !is_bottom;
2151  float factor;
2152 
2153  /* Prepare operator state vars. */
2154  if (ELEM(sad->gesture_dir, 'n', 's')) {
2155  dir = 'h';
2156  factor = factor_h;
2157  }
2158  else {
2159  dir = 'v';
2160  factor = factor_v;
2161  }
2162 
2163  if ((is_top && is_left) || (is_bottom && is_right)) {
2164  factor = 1.0f - factor;
2165  }
2166 
2167  RNA_property_float_set(op->ptr, prop_factor, factor);
2168 
2169  RNA_property_enum_set(op->ptr, prop_dir, dir);
2170 
2171  /* general init, also non-UI case, adds customdata, sets area and defaults */
2172  if (!area_split_init(C, op)) {
2173  return OPERATOR_PASS_THROUGH;
2174  }
2175  }
2176  else if (RNA_property_is_set(op->ptr, prop_dir)) {
2177  ScrArea *area = CTX_wm_area(C);
2178  if (area == NULL) {
2179  return OPERATOR_CANCELLED;
2180  }
2181  dir = RNA_property_enum_get(op->ptr, prop_dir);
2182  if (dir == 'h') {
2184  op->ptr, prop_factor, ((float)(event->x - area->v1->vec.x)) / (float)area->winx);
2185  }
2186  else {
2188  op->ptr, prop_factor, ((float)(event->y - area->v1->vec.y)) / (float)area->winy);
2189  }
2190 
2191  if (!area_split_init(C, op)) {
2192  return OPERATOR_CANCELLED;
2193  }
2194  }
2195  else {
2196  int event_co[2];
2197 
2198  /* retrieve initial mouse coord, so we can find the active edge */
2199  if (RNA_property_is_set(op->ptr, prop_cursor)) {
2200  RNA_property_int_get_array(op->ptr, prop_cursor, event_co);
2201  }
2202  else {
2203  copy_v2_v2_int(event_co, &event->x);
2204  }
2205 
2206  rcti window_rect;
2207  WM_window_rect_calc(win, &window_rect);
2208 
2210  AREAMAP_FROM_SCREEN(screen), &window_rect, event_co[0], event_co[1]);
2211  if (actedge == NULL) {
2212  return OPERATOR_CANCELLED;
2213  }
2214 
2215  dir = screen_geom_edge_is_horizontal(actedge) ? 'v' : 'h';
2216 
2217  RNA_property_enum_set(op->ptr, prop_dir, dir);
2218 
2219  /* special case, adds customdata, sets defaults */
2220  if (!area_split_menu_init(C, op)) {
2221  return OPERATOR_CANCELLED;
2222  }
2223  }
2224 
2226 
2227  if (event->type == EVT_ACTIONZONE_AREA) {
2228  /* do the split */
2229  if (area_split_apply(C, op)) {
2230  area_move_set_limits(win, screen, dir, &sd->bigger, &sd->smaller, NULL);
2231 
2232  /* add temp handler for edge move or cancel */
2233  G.moving |= G_TRANSFORM_WM;
2235 
2236  return OPERATOR_RUNNING_MODAL;
2237  }
2238  }
2239  else {
2240  sd->previewmode = 1;
2242  /* add temp handler for edge move or cancel */
2245 
2246  return OPERATOR_RUNNING_MODAL;
2247  }
2248 
2249  return OPERATOR_PASS_THROUGH;
2250 }
2251 
2252 /* function to be called outside UI context, or for redo */
2254 {
2255  if (!area_split_init(C, op)) {
2256  return OPERATOR_CANCELLED;
2257  }
2258 
2259  area_split_apply(C, op);
2260  area_split_exit(C, op);
2261 
2262  return OPERATOR_FINISHED;
2263 }
2264 
2266 {
2268 
2269  if (sd->previewmode) {
2270  /* pass */
2271  }
2272  else {
2273  if (screen_area_join(C, CTX_wm_screen(C), sd->sarea, sd->narea)) {
2274  if (CTX_wm_area(C) == sd->narea) {
2277  }
2278  sd->narea = NULL;
2279  }
2280  }
2281  area_split_exit(C, op);
2282 }
2283 
2284 static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
2285 {
2287  PropertyRNA *prop_dir = RNA_struct_find_property(op->ptr, "direction");
2288  bool update_factor = false;
2289 
2290  /* execute the events */
2291  switch (event->type) {
2292  case MOUSEMOVE:
2293  update_factor = true;
2294  break;
2295 
2296  case LEFTMOUSE:
2297  if (sd->previewmode) {
2298  area_split_apply(C, op);
2299  area_split_exit(C, op);
2300  return OPERATOR_FINISHED;
2301  }
2302  else {
2303  if (event->val == KM_RELEASE) { /* mouse up */
2304  area_split_exit(C, op);
2305  return OPERATOR_FINISHED;
2306  }
2307  }
2308  break;
2309 
2310  case MIDDLEMOUSE:
2311  case EVT_TABKEY:
2312  if (sd->previewmode == 0) {
2313  /* pass */
2314  }
2315  else {
2316  if (event->val == KM_PRESS) {
2317  if (sd->sarea) {
2318  int dir = RNA_property_enum_get(op->ptr, prop_dir);
2319  RNA_property_enum_set(op->ptr, prop_dir, (dir == 'v') ? 'h' : 'v');
2321  update_factor = true;
2322  }
2323  }
2324  }
2325 
2326  break;
2327 
2328  case RIGHTMOUSE: /* cancel operation */
2329  case EVT_ESCKEY:
2330  area_split_cancel(C, op);
2331  return OPERATOR_CANCELLED;
2332 
2333  case EVT_LEFTCTRLKEY:
2334  sd->do_snap = event->val == KM_PRESS;
2335  update_factor = true;
2336  break;
2337  }
2338 
2339  if (update_factor) {
2340  const int dir = RNA_property_enum_get(op->ptr, prop_dir);
2341 
2342  sd->delta = (dir == 'v') ? event->x - sd->origval : event->y - sd->origval;
2343 
2344  if (sd->previewmode == 0) {
2345  if (sd->do_snap) {
2346  const int snap_loc = area_snap_calc_location(CTX_wm_screen(C),
2347  SNAP_FRACTION_AND_ADJACENT,
2348  sd->delta,
2349  sd->origval,
2350  dir,
2351  sd->bigger,
2352  sd->smaller);
2353  sd->delta = snap_loc - sd->origval;
2354  }
2355  area_move_apply_do(C, sd->delta, sd->origval, dir, sd->bigger, sd->smaller, SNAP_NONE);
2356  }
2357  else {
2358  if (sd->sarea) {
2360  }
2361  /* area context not set */
2362  sd->sarea = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y);
2363 
2364  if (sd->sarea) {
2365  ScrArea *area = sd->sarea;
2366  if (dir == 'v') {
2367  sd->origmin = area->v1->vec.x;
2368  sd->origsize = area->v4->vec.x - sd->origmin;
2369  }
2370  else {
2371  sd->origmin = area->v1->vec.y;
2372  sd->origsize = area->v2->vec.y - sd->origmin;
2373  }
2374 
2375  if (sd->do_snap) {
2376  area->v1->editflag = area->v2->editflag = area->v3->editflag = area->v4->editflag = 1;
2377 
2378  const int snap_loc = area_snap_calc_location(CTX_wm_screen(C),
2379  SNAP_FRACTION_AND_ADJACENT,
2380  sd->delta,
2381  sd->origval,
2382  dir,
2383  sd->origmin + sd->origsize,
2384  -sd->origmin);
2385 
2386  area->v1->editflag = area->v2->editflag = area->v3->editflag = area->v4->editflag = 0;
2387  sd->delta = snap_loc - sd->origval;
2388  }
2389 
2391  }
2392 
2393  CTX_wm_screen(C)->do_draw = true;
2394  }
2395 
2396  float fac = (float)(sd->delta + sd->origval - sd->origmin) / sd->origsize;
2397  RNA_float_set(op->ptr, "factor", fac);
2398  }
2399 
2400  return OPERATOR_RUNNING_MODAL;
2401 }
2402 
2404  {'h', "HORIZONTAL", 0, "Horizontal", ""},
2405  {'v', "VERTICAL", 0, "Vertical", ""},
2406  {0, NULL, 0, NULL, NULL},
2407 };
2408 
2410 {
2411  ot->name = "Split Area";
2412  ot->description = "Split selected area into new windows";
2413  ot->idname = "SCREEN_OT_area_split";
2414 
2415  ot->exec = area_split_exec;
2419 
2421 
2422  /* flags */
2424 
2425  /* rna */
2426  RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", "");
2427  RNA_def_float(ot->srna, "factor", 0.5f, 0.0, 1.0, "Factor", "", 0.0, 1.0);
2429  ot->srna, "cursor", 2, NULL, INT_MIN, INT_MAX, "Cursor", "", INT_MIN, INT_MAX);
2430 }
2431 
2434 /* -------------------------------------------------------------------- */
2438 typedef struct RegionMoveData {
2443  int origx, origy;
2444  int maxsize;
2446 
2448 
2449 static int area_max_regionsize(ScrArea *area, ARegion *scalear, AZEdge edge)
2450 {
2451  int dist;
2452 
2453  /* regions in regions. */
2454  if (scalear->alignment & RGN_SPLIT_PREV) {
2455  const int align = RGN_ALIGN_ENUM_FROM_MASK(scalear->alignment);
2456 
2457  if (ELEM(align, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
2458  ARegion *region = scalear->prev;
2459  dist = region->winy + scalear->winy - U.pixelsize;
2460  }
2461  else /* if (ELEM(align, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) */ {
2462  ARegion *region = scalear->prev;
2463  dist = region->winx + scalear->winx - U.pixelsize;
2464  }
2465  }
2466  else {
2468  dist = BLI_rcti_size_x(&area->totrct);
2469  }
2470  else { /* AE_BOTTOM_TO_TOPLEFT, AE_TOP_TO_BOTTOMRIGHT */
2471  dist = BLI_rcti_size_y(&area->totrct);
2472  }
2473 
2474  /* subtractwidth of regions on opposite side
2475  * prevents dragging regions into other opposite regions */
2476  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
2477  if (region == scalear) {
2478  continue;
2479  }
2480 
2481  if (scalear->alignment == RGN_ALIGN_LEFT && region->alignment == RGN_ALIGN_RIGHT) {
2482  dist -= region->winx;
2483  }
2484  else if (scalear->alignment == RGN_ALIGN_RIGHT && region->alignment == RGN_ALIGN_LEFT) {
2485  dist -= region->winx;
2486  }
2487  else if (scalear->alignment == RGN_ALIGN_TOP &&
2488  (region->alignment == RGN_ALIGN_BOTTOM ||
2489  ELEM(
2490  region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER, RGN_TYPE_FOOTER))) {
2491  dist -= region->winy;
2492  }
2493  else if (scalear->alignment == RGN_ALIGN_BOTTOM &&
2494  (region->alignment == RGN_ALIGN_TOP ||
2495  ELEM(
2496  region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER, RGN_TYPE_FOOTER))) {
2497  dist -= region->winy;
2498  }
2499  }
2500  }
2501 
2502  dist /= UI_DPI_FAC;
2503  return dist;
2504 }
2505 
2506 static bool is_split_edge(const int alignment, const AZEdge edge)
2507 {
2508  return ((alignment == RGN_ALIGN_BOTTOM) && (edge == AE_TOP_TO_BOTTOMRIGHT)) ||
2509  ((alignment == RGN_ALIGN_TOP) && (edge == AE_BOTTOM_TO_TOPLEFT)) ||
2510  ((alignment == RGN_ALIGN_LEFT) && (edge == AE_RIGHT_TO_TOPLEFT)) ||
2511  ((alignment == RGN_ALIGN_RIGHT) && (edge == AE_LEFT_TO_TOPRIGHT));
2512 }
2513 
2515 {
2516  MEM_freeN(op->customdata);
2517  op->customdata = NULL;
2518 
2519  G.moving &= ~G_TRANSFORM_WM;
2520 }
2521 
2522 static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event)
2523 {
2524  sActionzoneData *sad = event->customdata;
2525 
2526  if (event->type != EVT_ACTIONZONE_REGION) {
2527  BKE_report(op->reports, RPT_ERROR, "Can only scale region size from an action zone");
2528  return OPERATOR_CANCELLED;
2529  }
2530 
2531  AZone *az = sad->az;
2532 
2533  if (az->region) {
2534  RegionMoveData *rmd = MEM_callocN(sizeof(RegionMoveData), "RegionMoveData");
2535 
2536  op->customdata = rmd;
2537 
2538  rmd->az = az;
2539  /* special case for region within region - this allows the scale of
2540  * the parent region if the azone edge is not the edge splitting
2541  * both regions */
2542  if ((az->region->alignment & RGN_SPLIT_PREV) && az->region->prev &&
2544  rmd->region = az->region->prev;
2545  }
2546  else {
2547  rmd->region = az->region;
2548  }
2549  rmd->area = sad->sa1;
2550  rmd->edge = az->edge;
2551  rmd->origx = event->x;
2552  rmd->origy = event->y;
2553  rmd->maxsize = area_max_regionsize(rmd->area, rmd->region, rmd->edge);
2554 
2555  /* if not set we do now, otherwise it uses type */
2556  if (rmd->region->sizex == 0) {
2557  rmd->region->sizex = rmd->region->winx;
2558  }
2559  if (rmd->region->sizey == 0) {
2560  rmd->region->sizey = rmd->region->winy;
2561  }
2562 
2563  /* now copy to regionmovedata */
2565  rmd->origval = rmd->region->sizex;
2566  }
2567  else {
2568  rmd->origval = rmd->region->sizey;
2569  }
2570 
2571  CLAMP(rmd->maxsize, 0, 1000);
2572 
2573  /* add temp handler */
2574  G.moving |= G_TRANSFORM_WM;
2576 
2577  return OPERATOR_RUNNING_MODAL;
2578  }
2579 
2580  return OPERATOR_FINISHED;
2581 }
2582 
2584 {
2585  if ((rmd->region->flag & RGN_FLAG_HIDDEN) == 0) {
2586  short *size, maxsize = -1;
2587 
2589  size = &rmd->region->sizex;
2590  }
2591  else {
2592  size = &rmd->region->sizey;
2593  }
2594 
2595  maxsize = rmd->maxsize - (UI_UNIT_Y / UI_DPI_FAC);
2596 
2597  if (*size > maxsize && maxsize > 0) {
2598  *size = maxsize;
2599  }
2600  }
2601 }
2602 
2604 {
2605  /* hidden areas may have bad 'View2D.cur' value,
2606  * correct before displaying. see T45156 */
2607  if (rmd->region->flag & RGN_FLAG_HIDDEN) {
2609  }
2610 
2611  region_toggle_hidden(C, rmd->region, 0);
2613 
2614  if ((rmd->region->flag & RGN_FLAG_HIDDEN) == 0) {
2615  if (rmd->region->regiontype == RGN_TYPE_HEADER) {
2616  ARegion *region_tool_header = BKE_area_find_region_type(rmd->area, RGN_TYPE_TOOL_HEADER);
2617  if (region_tool_header != NULL) {
2618  if ((region_tool_header->flag & RGN_FLAG_HIDDEN_BY_USER) == 0 &&
2619  (region_tool_header->flag & RGN_FLAG_HIDDEN) != 0) {
2620  region_toggle_hidden(C, region_tool_header, 0);
2621  }
2622  }
2623  }
2624  }
2625 }
2626 
2627 static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
2628 {
2629  RegionMoveData *rmd = op->customdata;
2630  int delta;
2631 
2632  /* execute the events */
2633  switch (event->type) {
2634  case MOUSEMOVE: {
2635  const float aspect = BLI_rctf_size_x(&rmd->region->v2d.cur) /
2636  (BLI_rcti_size_x(&rmd->region->v2d.mask) + 1);
2637  const int snap_size_threshold = (U.widget_unit * 2) / aspect;
2639  delta = event->x - rmd->origx;
2640  if (rmd->edge == AE_LEFT_TO_TOPRIGHT) {
2641  delta = -delta;
2642  }
2643 
2644  /* region sizes now get multiplied */
2645  delta /= UI_DPI_FAC;
2646 
2647  const int size_no_snap = rmd->origval + delta;
2648  rmd->region->sizex = size_no_snap;
2649 
2650  if (rmd->region->type->snap_size) {
2651  short sizex_test = rmd->region->type->snap_size(rmd->region, rmd->region->sizex, 0);
2652  if (abs(rmd->region->sizex - sizex_test) < snap_size_threshold) {
2653  rmd->region->sizex = sizex_test;
2654  }
2655  }
2656  CLAMP(rmd->region->sizex, 0, rmd->maxsize);
2657 
2658  if (size_no_snap < UI_UNIT_X / aspect) {
2659  rmd->region->sizex = rmd->origval;
2660  if (!(rmd->region->flag & RGN_FLAG_HIDDEN)) {
2662  }
2663  }
2664  else if (rmd->region->flag & RGN_FLAG_HIDDEN) {
2666  }
2667  else if (rmd->region->flag & RGN_FLAG_DYNAMIC_SIZE) {
2668  rmd->region->sizex = rmd->origval;
2669  }
2670  }
2671  else {
2672  delta = event->y - rmd->origy;
2673  if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) {
2674  delta = -delta;
2675  }
2676 
2677  /* region sizes now get multiplied */
2678  delta /= UI_DPI_FAC;
2679 
2680  const int size_no_snap = rmd->origval + delta;
2681  rmd->region->sizey = size_no_snap;
2682 
2683  if (rmd->region->type->snap_size) {
2684  short sizey_test = rmd->region->type->snap_size(rmd->region, rmd->region->sizey, 1);
2685  if (abs(rmd->region->sizey - sizey_test) < snap_size_threshold) {
2686  rmd->region->sizey = sizey_test;
2687  }
2688  }
2689  CLAMP(rmd->region->sizey, 0, rmd->maxsize);
2690 
2691  /* note, 'UI_UNIT_Y/4' means you need to drag the footer and execute region
2692  * almost all the way down for it to become hidden, this is done
2693  * otherwise its too easy to do this by accident */
2694  if (size_no_snap < (UI_UNIT_Y / 4) / aspect) {
2695  rmd->region->sizey = rmd->origval;
2696  if (!(rmd->region->flag & RGN_FLAG_HIDDEN)) {
2698  }
2699  }
2700  else if (rmd->region->flag & RGN_FLAG_HIDDEN) {
2702  }
2703  else if (rmd->region->flag & RGN_FLAG_DYNAMIC_SIZE) {
2704  rmd->region->sizey = rmd->origval;
2705  }
2706  }
2707  ED_area_tag_redraw(rmd->area);
2709 
2710  break;
2711  }
2712  case LEFTMOUSE:
2713  if (event->val == KM_RELEASE) {
2715  if (rmd->region->flag & RGN_FLAG_HIDDEN) {
2717  }
2718  else if (rmd->region->flag & RGN_FLAG_TOO_SMALL) {
2720  }
2721 
2722  ED_area_tag_redraw(rmd->area);
2724  }
2725 
2726  region_scale_exit(op);
2727 
2728  return OPERATOR_FINISHED;
2729  }
2730  break;
2731 
2732  case EVT_ESCKEY:
2733  break;
2734  }
2735 
2736  return OPERATOR_RUNNING_MODAL;
2737 }
2738 
2740 {
2741  region_scale_exit(op);
2742 }
2743 
2745 {
2746  /* identifiers */
2747  ot->name = "Scale Region Size";
2748  ot->description = "Scale selected area";
2749  ot->idname = "SCREEN_OT_region_scale";
2750 
2754 
2756 
2757  /* flags */
2759 }
2760 
2763 /* -------------------------------------------------------------------- */
2767 static void areas_do_frame_follow(bContext *C, bool middle)
2768 {
2769  bScreen *screen_ctx = CTX_wm_screen(C);
2772  LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
2773  const bScreen *screen = WM_window_get_active_screen(window);
2774 
2775  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
2776  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
2777  /* do follow here if editor type supports it */
2778  if ((screen_ctx->redraws_flag & TIME_FOLLOW)) {
2779  if ((region->regiontype == RGN_TYPE_WINDOW &&
2780  ELEM(area->spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) ||
2781  (area->spacetype == SPACE_CLIP && region->regiontype == RGN_TYPE_PREVIEW)) {
2782  float w = BLI_rctf_size_x(&region->v2d.cur);
2783 
2784  if (middle) {
2785  if ((scene->r.cfra < region->v2d.cur.xmin) ||
2786  (scene->r.cfra > region->v2d.cur.xmax)) {
2787  region->v2d.cur.xmax = scene->r.cfra + (w / 2);
2788  region->v2d.cur.xmin = scene->r.cfra - (w / 2);
2789  }
2790  }
2791  else {
2792  if (scene->r.cfra < region->v2d.cur.xmin) {
2793  region->v2d.cur.xmax = scene->r.cfra;
2794  region->v2d.cur.xmin = region->v2d.cur.xmax - w;
2795  }
2796  else if (scene->r.cfra > region->v2d.cur.xmax) {
2797  region->v2d.cur.xmin = scene->r.cfra;
2798  region->v2d.cur.xmax = region->v2d.cur.xmin + w;
2799  }
2800  }
2801  }
2802  }
2803  }
2804  }
2805  }
2806 }
2807 
2808 /* function to be called outside UI context, or for redo */
2810 {
2812 
2813  int delta = RNA_int_get(op->ptr, "delta");
2814 
2815  CFRA += delta;
2817  SUBFRA = 0.0f;
2818 
2819  areas_do_frame_follow(C, false);
2820 
2822 
2824 
2825  return OPERATOR_FINISHED;
2826 }
2827 
2829 {
2830  ot->name = "Frame Offset";
2831  ot->idname = "SCREEN_OT_frame_offset";
2832  ot->description = "Move current frame forward/backward by a given number";
2833 
2835 
2838  ot->undo_group = "Frame Change";
2839 
2840  /* rna */
2841  RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
2842 }
2843 
2846 /* -------------------------------------------------------------------- */
2850 /* function to be called outside UI context, or for redo */
2852 {
2854  wmTimer *animtimer = CTX_wm_screen(C)->animtimer;
2855 
2856  /* Don't change CFRA directly if animtimer is running as this can cause
2857  * first/last frame not to be actually shown (bad since for example physics
2858  * simulations aren't reset properly).
2859  */
2860  if (animtimer) {
2861  ScreenAnimData *sad = animtimer->customdata;
2862 
2864 
2865  if (RNA_boolean_get(op->ptr, "end")) {
2866  sad->nextfra = PEFRA;
2867  }
2868  else {
2869  sad->nextfra = PSFRA;
2870  }
2871  }
2872  else {
2873  if (RNA_boolean_get(op->ptr, "end")) {
2874  CFRA = PEFRA;
2875  }
2876  else {
2877  CFRA = PSFRA;
2878  }
2879 
2880  areas_do_frame_follow(C, true);
2881 
2883 
2885  }
2886 
2887  return OPERATOR_FINISHED;
2888 }
2889 
2891 {
2892  ot->name = "Jump to Endpoint";
2893  ot->description = "Jump to first/last frame in frame range";
2894  ot->idname = "SCREEN_OT_frame_jump";
2895 
2896  ot->exec = frame_jump_exec;
2897 
2900  ot->undo_group = "Frame Change";
2901 
2902  /* rna */
2903  RNA_def_boolean(ot->srna, "end", 0, "Last Frame", "Jump to the last frame of the frame range");
2904 }
2905 
2908 /* -------------------------------------------------------------------- */
2912 /* function to be called outside UI context, or for redo */
2914 {
2917  bDopeSheet ads = {NULL};
2918  const bool next = RNA_boolean_get(op->ptr, "next");
2919  bool done = false;
2920 
2921  /* sanity checks */
2922  if (scene == NULL) {
2923  return OPERATOR_CANCELLED;
2924  }
2925 
2926  float cfra = (float)(CFRA);
2927 
2928  /* init binarytree-list for getting keyframes */
2929  DLRBT_Tree keys;
2930  BLI_dlrbTree_init(&keys);
2931 
2932  /* seed up dummy dopesheet context with flags to perform necessary filtering */
2933  if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) {
2934  /* only selected channels are included */
2936  }
2937 
2938  /* populate tree with keyframe nodes */
2939  scene_to_keylist(&ads, scene, &keys, 0);
2940 
2941  if (ob) {
2942  ob_to_keylist(&ads, ob, &keys, 0);
2943 
2944  if (ob->type == OB_GPENCIL) {
2945  const bool active = !(scene->flag & SCE_KEYS_NO_SELONLY);
2946  gpencil_to_keylist(&ads, ob->data, &keys, active);
2947  }
2948  }
2949 
2950  {
2952  if (mask) {
2953  MaskLayer *masklay = BKE_mask_layer_active(mask);
2954  mask_to_keylist(&ads, masklay, &keys);
2955  }
2956  }
2957 
2958  /* find matching keyframe in the right direction */
2959  ActKeyColumn *ak;
2960  if (next) {
2962  }
2963  else {
2965  }
2966 
2967  while ((ak != NULL) && (done == false)) {
2968  if (CFRA != (int)ak->cfra) {
2969  /* this changes the frame, so set the frame and we're done */
2970  CFRA = (int)ak->cfra;
2971  done = true;
2972  }
2973  else {
2974  /* take another step... */
2975  if (next) {
2976  ak = ak->next;
2977  }
2978  else {
2979  ak = ak->prev;
2980  }
2981  }
2982  }
2983 
2984  /* free temp stuff */
2985  BLI_dlrbTree_free(&keys);
2986 
2987  /* any success? */
2988  if (done == false) {
2989  BKE_report(op->reports, RPT_INFO, "No more keyframes to jump to in this direction");
2990 
2991  return OPERATOR_CANCELLED;
2992  }
2993 
2994  areas_do_frame_follow(C, true);
2995 
2997 
2999 
3000  return OPERATOR_FINISHED;
3001 }
3002 
3004 {
3005  ot->name = "Jump to Keyframe";
3006  ot->description = "Jump to previous/next keyframe";
3007  ot->idname = "SCREEN_OT_keyframe_jump";
3008 
3010 
3013  ot->undo_group = "Frame Change";
3014 
3015  /* properties */
3016  RNA_def_boolean(ot->srna, "next", true, "Next Keyframe", "");
3017 }
3018 
3021 /* -------------------------------------------------------------------- */
3025 /* function to be called outside UI context, or for redo */
3027 {
3029  int closest = CFRA;
3030  const bool next = RNA_boolean_get(op->ptr, "next");
3031  bool found = false;
3032 
3033  /* find matching marker in the right direction */
3034  LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
3035  if (next) {
3036  if ((marker->frame > CFRA) && (!found || closest > marker->frame)) {
3037  closest = marker->frame;
3038  found = true;
3039  }
3040  }
3041  else {
3042  if ((marker->frame < CFRA) && (!found || closest < marker->frame)) {
3043  closest = marker->frame;
3044  found = true;
3045  }
3046  }
3047  }
3048 
3049  /* any success? */
3050  if (!found) {
3051  BKE_report(op->reports, RPT_INFO, "No more markers to jump to in this direction");
3052 
3053  return OPERATOR_CANCELLED;
3054  }
3055 
3056  CFRA = closest;
3057 
3058  areas_do_frame_follow(C, true);
3059 
3061 
3063 
3064  return OPERATOR_FINISHED;
3065 }
3066 
3068 {
3069  ot->name = "Jump to Marker";
3070  ot->description = "Jump to previous/next marker";
3071  ot->idname = "SCREEN_OT_marker_jump";
3072 
3074 
3077  ot->undo_group = "Frame Change";
3078 
3079  /* properties */
3080  RNA_def_boolean(ot->srna, "next", true, "Next Marker", "");
3081 }
3082 
3085 /* -------------------------------------------------------------------- */
3089 /* function to be called outside UI context, or for redo */
3091 {
3092  WorkSpace *workspace = CTX_wm_workspace(C);
3093  int delta = RNA_int_get(op->ptr, "delta");
3094 
3095  if (ED_workspace_layout_cycle(workspace, delta, C)) {
3096  return OPERATOR_FINISHED;
3097  }
3098 
3099  return OPERATOR_CANCELLED;
3100 }
3101 
3103 {
3104  ot->name = "Set Screen";
3105  ot->description = "Cycle through available screens";
3106  ot->idname = "SCREEN_OT_screen_set";
3107 
3108  ot->exec = screen_set_exec;
3110 
3111  /* rna */
3112  RNA_def_int(ot->srna, "delta", 1, -1, 1, "Delta", "", -1, 1);
3113 }
3114 
3117 /* -------------------------------------------------------------------- */
3121 /* function to be called outside UI context, or for redo */
3123 {
3124  bScreen *screen = CTX_wm_screen(C);
3125  ScrArea *area = NULL;
3126  const bool hide_panels = RNA_boolean_get(op->ptr, "use_hide_panels");
3127 
3128  BLI_assert(!screen->temp);
3129 
3130  /* search current screen for 'fullscreen' areas */
3131  /* prevents restoring info header, when mouse is over it */
3132  LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) {
3133  if (area_iter->full) {
3134  area = area_iter;
3135  break;
3136  }
3137  }
3138 
3139  if (area == NULL) {
3140  area = CTX_wm_area(C);
3141  }
3142 
3143  if (hide_panels) {
3144  if (!ELEM(screen->state, SCREENNORMAL, SCREENFULL)) {
3145  return OPERATOR_CANCELLED;
3146  }
3148  }
3149  else {
3150  if (!ELEM(screen->state, SCREENNORMAL, SCREENMAXIMIZED)) {
3151  return OPERATOR_CANCELLED;
3152  }
3154  }
3155 
3156  return OPERATOR_FINISHED;
3157 }
3158 
3160 {
3161  const wmWindow *win = CTX_wm_window(C);
3162  const bScreen *screen = CTX_wm_screen(C);
3163  const ScrArea *area = CTX_wm_area(C);
3164  return ED_operator_areaactive(C) &&
3165  /* Don't allow maximizing global areas but allow minimizing from them. */
3166  ((screen->state != SCREENNORMAL) || !ED_area_is_global(area)) &&
3167  /* Don't change temporary screens. */
3169 }
3170 
3172 {
3173  PropertyRNA *prop;
3174 
3175  ot->name = "Toggle Maximize Area";
3176  ot->description = "Toggle display selected area as fullscreen/maximized";
3177  ot->idname = "SCREEN_OT_screen_full_area";
3178 
3181  ot->flag = 0;
3182 
3183  prop = RNA_def_boolean(ot->srna, "use_hide_panels", false, "Hide Panels", "Hide all the panels");
3185 }
3186 
3189 /* -------------------------------------------------------------------- */
3193 /* operator state vars used:
3194  * x1, y1 mouse coord in first area, which will disappear
3195  * x2, y2 mouse coord in 2nd area, which will become joined
3196  *
3197  * functions:
3198  *
3199  * init() find edge based on state vars
3200  * test if the edge divides two areas,
3201  * store active and nonactive area,
3202  *
3203  * apply() do the actual join
3204  *
3205  * exit() cleanup, send notifier
3206  *
3207  * callbacks:
3208  *
3209  * exec() calls init, apply, exit
3210  *
3211  * invoke() sets mouse coords in x,y
3212  * call init()
3213  * add modal handler
3214  *
3215  * modal() accept modal events while doing it
3216  * call apply() with active window and nonactive window
3217  * call exit() and remove handler when LMB confirm
3218  */
3219 
3220 typedef struct sAreaJoinData {
3221  ScrArea *sa1; /* first area to be considered */
3222  ScrArea *sa2; /* second area to be considered */
3223  void *draw_callback; /* call `ED_screen_draw_join_shape` */
3224 
3226 
3227 static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata)
3228 {
3229  const wmOperator *op = userdata;
3230 
3231  sAreaJoinData *sd = op->customdata;
3232  if (sd->sa1 && sd->sa2) {
3233  ED_screen_draw_join_shape(sd->sa1, sd->sa2);
3234  }
3235 }
3236 
3237 /* validate selection inside screen, set variables OK */
3238 /* return false: init failed */
3239 static bool area_join_init(bContext *C, wmOperator *op, ScrArea *sa1, ScrArea *sa2)
3240 {
3241  if (sa1 == NULL || sa2 == NULL) {
3242  /* Get areas from cursor location if not specified. */
3243  int cursor[2];
3244  RNA_int_get_array(op->ptr, "cursor", cursor);
3245  screen_area_edge_from_cursor(C, cursor, &sa1, &sa2);
3246  }
3247  if (sa1 == NULL || sa2 == NULL) {
3248  return false;
3249  }
3250 
3251  sAreaJoinData *jd = MEM_callocN(sizeof(sAreaJoinData), "op_area_join");
3252 
3253  jd->sa1 = sa1;
3254  jd->sa2 = sa2;
3255 
3256  op->customdata = jd;
3257 
3259 
3260  return true;
3261 }
3262 
3263 /* apply the join of the areas (space types) */
3265 {
3266  sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
3267  if (!jd) {
3268  return false;
3269  }
3270 
3271  if (!screen_area_join(C, CTX_wm_screen(C), jd->sa1, jd->sa2)) {
3272  return false;
3273  }
3274  if (CTX_wm_area(C) == jd->sa2) {
3277  }
3278 
3279  return true;
3280 }
3281 
3282 /* finish operation */
3284 {
3285  sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
3286 
3287  if (jd) {
3288  if (jd->draw_callback) {
3290  }
3291 
3292  MEM_freeN(jd);
3293  op->customdata = NULL;
3294  }
3295 
3296  /* this makes sure aligned edges will result in aligned grabbing */
3300 }
3301 
3303 {
3304  if (!area_join_init(C, op, NULL, NULL)) {
3305  return OPERATOR_CANCELLED;
3306  }
3307 
3308  area_join_apply(C, op);
3309  area_join_exit(C, op);
3310 
3311  return OPERATOR_FINISHED;
3312 }
3313 
3314 /* interaction callback */
3315 static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
3316 {
3317  if (event->type == EVT_ACTIONZONE_AREA) {
3318  sActionzoneData *sad = event->customdata;
3319 
3320  if (sad == NULL || sad->modifier > 0) {
3321  return OPERATOR_PASS_THROUGH;
3322  }
3323 
3324  /* verify *sad itself */
3325  if (sad->sa1 == NULL || sad->sa2 == NULL) {
3326  return OPERATOR_PASS_THROUGH;
3327  }
3328 
3329  /* is this our *sad? if areas equal it should be passed on */
3330  if (sad->sa1 == sad->sa2) {
3331  return OPERATOR_PASS_THROUGH;
3332  }
3333  if (!area_join_init(C, op, sad->sa1, sad->sa2)) {
3334  return OPERATOR_CANCELLED;
3335  }
3336  }
3337 
3338  /* add temp handler */
3340 
3341  return OPERATOR_RUNNING_MODAL;
3342 }
3343 
3345 {
3347 
3348  area_join_exit(C, op);
3349 }
3350 
3351 /* modal callback while selecting area (space) that will be removed */
3352 static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
3353 {
3354  bScreen *screen = CTX_wm_screen(C);
3355  wmWindow *win = CTX_wm_window(C);
3356 
3357  if (op->customdata == NULL) {
3358  if (!area_join_init(C, op, NULL, NULL)) {
3359  return OPERATOR_CANCELLED;
3360  }
3361  }
3362  sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
3363 
3364  /* execute the events */
3365  switch (event->type) {
3366 
3367  case MOUSEMOVE: {
3368  ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y);
3369  int dir = -1;
3370 
3371  if (area) {
3372  if (jd->sa1 != area) {
3373  dir = area_getorientation(jd->sa1, area);
3374  if (dir != -1) {
3375  jd->sa2 = area;
3376  }
3377  else {
3378  /* we are not bordering on the previously selected area
3379  * we check if area has common border with the one marked for removal
3380  * in this case we can swap areas.
3381  */
3382  dir = area_getorientation(area, jd->sa2);
3383  if (dir != -1) {
3384  jd->sa1 = jd->sa2;
3385  jd->sa2 = area;
3386  }
3387  else {
3388  jd->sa2 = NULL;
3389  }
3390  }
3392  }
3393  else {
3394  /* we are back in the area previously selected for keeping
3395  * we swap the areas if possible to allow user to choose */
3396  if (jd->sa2 != NULL) {
3397  jd->sa1 = jd->sa2;
3398  jd->sa2 = area;
3399  dir = area_getorientation(jd->sa1, jd->sa2);
3400  if (dir == -1) {
3401  printf("oops, didn't expect that!\n");
3402  }
3403  }
3404  else {
3405  dir = area_getorientation(jd->sa1, area);
3406  if (dir != -1) {
3407  jd->sa2 = area;
3408  }
3409  }
3411  }
3412  }
3413 
3414  if (dir == 1) {
3416  }
3417  else if (dir == 3) {
3419  }
3420  else if (dir == 2) {
3422  }
3423  else if (dir == 0) {
3425  }
3426  else {
3428  }
3429 
3430  break;
3431  }
3432  case LEFTMOUSE:
3433  if (event->val == KM_RELEASE) {
3434  ED_area_tag_redraw(jd->sa1);
3435  ED_area_tag_redraw(jd->sa2);
3436 
3437  area_join_apply(C, op);
3439  area_join_exit(C, op);
3440  return OPERATOR_FINISHED;
3441  }
3442  break;
3443 
3444  case RIGHTMOUSE:
3445  case EVT_ESCKEY:
3446  area_join_cancel(C, op);
3447  return OPERATOR_CANCELLED;
3448  }
3449 
3450  return OPERATOR_RUNNING_MODAL;
3451 }
3452 
3453 /* Operator for joining two areas (space types) */
3455 {
3456  /* identifiers */
3457  ot->name = "Join Area";
3458  ot->description = "Join selected areas into new window";
3459  ot->idname = "SCREEN_OT_area_join";
3460 
3461  /* api callbacks */
3462  ot->exec = area_join_exec;
3467 
3468  /* flags */
3470 
3471  /* rna */
3473  ot->srna, "cursor", 2, NULL, INT_MIN, INT_MAX, "Cursor", "", INT_MIN, INT_MAX);
3474 }
3475 
3478 /* -------------------------------------------------------------------- */
3482 static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event)
3483 {
3484  ScrArea *sa1, *sa2;
3485  if (screen_area_edge_from_cursor(C, &event->x, &sa1, &sa2) == NULL) {
3486  return OPERATOR_CANCELLED;
3487  }
3488 
3489  uiPopupMenu *pup = UI_popup_menu_begin(C, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
3490  uiLayout *layout = UI_popup_menu_layout(pup);
3491 
3492  /* Vertical Split */
3493  PointerRNA ptr;
3494  uiItemFullO(layout,
3495  "SCREEN_OT_area_split",
3496  IFACE_("Vertical Split"),
3497  ICON_NONE,
3498  NULL,
3500  0,
3501  &ptr);
3502  /* store initial mouse cursor position. */
3503  RNA_int_set_array(&ptr, "cursor", &event->x);
3504  RNA_enum_set(&ptr, "direction", 'v');
3505 
3506  /* Horizontal Split */
3507  uiItemFullO(layout,
3508  "SCREEN_OT_area_split",
3509  IFACE_("Horizontal Split"),
3510  ICON_NONE,
3511  NULL,
3513  0,
3514  &ptr);
3515  /* store initial mouse cursor position. */
3516  RNA_int_set_array(&ptr, "cursor", &event->x);
3517  RNA_enum_set(&ptr, "direction", 'h');
3518 
3519  if (sa1 && sa2) {
3520  uiItemS(layout);
3521  }
3522 
3523  /* Join needs two very similar areas. */
3524  if (sa1 && sa2 && (area_getorientation(sa1, sa2) != -1)) {
3525  uiItemFullO(layout,
3526  "SCREEN_OT_area_join",
3527  IFACE_("Join Areas"),
3528  ICON_NONE,
3529  NULL,
3531  0,
3532  &ptr);
3533  RNA_int_set_array(&ptr, "cursor", &event->x);
3534  }
3535 
3536  /* Swap just needs two areas. */
3537  if (sa1 && sa2) {
3538  uiItemFullO(layout,
3539  "SCREEN_OT_area_swap",
3540  IFACE_("Swap Areas"),
3541  ICON_NONE,
3542  NULL,
3544  0,
3545  &ptr);
3546  RNA_int_set_array(&ptr, "cursor", &event->x);
3547  }
3548 
3549  UI_popup_menu_end(C, pup);
3550 
3551  return OPERATOR_INTERFACE;
3552 }
3553 
3555 {
3556  /* identifiers */
3557  ot->name = "Area Options";
3558  ot->description = "Operations for splitting and merging";
3559  ot->idname = "SCREEN_OT_area_options";
3560 
3561  /* api callbacks */
3563 
3565 
3566  /* flags */
3567  ot->flag = OPTYPE_INTERNAL;
3568 }
3569 
3572 /* -------------------------------------------------------------------- */
3577 {
3578  Main *bmain = CTX_data_main(C);
3579  int tot = 0;
3580 
3581  LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
3582  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
3583  if (area->spacedata.first != area->spacedata.last) {
3584  SpaceLink *sl = area->spacedata.first;
3585 
3586  BLI_remlink(&area->spacedata, sl);
3587  tot += BLI_listbase_count(&area->spacedata);
3588  BKE_spacedata_freelist(&area->spacedata);
3589  BLI_addtail(&area->spacedata, sl);
3590  }
3591  }
3592  }
3593  BKE_reportf(op->reports, RPT_INFO, "Removed amount of editors: %d", tot);
3594 
3595  return OPERATOR_FINISHED;
3596 }
3597 
3599 {
3600  /* identifiers */
3601  ot->name = "Clean Up Space Data";
3602  ot->description = "Remove unused settings for invisible editors";
3603  ot->idname = "SCREEN_OT_spacedata_cleanup";
3604 
3605  /* api callbacks */
3608 }
3609 
3612 /* -------------------------------------------------------------------- */
3617 {
3618  if (!ED_operator_screenactive(C)) {
3619  return false;
3620  }
3622  return !BLI_listbase_is_empty(&wm->operators);
3623 }
3624 
3626 {
3628  wmOperator *lastop = wm->operators.last;
3629 
3630  /* Seek last registered operator */
3631  while (lastop) {
3632  if (lastop->type->flag & OPTYPE_REGISTER) {
3633  break;
3634  }
3635  lastop = lastop->prev;
3636  }
3637 
3638  if (lastop) {
3639  WM_operator_free_all_after(wm, lastop);
3640  WM_operator_repeat_last(C, lastop);
3641  }
3642 
3643  return OPERATOR_CANCELLED;
3644 }
3645 
3647 {
3648  /* identifiers */
3649  ot->name = "Repeat Last";
3650  ot->description = "Repeat last action";
3651  ot->idname = "SCREEN_OT_repeat_last";
3652 
3653  /* api callbacks */
3655 
3657 }
3658 
3661 /* -------------------------------------------------------------------- */
3665 static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
3666 {
3668 
3669  int items = BLI_listbase_count(&wm->operators);
3670  if (items == 0) {
3671  return OPERATOR_CANCELLED;
3672  }
3673 
3674  uiPopupMenu *pup = UI_popup_menu_begin(C, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
3675  uiLayout *layout = UI_popup_menu_layout(pup);
3676 
3677  wmOperator *lastop;
3678  int i;
3679  for (i = items - 1, lastop = wm->operators.last; lastop; lastop = lastop->prev, i--) {
3680  if ((lastop->type->flag & OPTYPE_REGISTER) && WM_operator_repeat_check(C, lastop)) {
3681  uiItemIntO(layout,
3682  WM_operatortype_name(lastop->type, lastop->ptr),
3683  ICON_NONE,
3684  op->type->idname,
3685  "index",
3686  i);
3687  }
3688  }
3689 
3690  UI_popup_menu_end(C, pup);
3691 
3692  return OPERATOR_INTERFACE;
3693 }
3694 
3696 {
3698 
3699  op = BLI_findlink(&wm->operators, RNA_int_get(op->ptr, "index"));
3700  if (op) {
3701  /* let's put it as last operator in list */
3702  BLI_remlink(&wm->operators, op);
3703  BLI_addtail(&wm->operators, op);
3704 
3705  WM_operator_repeat(C, op);
3706  }
3707 
3708  return OPERATOR_FINISHED;
3709 }
3710 
3712 {
3713  /* identifiers */
3714  ot->name = "Repeat History";
3715  ot->description = "Display menu for previous actions performed";
3716  ot->idname = "SCREEN_OT_repeat_history";
3717 
3718  /* api callbacks */
3722 
3723  RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
3724 }
3725 
3728 /* -------------------------------------------------------------------- */
3732 static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
3733 {
3734  wmOperator *lastop = WM_operator_last_redo(C);
3735 
3736  if (lastop) {
3737  WM_operator_redo_popup(C, lastop);
3738  }
3739 
3740  return OPERATOR_CANCELLED;
3741 }
3742 
3744 {
3745  /* identifiers */
3746  ot->name = "Redo Last";
3747  ot->description = "Display parameters for last action performed";
3748  ot->idname = "SCREEN_OT_redo_last";
3749 
3750  /* api callbacks */
3753 }
3754 
3757 /* -------------------------------------------------------------------- */
3762 {
3763  if (rv3d->localvd) {
3764  rv3d->localvd->view = rv3d->view;
3765  rv3d->localvd->persp = rv3d->persp;
3766  copy_qt_qt(rv3d->localvd->viewquat, rv3d->viewquat);
3767  }
3768 }
3769 
3771  ScrArea *area, ARegion *region, const char viewlock, const char view, const char persp)
3772 {
3773  RegionView3D *rv3d = region->regiondata;
3774 
3775  if (persp == RV3D_CAMOB) {
3777  }
3778 
3779  rv3d->viewlock = viewlock;
3780  rv3d->runtime_viewlock = 0;
3781  rv3d->view = view;
3783  rv3d->persp = persp;
3784 
3785  ED_view3d_lock(rv3d);
3787  if ((viewlock & RV3D_BOXCLIP) && (persp == RV3D_ORTHO)) {
3788  ED_view3d_quadview_update(area, region, true);
3789  }
3790 }
3791 
3792 /* insert a region in the area region list */
3794 {
3795  ARegion *region = CTX_wm_region(C);
3796 
3797  /* some rules... */
3798  if (region->regiontype != RGN_TYPE_WINDOW) {
3799  BKE_report(op->reports, RPT_ERROR, "Only window region can be 4-split");
3800  }
3801  else if (region->alignment == RGN_ALIGN_QSPLIT) {
3802  /* Exit quad-view */
3803  ScrArea *area = CTX_wm_area(C);
3804 
3805  /* keep current region */
3806  region->alignment = 0;
3807 
3808  if (area->spacetype == SPACE_VIEW3D) {
3809  RegionView3D *rv3d = region->regiondata;
3810 
3811  /* if this is a locked view, use settings from 'User' view */
3812  if (rv3d->viewlock) {
3813  View3D *v3d_user;
3814  ARegion *region_user;
3815 
3816  if (ED_view3d_context_user_region(C, &v3d_user, &region_user)) {
3817  if (region != region_user) {
3818  SWAP(void *, region->regiondata, region_user->regiondata);
3819  rv3d = region->regiondata;
3820  }
3821  }
3822  }
3823 
3825  rv3d->viewlock = 0;
3826 
3827  /* FIXME: This fixes missing update to workbench TAA. (see T76216)
3828  * However, it would be nice if the tagging should be done in a more conventional way. */
3829  rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
3830 
3831  /* Accumulate locks, in case they're mixed. */
3832  LISTBASE_FOREACH (ARegion *, region_iter, &area->regionbase) {
3833  if (region_iter->regiontype == RGN_TYPE_WINDOW) {
3834  RegionView3D *rv3d_iter = region_iter->regiondata;
3835  rv3d->viewlock_quad |= rv3d_iter->viewlock;
3836  }
3837  }
3838  }
3839 
3840  LISTBASE_FOREACH_MUTABLE (ARegion *, region_iter, &area->regionbase) {
3841  if (region_iter->alignment == RGN_ALIGN_QSPLIT) {
3842  ED_region_remove(C, area, region_iter);
3843  }
3844  }
3847  }
3848  else if (region->next) {
3849  BKE_report(op->reports, RPT_ERROR, "Only last region can be 4-split");
3850  }
3851  else {
3852  /* Enter quad-view */
3853  ScrArea *area = CTX_wm_area(C);
3854 
3855  region->alignment = RGN_ALIGN_QSPLIT;
3856 
3857  for (int count = 0; count < 3; count++) {
3858  ARegion *new_region = BKE_area_region_copy(area->type, region);
3859  BLI_addtail(&area->regionbase, new_region);
3860  }
3861 
3862  /* lock views and set them */
3863  if (area->spacetype == SPACE_VIEW3D) {
3864  View3D *v3d = area->spacedata.first;
3865  int index_qsplit = 0;
3866 
3867  /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set,
3868  * otherwise when restoring rv3d->localvd the 'viewquat' won't
3869  * match the 'view', set on entering localview See: T26315,
3870  *
3871  * We could avoid manipulating rv3d->localvd here if exiting
3872  * localview with a 4-split would assign these view locks */
3873  RegionView3D *rv3d = region->regiondata;
3874  const char viewlock = (rv3d->viewlock_quad & RV3D_VIEWLOCK_INIT) ?
3875  (rv3d->viewlock_quad & ~RV3D_VIEWLOCK_INIT) :
3877 
3879  area, region, viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO);
3881  (region = region->next),
3882  viewlock,
3883  ED_view3d_lock_view_from_index(index_qsplit++),
3884  RV3D_ORTHO);
3886  (region = region->next),
3887  viewlock,
3888  ED_view3d_lock_view_from_index(index_qsplit++),
3889  RV3D_ORTHO);
3890  /* forcing camera is distracting */
3891 #if 0
3892  if (v3d->camera) {
3894  }
3895  else {
3896  region_quadview_init_rv3d(area, (region = region->next), 0, RV3D_VIEW_USER, RV3D_PERSP);
3897  }
3898 #else
3899  (void)v3d;
3900 #endif
3901  }
3904  }
3905 
3906  return OPERATOR_FINISHED;
3907 }
3908 
3910 {
3911  /* identifiers */
3912  ot->name = "Toggle Quad View";
3913  ot->description = "Split selected area into camera, front, right, and top views";
3914  ot->idname = "SCREEN_OT_region_quadview";
3915 
3916  /* api callbacks */
3919  ot->flag = 0;
3920 }
3921 
3924 /* -------------------------------------------------------------------- */
3929 {
3930  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "region_type");
3931 
3932  ARegion *region;
3933  if (RNA_property_is_set(op->ptr, prop)) {
3935  }
3936  else {
3937  region = CTX_wm_region(C);
3938  }
3939 
3940  if (region && (region->alignment != RGN_ALIGN_NONE)) {
3941  ED_region_toggle_hidden(C, region);
3942  }
3943  ED_region_tag_redraw(region);
3944 
3945  return OPERATOR_FINISHED;
3946 }
3947 
3949 {
3950  ScrArea *area = CTX_wm_area(C);
3951 
3952  /* Don't flip anything around in top-bar. */
3953  if (area && area->spacetype == SPACE_TOPBAR) {
3954  CTX_wm_operator_poll_msg_set(C, "Toggling regions in the Top-bar is not allowed");
3955  return false;
3956  }
3957 
3958  return ED_operator_areaactive(C);
3959 }
3960 
3962 {
3963  /* identifiers */
3964  ot->name = "Toggle Region";
3965  ot->idname = "SCREEN_OT_region_toggle";
3966  ot->description = "Hide or unhide the region";
3967 
3968  /* api callbacks */
3971  ot->flag = 0;
3972 
3973  RNA_def_enum(ot->srna,
3974  "region_type",
3976  0,
3977  "Region Type",
3978  "Type of the region to toggle");
3979 }
3980 
3983 /* -------------------------------------------------------------------- */
3987 /* flip a region alignment */
3989 {
3990  ARegion *region = CTX_wm_region(C);
3991 
3992  if (!region) {
3993  return OPERATOR_CANCELLED;
3994  }
3995 
3996  if (region->alignment == RGN_ALIGN_TOP) {
3997  region->alignment = RGN_ALIGN_BOTTOM;
3998  }
3999  else if (region->alignment == RGN_ALIGN_BOTTOM) {
4000  region->alignment = RGN_ALIGN_TOP;
4001  }
4002  else if (region->alignment == RGN_ALIGN_LEFT) {
4003  region->alignment = RGN_ALIGN_RIGHT;
4004  }
4005  else if (region->alignment == RGN_ALIGN_RIGHT) {
4006  region->alignment = RGN_ALIGN_LEFT;
4007  }
4008 
4012 
4013  return OPERATOR_FINISHED;
4014 }
4015 
4017 {
4018  ScrArea *area = CTX_wm_area(C);
4019 
4020  /* Don't flip anything around in top-bar. */
4021  if (area && area->spacetype == SPACE_TOPBAR) {
4022  CTX_wm_operator_poll_msg_set(C, "Flipping regions in the Top-bar is not allowed");
4023  return 0;
4024  }
4025 
4026  return ED_operator_areaactive(C);
4027 }
4028 
4030 {
4031  /* identifiers */
4032  ot->name = "Flip Region";
4033  ot->idname = "SCREEN_OT_region_flip";
4034  ot->description = "Toggle the region's alignment (left/right or top/bottom)";
4035 
4036  /* api callbacks */
4039  ot->flag = 0;
4040 }
4041 
4044 /* -------------------------------------------------------------------- */
4048 /* show/hide header text menus */
4050 {
4051  ScrArea *area = CTX_wm_area(C);
4052 
4053  area->flag = area->flag ^ HEADER_NO_PULLDOWN;
4054 
4057 
4058  return OPERATOR_FINISHED;
4059 }
4060 
4062 {
4063  /* identifiers */
4064  ot->name = "Expand/Collapse Header Menus";
4065  ot->idname = "SCREEN_OT_header_toggle_menus";
4066  ot->description = "Expand or collapse the header pulldown menus";
4067 
4068  /* api callbacks */
4071  ot->flag = 0;
4072 }
4073 
4076 /* -------------------------------------------------------------------- */
4081 {
4082  ScrArea *area = CTX_wm_area(C);
4083  ARegion *region = CTX_wm_region(C);
4084  const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_TOP) ?
4085  IFACE_("Flip to Bottom") :
4086  IFACE_("Flip to Top");
4087  {
4088  PointerRNA ptr;
4089  RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, area->spacedata.first, &ptr);
4090  if (!ELEM(area->spacetype, SPACE_TOPBAR)) {
4091  uiItemR(layout, &ptr, "show_region_header", 0, IFACE_("Show Header"), ICON_NONE);
4092  }
4093 
4095  uiLayout *col = uiLayoutColumn(layout, 0);
4096  uiLayoutSetActive(col, (region_header->flag & RGN_FLAG_HIDDEN) == 0);
4097 
4099  uiItemR(col, &ptr, "show_region_tool_header", 0, IFACE_("Show Tool Settings"), ICON_NONE);
4100  }
4101 
4102  uiItemO(col,
4103  IFACE_("Show Menus"),
4104  (area->flag & HEADER_NO_PULLDOWN) ? ICON_CHECKBOX_DEHLT : ICON_CHECKBOX_HLT,
4105  "SCREEN_OT_header_toggle_menus");
4106  }
4107 
4108  /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
4110 
4111  if (!ELEM(area->spacetype, SPACE_TOPBAR)) {
4112  uiItemS(layout);
4113 
4114  uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
4115  }
4116 
4117  /* File browser should be fullscreen all the time, top-bar should
4118  * never be. But other regions can be maximized/restored. */
4119  if (!ELEM(area->spacetype, SPACE_FILE, SPACE_TOPBAR)) {
4120  uiItemS(layout);
4121 
4122  const char *but_str = area->full ? IFACE_("Tile Area") : IFACE_("Maximize Area");
4123  uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area");
4124  }
4125 }
4126 
4128 {
4129  ScrArea *area = CTX_wm_area(C);
4130  ARegion *region = CTX_wm_region(C);
4131  const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_TOP) ?
4132  IFACE_("Flip to Bottom") :
4133  IFACE_("Flip to Top");
4134  {
4135  PointerRNA ptr;
4136  RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, area->spacedata.first, &ptr);
4137  uiItemR(layout, &ptr, "show_region_footer", 0, IFACE_("Show Footer"), ICON_NONE);
4138  }
4139 
4140  /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
4142 
4143  uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
4144 
4145  /* File browser should be fullscreen all the time, top-bar should
4146  * never be. But other regions can be maximized/restored... */
4147  if (!ELEM(area->spacetype, SPACE_FILE, SPACE_TOPBAR)) {
4148  uiItemS(layout);
4149 
4150  const char *but_str = area->full ? IFACE_("Tile Area") : IFACE_("Maximize Area");
4151  uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area");
4152  }
4153 }
4154 
4156 {
4157  const ARegion *region = CTX_wm_region(C);
4158  const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_LEFT) ?
4159  IFACE_("Flip to Right") :
4160  IFACE_("Flip to Left");
4161 
4162  /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
4164 
4165  uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
4166 }
4167 
4168 static void ed_screens_statusbar_menu_create(uiLayout *layout, void *UNUSED(arg))
4169 {
4170  PointerRNA ptr;
4171 
4173  uiItemR(layout, &ptr, "show_statusbar_stats", 0, IFACE_("Scene Statistics"), ICON_NONE);
4174  uiItemR(layout, &ptr, "show_statusbar_memory", 0, IFACE_("System Memory"), ICON_NONE);
4175  if (GPU_mem_stats_supported()) {
4176  uiItemR(layout, &ptr, "show_statusbar_vram", 0, IFACE_("Video Memory"), ICON_NONE);
4177  }
4178  uiItemR(layout, &ptr, "show_statusbar_version", 0, IFACE_("Blender Version"), ICON_NONE);
4179 }
4180 
4182  wmOperator *UNUSED(op),
4183  const wmEvent *UNUSED(event))
4184 {
4185  const ScrArea *area = CTX_wm_area(C);
4186  const ARegion *region = CTX_wm_region(C);
4187 
4188  if (area && area->spacetype == SPACE_STATUSBAR) {
4189  uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Status Bar"), ICON_NONE);
4190  uiLayout *layout = UI_popup_menu_layout(pup);
4192  UI_popup_menu_end(C, pup);
4193  }
4194  else if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
4195  uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE);
4196  uiLayout *layout = UI_popup_menu_layout(pup);
4198  UI_popup_menu_end(C, pup);
4199  }
4200  else if (region->regiontype == RGN_TYPE_FOOTER) {
4201  uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Footer"), ICON_NONE);
4202  uiLayout *layout = UI_popup_menu_layout(pup);
4204  UI_popup_menu_end(C, pup);
4205  }
4206  else if (region->regiontype == RGN_TYPE_NAV_BAR) {
4207  uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Navigation Bar"), ICON_NONE);
4208  uiLayout *layout = UI_popup_menu_layout(pup);
4210  UI_popup_menu_end(C, pup);
4211  }
4212 
4213  return OPERATOR_INTERFACE;
4214 }
4215 
4217 {
4218  /* identifiers */
4219  ot->name = "Region Context Menu";
4220  ot->description = "Display region context menu";
4221  ot->idname = "SCREEN_OT_region_context_menu";
4222 
4223  /* api callbacks */
4225 }
4226 
4229 /* -------------------------------------------------------------------- */
4235  eRegionType regiontype)
4236 {
4237  return (regiontype == RGN_TYPE_WINDOW &&
4238  ELEM(spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) ||
4239  (spacetype == SPACE_CLIP && regiontype == RGN_TYPE_PREVIEW);
4240 }
4241 
4243  eRegionType regiontype,
4244  eScreen_Redraws_Flag redraws,
4245  bool from_anim_edit)
4246 {
4247  const eSpace_Type spacetype = area->spacetype;
4248  if (regiontype == RGN_TYPE_WINDOW) {
4249 
4250  switch (spacetype) {
4251  case SPACE_VIEW3D:
4252  if ((redraws & TIME_ALL_3D_WIN) || from_anim_edit) {
4253  return true;
4254  }
4255  break;
4256  case SPACE_GRAPH:
4257  case SPACE_NLA:
4258  if ((redraws & TIME_ALL_ANIM_WIN) || from_anim_edit) {
4259  return true;
4260  }
4261  break;
4262  case SPACE_ACTION:
4263  /* if only 1 window or 3d windows, we do timeline too
4264  * NOTE: Now we do action editor in all these cases, since timeline is here. */
4265  if ((redraws & (TIME_ALL_ANIM_WIN | TIME_REGION | TIME_ALL_3D_WIN)) || from_anim_edit) {
4266  return true;
4267  }
4268  break;
4269  case SPACE_PROPERTIES:
4270  if (redraws & TIME_ALL_BUTS_WIN) {
4271  return true;
4272  }
4273  break;
4274  case SPACE_SEQ:
4275  if ((redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) || from_anim_edit) {
4276  return true;
4277  }
4278  break;
4279  case SPACE_NODE:
4280  if (redraws & TIME_NODES) {
4281  return true;
4282  }
4283  break;
4284  case SPACE_IMAGE:
4285  if ((redraws & TIME_ALL_IMAGE_WIN) || from_anim_edit) {
4286  return true;
4287  }
4288  break;
4289  case SPACE_CLIP:
4290  if ((redraws & TIME_CLIPS) || from_anim_edit) {
4291  return true;
4292  }
4293  break;
4294  default:
4295  break;
4296  }
4297  }
4298  else if (regiontype == RGN_TYPE_UI) {
4299  if (spacetype == SPACE_CLIP) {
4300  /* Track Preview button is on Properties Editor in SpaceClip,
4301  * and it's very common case when users want it be refreshing
4302  * during playback, so asking people to enable special option
4303  * for this is a bit tricky, so add exception here for refreshing
4304  * Properties Editor for SpaceClip always */
4305  return true;
4306  }
4307 
4308  if (redraws & TIME_ALL_BUTS_WIN) {
4309  return true;
4310  }
4311  }
4312  else if (regiontype == RGN_TYPE_HEADER) {
4313  if (spacetype == SPACE_ACTION) {
4314  /* The timeline shows the current frame in the header. Other headers
4315  * don't need to be updated. */
4316  SpaceAction *saction = (SpaceAction *)area->spacedata.first;
4317  return saction->mode == SACTCONT_TIMELINE;
4318  }
4319  }
4320  else if (regiontype == RGN_TYPE_PREVIEW) {
4321  switch (spacetype) {
4322  case SPACE_SEQ:
4323  if (redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) {
4324  return true;
4325  }
4326  break;
4327  case SPACE_CLIP:
4328  return true;
4329  default:
4330  break;
4331  }
4332  }
4333  return false;
4334 }
4335 
4337  bContext *C, ScrArea *area, ARegion *region, const Scene *scene, eScreen_Redraws_Flag redraws)
4338 {
4339  /* Do follow time here if editor type supports it */
4340  if ((redraws & TIME_FOLLOW) &&
4342  float w = BLI_rctf_size_x(&region->v2d.cur);
4343  if (scene->r.cfra < region->v2d.cur.xmin) {
4344  region->v2d.cur.xmax = scene->r.cfra;
4345  region->v2d.cur.xmin = region->v2d.cur.xmax - w;
4346  ED_region_tag_redraw(region);
4347  return;
4348  }
4349  if (scene->r.cfra > region->v2d.cur.xmax) {
4350  region->v2d.cur.xmin = scene->r.cfra;
4351  region->v2d.cur.xmax = region->v2d.cur.xmin + w;
4352  ED_region_tag_redraw(region);
4353  return;
4354  }
4355  }
4356 
4357  /* No need to do a full redraw as the current frame indicator is only updated.
4358  * We do need to redraw when this area is in full screen as no other areas
4359  * will be tagged for redrawing. */
4360  if (region->regiontype == RGN_TYPE_WINDOW && !area->full) {
4361  if (ELEM(area->spacetype, SPACE_NLA, SPACE_ACTION)) {
4362  return;
4363  }
4364 
4365  /* Drivers Editor needs a full redraw on playback for graph_draw_driver_debug().
4366  * This will make it slower than regular graph editor during playback, but drawing this in
4367  * graph_main_region_draw_overlay() is not feasible because it requires animation filtering
4368  * which has significant overhead which needs to be avoided in the overlay which is redrawn on
4369  * every UI interaction. */
4370  if (area->spacetype == SPACE_GRAPH) {
4371  const SpaceGraph *sipo = area->spacedata.first;
4372  if (sipo->mode != SIPO_MODE_DRIVERS) {
4373  return;
4374  }
4375  bAnimContext ac;
4376  if (ANIM_animdata_get_context(C, &ac) == false) {
4377  return;
4378  }
4379  if (ac.datatype != ANIMCONT_DRIVERS) {
4380  return;
4381  }
4382  }
4383  }
4384  ED_region_tag_redraw(region);
4385 }
4386 
4387 //#define PROFILE_AUDIO_SYNCH
4388 
4390 {
4391  bScreen *screen = CTX_wm_screen(C);
4392  wmTimer *wt = screen->animtimer;
4393 
4394  if (!(wt && wt == event->customdata)) {
4395  return OPERATOR_PASS_THROUGH;
4396  }
4397 
4398  wmWindow *win = CTX_wm_window(C);
4399 
4400 #ifdef PROFILE_AUDIO_SYNCH
4401  static int old_frame = 0;
4402  int newfra_int;
4403 #endif
4404 
4405  Main *bmain = CTX_data_main(C);
4407  ViewLayer *view_layer = WM_window_get_active_view_layer(win);
4409  Scene *scene_eval = (depsgraph != NULL) ? DEG_get_evaluated_scene(depsgraph) : NULL;
4410  ScreenAnimData *sad = wt->customdata;
4412  int sync;
4413  double time;
4414 
4415  /* sync, don't sync, or follow scene setting */
4416  if (sad->flag & ANIMPLAY_FLAG_SYNC) {
4417  sync = 1;
4418  }
4419  else if (sad->flag & ANIMPLAY_FLAG_NO_SYNC) {
4420  sync = 0;
4421  }
4422  else {
4423  sync = (scene->flag & SCE_FRAME_DROP);
4424  }
4425 
4426  if (scene_eval == NULL) {
4427  /* Happens when undo/redo system is used during playback, nothing meaningful we can do here. */
4428  }
4429  else if (scene_eval->id.recalc & ID_RECALC_AUDIO_SEEK) {
4430  /* Ignore seek here, the audio will be updated to the scene frame after jump during next
4431  * dependency graph update. */
4432  }
4433  else if ((scene->audio.flag & AUDIO_SYNC) && (sad->flag & ANIMPLAY_FLAG_REVERSE) == false &&
4434  isfinite(time = BKE_sound_sync_scene(scene_eval))) {
4435  double newfra = time * FPS;
4436 
4437  /* give some space here to avoid jumps */
4438  if (newfra + 0.5 > scene->r.cfra && newfra - 0.5 < scene->r.cfra) {
4439  scene->r.cfra++;
4440  }
4441  else {
4442  scene->r.cfra = max_ii(scene->r.cfra, round(newfra));
4443  }
4444 
4445 #ifdef PROFILE_AUDIO_SYNCH
4446  newfra_int = scene->r.cfra;
4447  if (newfra_int < old_frame) {
4448  printf("back jump detected, frame %d!\n", newfra_int);
4449  }
4450  else if (newfra_int > old_frame + 1) {
4451  printf("forward jump detected, frame %d!\n", newfra_int);
4452  }
4453  fflush(stdout);
4454  old_frame = newfra_int;
4455 #endif
4456  }
4457  else {
4458  if (sync) {
4459  /* Try to keep the playback in realtime by dropping frames. */
4460 
4461  /* How much time (in frames) has passed since the last frame was drawn? */
4462  double delta_frames = wt->delta * FPS;
4463 
4464  /* Add the remaining fraction from the last time step. */
4465  delta_frames += sad->lagging_frame_count;
4466 
4467  if (delta_frames < 1.0) {
4468  /* We can render faster than the scene frame rate. However skipping or delaying frames
4469  * here seems to in practice lead to jittery playback so just step forward a minimum of
4470  * one frame. (Even though this can lead to too fast playback, the jitteryness is more
4471  * annoying)
4472  */
4473  delta_frames = 1.0f;
4474  sad->lagging_frame_count = 0;
4475  }
4476  else {
4477  /* Extract the delta frame fractions that will be skipped when converting to int. */
4478  sad->lagging_frame_count = delta_frames - (int)delta_frames;
4479  }
4480 
4481  const int step = delta_frames;
4482 
4483  /* skip frames */
4484  if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
4485  scene->r.cfra -= step;
4486  }
4487  else {
4488  scene->r.cfra += step;
4489  }
4490  }
4491  else {
4492  /* one frame +/- */
4493  if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
4494  scene->r.cfra--;
4495  }
4496  else {
4497  scene->r.cfra++;
4498  }
4499  }
4500  }
4501 
4502  /* reset 'jumped' flag before checking if we need to jump... */
4503  sad->flag &= ~ANIMPLAY_FLAG_JUMPED;
4504 
4505  if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
4506  /* jump back to end? */
4507  if (PRVRANGEON) {
4508  if (scene->r.cfra < scene->r.psfra) {
4509  scene->r.cfra = scene->r.pefra;
4510  sad->flag |= ANIMPLAY_FLAG_JUMPED;
4511  }
4512  }
4513  else {
4514  if (scene->r.cfra < scene->r.sfra) {
4515  scene->r.cfra = scene->r.efra;
4516  sad->flag |= ANIMPLAY_FLAG_JUMPED;
4517  }
4518  }
4519  }
4520  else {
4521  /* jump back to start? */
4522  if (PRVRANGEON) {
4523  if (scene->r.cfra > scene->r.pefra) {
4524  scene->r.cfra = scene->r.psfra;
4525  sad->flag |= ANIMPLAY_FLAG_JUMPED;
4526  }
4527  }
4528  else {
4529  if (scene->r.cfra > scene->r.efra) {
4530  scene->r.cfra = scene->r.sfra;
4531  sad->flag |= ANIMPLAY_FLAG_JUMPED;
4532  }
4533  }
4534  }
4535 
4536  /* next frame overridden by user action (pressed jump to first/last frame) */
4537  if (sad->flag & ANIMPLAY_FLAG_USE_NEXT_FRAME) {
4538  scene->r.cfra = sad->nextfra;
4540  sad->flag |= ANIMPLAY_FLAG_JUMPED;
4541  }
4542 
4543  if (sad->flag & ANIMPLAY_FLAG_JUMPED) {
4545 #ifdef PROFILE_AUDIO_SYNCH
4546  old_frame = CFRA;
4547 #endif
4548  }
4549 
4550  /* since we follow drawflags, we can't send notifier but tag regions ourselves */
4551  if (depsgraph != NULL) {
4553  }
4554 
4555  LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
4556  const bScreen *win_screen = WM_window_get_active_screen(window);
4557 
4558  LISTBASE_FOREACH (ScrArea *, area, &win_screen->areabase) {
4559  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
4560  bool redraw = false;
4561  if (region == sad->region) {
4562  redraw = true;
4563  }
4564  else if (match_region_with_redraws(
4565  area, region->regiontype, sad->redraws, sad->from_anim_edit)) {
4566  redraw = true;
4567  }
4568 
4569  if (redraw) {
4571  }
4572  }
4573  }
4574  }
4575 
4576  /* update frame rate info too
4577  * NOTE: this may not be accurate enough, since we might need this after modifiers/etc.
4578  * have been calculated instead of just before updates have been done?
4579  */
4581 
4582  /* Recalculate the time-step for the timer now that we've finished calculating this,
4583  * since the frames-per-second value may have been changed.
4584  */
4585  /* TODO: this may make evaluation a bit slower if the value doesn't change...
4586  * any way to avoid this? */
4587  wt->timestep = (1.0 / FPS);
4588 
4589  return OPERATOR_FINISHED;
4590 }
4591 
4593 {
4594  /* identifiers */
4595  ot->name = "Animation Step";
4596  ot->description = "Step through animation by position";
4597  ot->idname = "SCREEN_OT_animation_step";
4598 
4599  /* api callbacks */
4601 
4603 }
4604 
4607 /* -------------------------------------------------------------------- */
4613 /* find window that owns the animation timer */
4615 {
4616  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
4617  bScreen *screen = WM_window_get_active_screen(win);
4618 
4619  if (screen->animtimer || screen->scrubbing) {
4620  return screen;
4621  }
4622  }
4623 
4624  return NULL;
4625 }
4626 
4628 {
4629  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
4630  bScreen *screen = WM_window_get_active_screen(win);
4631 
4632  if (screen->animtimer) {
4633  return screen;
4634  }
4635  }
4636 
4637  return NULL;
4638 }
4639 
4640 /* toggle operator */
4641 int ED_screen_animation_play(bContext *C, int sync, int mode)
4642 {
4643  bScreen *screen = CTX_wm_screen(C);
4646 
4648  /* stop playback now */
4649  ED_screen_animation_timer(C, 0, 0, 0);
4650  BKE_sound_stop_scene(scene_eval);
4651 
4653  }
4654  else {
4655  /* these settings are currently only available from a menu in the TimeLine */
4656  if (mode == 1) { /* XXX only play audio forwards!? */
4657  BKE_sound_play_scene(scene_eval);
4658  }
4659 
4660  ED_screen_animation_timer(C, screen->redraws_flag, sync, mode);
4661 
4662  if (screen->animtimer) {
4663  wmTimer *wt = screen->animtimer;
4664  ScreenAnimData *sad = wt->customdata;
4665 
4666  sad->region = CTX_wm_region(C);
4667  }
4668  }
4669 
4670  return OPERATOR_FINISHED;
4671 }
4672 
4674 {
4675  int mode = (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
4676  int sync = -1;
4677 
4678  if (RNA_struct_property_is_set(op->ptr, "sync")) {
4679  sync = (RNA_boolean_get(op->ptr, "sync"));
4680  }
4681 
4682  return ED_screen_animation_play(C, sync, mode);
4683 }
4684 
4686 {
4687  PropertyRNA *prop;
4688 
4689  /* identifiers */
4690  ot->name = "Play Animation";
4691  ot->description = "Play animation";
4692  ot->idname = "SCREEN_OT_animation_play";
4693 
4694  /* api callbacks */
4696 
4698 
4699  prop = RNA_def_boolean(
4700  ot->srna, "reverse", 0, "Play in Reverse", "Animation is played backwards");
4702  prop = RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate");
4704 }
4705 
4708 /* -------------------------------------------------------------------- */
4713 {
4715 
4716  if (screen) {
4717  if (RNA_boolean_get(op->ptr, "restore_frame") && screen->animtimer) {
4718  ScreenAnimData *sad = screen->animtimer->customdata;
4720 
4721  /* reset current frame before stopping, and just send a notifier to deal with the rest
4722  * (since playback still needs to be stopped)
4723  */
4724  scene->r.cfra = sad->sfra;
4725 
4727  }
4728 
4729  /* call the other "toggling" operator to clean up now */
4730  ED_screen_animation_play(C, 0, 0);
4731  }
4732 
4733  return OPERATOR_PASS_THROUGH;
4734 }
4735 
4737 {
4738  /* identifiers */
4739  ot->name = "Cancel Animation";
4740  ot->description = "Cancel animation, returning to the original frame";
4741  ot->idname = "SCREEN_OT_animation_cancel";
4742 
4743  /* api callbacks */
4745 
4747 
4749  "restore_frame",
4750  true,
4751  "Restore Frame",
4752  "Restore the frame when animation was initialized");
4753 }
4754 
4757 /* -------------------------------------------------------------------- */
4761 /* operator state vars used: (added by default WM callbacks)
4762  * xmin, ymin
4763  * xmax, ymax
4764  *
4765  * customdata: the wmGesture pointer
4766  *
4767  * callbacks:
4768  *
4769  * exec() has to be filled in by user
4770  *
4771  * invoke() default WM function
4772  * adds modal handler
4773  *
4774  * modal() default WM function
4775  * accept modal events while doing it, calls exec(), handles ESC and border drawing
4776  *
4777  * poll() has to be filled in by user for context
4778  */
4779 #if 0
4780 static int box_select_exec(bContext *C, wmOperator *op)
4781 {
4782  int event_type = RNA_int_get(op->ptr, "event_type");
4783 
4784  if (event_type == LEFTMOUSE) {
4785  printf("box select do select\n");
4786  }
4787  else if (event_type == RIGHTMOUSE) {
4788  printf("box select deselect\n");
4789  }
4790  else {
4791  printf("box select do something\n");
4792  }
4793 
4794  return 1;
4795 }
4796 
4797 static void SCREEN_OT_box_select(wmOperatorType *ot)
4798 {
4799  /* identifiers */
4800  ot->name = "Box Select";
4801  ot->idname = "SCREEN_OT_box_select";
4802 
4803  /* api callbacks */
4804  ot->exec = box_select_exec;
4808 
4810 
4811  /* rna */
4812  RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
4814 }
4815 #endif
4816 
4819 /* -------------------------------------------------------------------- */
4826 {
4827  bScreen *screen = CTX_wm_screen(C);
4828  ScrArea *area = NULL;
4829 
4830  /* search current screen for 'fullscreen' areas */
4831  LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) {
4832  if (area_iter->full) {
4833  area = area_iter;
4834  break;
4835  }
4836  }
4837  if (!area) {
4838  BKE_report(op->reports, RPT_ERROR, "No fullscreen areas were found");
4839  return OPERATOR_CANCELLED;
4840  }
4841 
4843 
4844  return OPERATOR_FINISHED;
4845 }
4846 
4848 {
4849  /* identifiers */
4850  ot->name = "Back to Previous Screen";
4851  ot->description = "Revert back to the original screen layout, before fullscreen area overlay";
4852  ot->idname = "SCREEN_OT_back_to_previous";
4853 
4854  /* api callbacks */
4857 }
4858 
4861 /* -------------------------------------------------------------------- */
4866 {
4867  wmWindow *win_cur = CTX_wm_window(C);
4868  /* Use eventstate, not event from _invoke, so this can be called through exec(). */
4869  const wmEvent *event = win_cur->eventstate;
4870  int sizex = (500 + UI_NAVIGATION_REGION_WIDTH) * UI_DPI_FAC;
4871  int sizey = 520 * UI_DPI_FAC;
4872 
4873  /* changes context! */
4874  if (WM_window_open(C,
4875  IFACE_("Blender Preferences"),
4876  event->x,
4877  event->y,
4878  sizex,
4879  sizey,
4881  false,
4882  true,
4884  /* The header only contains the editor switcher and looks empty.
4885  * So hiding in the temp window makes sense. */
4886  ScrArea *area = CTX_wm_area(C);
4888 
4889  region->flag |= RGN_FLAG_HIDDEN;
4891 
4892  /* And also show the region with "Load & Save" buttons. */
4894  region->flag &= ~RGN_FLAG_HIDDEN;
4896 
4897  return OPERATOR_FINISHED;
4898  }
4899  BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
4900  return OPERATOR_CANCELLED;
4901 }
4902 
4904 {
4905  /* identifiers */
4906  ot->name = "Show Preferences";
4907  ot->description = "Edit user preferences and system settings";
4908  ot->idname = "SCREEN_OT_userpref_show";
4909 
4910  /* api callbacks */
4912  ot->poll = ED_operator_screenactive_nobackground; /* Not in background as this opens a window. */
4913 }
4914 
4917 /* -------------------------------------------------------------------- */
4922 {
4923  wmWindow *win_cur = CTX_wm_window(C);
4924  /* Use eventstate, not event from _invoke, so this can be called through exec(). */
4925  const wmEvent *event = win_cur->eventstate;
4926 
4927  int sizex = 900 * UI_DPI_FAC;
4928  int sizey = 580 * UI_DPI_FAC;
4929 
4930  /* Get active property to show driver for
4931  * - Need to grab it first, or else this info disappears
4932  * after we've created the window
4933  */
4934  int index;
4935  PointerRNA ptr;
4936  PropertyRNA *prop;
4937  uiBut *but = UI_context_active_but_prop_get(C, &ptr, &prop, &index);
4938 
4939  /* changes context! */
4940  if (WM_window_open(C,
4941  IFACE_("Blender Drivers Editor"),
4942  event->x,
4943  event->y,
4944  sizex,
4945  sizey,
4946  SPACE_GRAPH,
4947  false,
4948  true,
4951 
4952  /* activate driver F-Curve for the property under the cursor */
4953  if (but) {
4954  bool driven, special;
4956  C, &ptr, prop, index, NULL, NULL, &driven, &special);
4957 
4958  if (fcu) {
4959  /* Isolate this F-Curve... */
4960  bAnimContext ac;
4961  if (ANIM_animdata_get_context(C, &ac)) {
4965  }
4966  else {
4967  /* Just blindly isolate...
4968  * This isn't the best, and shouldn't happen, but may be enough. */
4969  fcu->flag |= (FCURVE_ACTIVE | FCURVE_SELECTED);
4970  }
4971  }
4972  }
4973 
4974  return OPERATOR_FINISHED;
4975  }
4976  BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
4977  return OPERATOR_CANCELLED;
4978 }
4979 
4981 {
4982  /* identifiers */
4983  ot->name = "Show Drivers Editor";
4984  ot->description = "Show drivers editor in a separate window";
4985  ot->idname = "SCREEN_OT_drivers_editor_show";
4986 
4987  /* api callbacks */
4989  ot->poll = ED_operator_screenactive_nobackground; /* Not in background as this opens a window. */
4990 }
4991 
4994 /* -------------------------------------------------------------------- */
4999 {
5000  wmWindow *win_cur = CTX_wm_window(C);
5001  /* Use eventstate, not event from _invoke, so this can be called through exec(). */
5002  const wmEvent *event = win_cur->eventstate;
5003  int sizex = 900 * UI_DPI_FAC;
5004  int sizey = 580 * UI_DPI_FAC;
5005  int shift_y = 480;
5006 
5007  /* changes context! */
5008  if (WM_window_open(C,
5009  IFACE_("Blender Info Log"),
5010  event->x,
5011  event->y + shift_y,
5012  sizex,
5013  sizey,
5014  SPACE_INFO,
5015  false,
5016  true,
5018  return OPERATOR_FINISHED;
5019  }
5020  BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
5021  return OPERATOR_CANCELLED;
5022 }
5023 
5025 {
5026  /* identifiers */
5027  ot->name = "Show Info Log";
5028  ot->description = "Show info log in a separate window";
5029  ot->idname = "SCREEN_OT_info_log_show";
5030 
5031  /* api callbacks */
5034 }
5035 
5038 /* -------------------------------------------------------------------- */
5043 {
5044  Main *bmain = CTX_data_main(C);
5045  wmWindow *win = CTX_wm_window(C);
5048 
5049  WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win);
5050 
5052 
5053  return OPERATOR_FINISHED;
5054 }
5055 
5057 {
5058  /* identifiers */
5059  ot->name = "New Screen";
5060  ot->description = "Add a new screen";
5061  ot->idname = "SCREEN_OT_new";
5062 
5063  /* api callbacks */
5064  ot->exec = screen_new_exec;
5066 }
5067 
5070 /* -------------------------------------------------------------------- */
5075 {
5076  bScreen *screen = CTX_wm_screen(C);
5077  WorkSpace *workspace = CTX_wm_workspace(C);
5078  WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, screen);
5079 
5081 
5082  return OPERATOR_FINISHED;
5083 }
5084 
5086 {
5087  /* identifiers */
5088  ot->name = "Delete Screen";
5089  ot->description = "Delete active screen";
5090  ot->idname = "SCREEN_OT_delete";
5091 
5092  /* api callbacks */
5094 }
5095 
5098 /* -------------------------------------------------------------------- */
5107 typedef struct RegionAlphaInfo {
5109  ARegion *region, *child_region; /* other region */
5110  int hidden;
5112 
5113 #define TIMEOUT 0.1f
5114 #define TIMESTEP (1.0f / 60.0f)
5115 
5117 {
5118  /* check parent too */
5119  if (region->regiontimer == NULL && (region->alignment & RGN_SPLIT_PREV) && region->prev) {
5120  region = region->prev;
5121  }
5122 
5123  if (region->regiontimer) {
5124  RegionAlphaInfo *rgi = region->regiontimer->customdata;
5125  float alpha;
5126 
5127  alpha = (float)region->regiontimer->duration / TIMEOUT;
5128  /* makes sure the blend out works 100% - without area redraws */
5129  if (rgi->hidden) {
5130  alpha = 0.9f - TIMESTEP - alpha;
5131  }
5132 
5133  CLAMP(alpha, 0.0f, 1.0f);
5134  return alpha;
5135  }
5136  return 1.0f;
5137 }
5138 
5139 /* assumes region has running region-blend timer */
5140 static void region_blend_end(bContext *C, ARegion *region, const bool is_running)
5141 {
5142  RegionAlphaInfo *rgi = region->regiontimer->customdata;
5143 
5144  /* always send redraw */
5145  ED_region_tag_redraw(region);
5146  if (rgi->child_region) {
5148  }
5149 
5150  /* if running timer was hiding, the flag toggle went wrong */
5151  if (is_running) {
5152  if (rgi->hidden) {
5153  rgi->region->flag &= ~RGN_FLAG_HIDDEN;
5154  }
5155  }
5156  else {
5157  if (rgi->hidden) {
5158  rgi->region->flag |= rgi->hidden;
5160  }
5161  /* area decoration needs redraw in end */
5162  ED_area_tag_redraw(rgi->area);
5163  }
5164  WM_event_remove_timer(CTX_wm_manager(C), NULL, region->regiontimer); /* frees rgi */
5165  region->regiontimer = NULL;
5166 }
5171 {
5173  wmWindow *win = CTX_wm_window(C);
5174 
5175  /* end running timer */
5176  if (region->regiontimer) {
5177 
5178  region_blend_end(C, region, true);
5179  }
5180  RegionAlphaInfo *rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo");
5181 
5182  rgi->hidden = region->flag & RGN_FLAG_HIDDEN;
5183  rgi->area = area;
5184  rgi->region = region;
5185  region->flag &= ~RGN_FLAG_HIDDEN;
5186 
5187  /* blend in, reinitialize regions because it got unhidden */
5188  if (rgi->hidden == 0) {
5189  ED_area_init(wm, win, area);
5190  }
5191  else {
5192  WM_event_remove_handlers(C, &region->handlers);
5193  }
5194 
5195  if (region->next) {
5196  if (region->next->alignment & RGN_SPLIT_PREV) {
5197  rgi->child_region = region->next;
5198  }
5199  }
5200 
5201  /* new timer */
5202  region->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP);
5203  region->regiontimer->customdata = rgi;
5204 }
5205 
5206 /* timer runs in win->handlers, so it cannot use context to find area/region */
5207 static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
5208 {
5209  wmTimer *timer = event->customdata;
5210 
5211  /* event type is TIMERREGION, but we better check */
5212  if (event->type != TIMERREGION || timer == NULL) {
5213  return OPERATOR_PASS_THROUGH;
5214  }
5215 
5216  RegionAlphaInfo *rgi = timer->customdata;
5217 
5218  /* always send redraws */
5220  if (rgi->child_region) {
5222  }
5223 
5224  /* end timer? */
5225  if (rgi->region->regiontimer->duration > (double)TIMEOUT) {
5226  region_blend_end(C, rgi->region, false);
5228  }
5229 
5231 }
5232 
5234 {
5235  /* identifiers */
5236  ot->name = "Region Alpha";
5237  ot->idname = "SCREEN_OT_region_blend";
5238  ot->description = "Blend in and out overlapping region";
5239 
5240  /* api callbacks */
5242 
5243  /* flags */
5244  ot->flag = OPTYPE_INTERNAL;
5245 
5246  /* properties */
5247 }
5248 
5251 /* -------------------------------------------------------------------- */
5256 {
5257  ScrArea *area = CTX_wm_area(C);
5258  return (area && !ELEM(area->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR));
5259 }
5260 
5262 {
5263  const int space_type = RNA_enum_get(op->ptr, "space_type");
5264 
5265  PointerRNA ptr;
5266  ScrArea *area = CTX_wm_area(C);
5268  PropertyRNA *prop_type = RNA_struct_find_property(&ptr, "type");
5269  PropertyRNA *prop_ui_type = RNA_struct_find_property(&ptr, "ui_type");
5270 
5271  if (area->spacetype != space_type) {
5272  /* Set the type. */
5273  RNA_property_enum_set(&ptr, prop_type, space_type);
5274  RNA_property_update(C, &ptr, prop_type);
5275  }
5276  else {
5277  /* Types match, cycle the subtype. */
5278  const int space_type_ui = RNA_property_enum_get(&ptr, prop_ui_type);
5279  const EnumPropertyItem *item;
5280  int item_len;
5281  bool free;
5282  RNA_property_enum_items(C, &ptr, prop_ui_type, &item, &item_len, &free);
5283  int index = RNA_enum_from_value(item, space_type_ui);
5284  for (int i = 1; i < item_len; i++) {
5285  const EnumPropertyItem *item_test = &item[(index + i) % item_len];
5286  if ((item_test->value >> 16) == space_type) {
5287  RNA_property_enum_set(&ptr, prop_ui_type, item_test->value);
5288  RNA_property_update(C, &ptr, prop_ui_type);
5289  break;
5290  }
5291  }
5292  if (free) {
5293  MEM_freeN((void *)item);
5294  }
5295  }
5296 
5297  return OPERATOR_FINISHED;
5298 }
5299 
5301 {
5302  /* identifiers */
5303  ot->name = "Cycle Space Type Set";
5304  ot->description = "Set the space type or cycle subtype";
5305  ot->idname = "SCREEN_OT_space_type_set_or_cycle";
5306 
5307  /* api callbacks */
5310 
5311  ot->flag = 0;
5312 
5313  RNA_def_enum(ot->srna, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Type", "");
5314 }
5315 
5318 /* -------------------------------------------------------------------- */
5323  {SPACE_CONTEXT_CYCLE_PREV, "PREV", 0, "Previous", ""},
5324  {SPACE_CONTEXT_CYCLE_NEXT, "NEXT", 0, "Next", ""},
5325  {0, NULL, 0, NULL, NULL},
5326 };
5327 
5329 {
5330  ScrArea *area = CTX_wm_area(C);
5331  /* area might be NULL if called out of window bounds */
5332  return (area && ELEM(area->spacetype, SPACE_PROPERTIES, SPACE_USERPREF));
5333 }
5334 
5339 static void context_cycle_prop_get(bScreen *screen,
5340  const ScrArea *area,
5341  PointerRNA *r_ptr,
5342  PropertyRNA **r_prop)
5343 {
5344  const char *propname;
5345 
5346  switch (area->spacetype) {
5347  case SPACE_PROPERTIES:
5348  RNA_pointer_create(&screen->id, &RNA_SpaceProperties, area->spacedata.first, r_ptr);
5349  propname = "context";
5350  break;
5351  case SPACE_USERPREF:
5353  propname = "active_section";
5354  break;
5355  default:
5356  BLI_assert(0);
5357  propname = "";
5358  }
5359 
5360  *r_prop = RNA_struct_find_property(r_ptr, propname);
5361 }
5362 
5364 {
5365  const int direction = RNA_enum_get(op->ptr, "direction");
5366 
5367  PointerRNA ptr;
5368  PropertyRNA *prop;
5370  const int old_context = RNA_property_enum_get(&ptr, prop);
5371  const int new_context = RNA_property_enum_step(
5372  C, &ptr, prop, old_context, direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1);
5373  RNA_property_enum_set(&ptr, prop, new_context);
5374  RNA_property_update(C, &ptr, prop);
5375 
5376  return OPERATOR_FINISHED;
5377 }
5378 
5380 {
5381  /* identifiers */
5382  ot->name = "Cycle Space Context";
5383  ot->description = "Cycle through the editor context by activating the next/previous one";
5384  ot->idname = "SCREEN_OT_space_context_cycle";
5385 
5386  /* api callbacks */
5389 
5390  ot->flag = 0;
5391 
5392  RNA_def_enum(ot->srna,
5393  "direction",
5396  "Direction",
5397  "Direction to cycle through");
5398 }
5399 
5402 /* -------------------------------------------------------------------- */
5407 {
5408  wmWindow *win = CTX_wm_window(C);
5409  if (WM_window_is_temp_screen(win)) {
5410  return OPERATOR_CANCELLED;
5411  }
5412 
5413  Main *bmain = CTX_data_main(C);
5414  const int direction = RNA_enum_get(op->ptr, "direction");
5415  WorkSpace *workspace_src = WM_window_get_active_workspace(win);
5416  WorkSpace *workspace_dst = NULL;
5417 
5418  ListBase ordered;
5419  BKE_id_ordered_list(&ordered, &bmain->workspaces);
5420 
5421  LISTBASE_FOREACH (LinkData *, link, &ordered) {
5422  if (link->data == workspace_src) {
5423  if (direction == SPACE_CONTEXT_CYCLE_PREV) {
5424  workspace_dst = (link->prev) ? link->prev->data : NULL;
5425  }
5426  else {
5427  workspace_dst = (link->next) ? link->next->data : NULL;
5428  }
5429  }
5430  }
5431 
5432  if (workspace_dst == NULL) {
5433  LinkData *link = (direction == SPACE_CONTEXT_CYCLE_PREV) ? ordered.last : ordered.first;
5434  workspace_dst = link->data;
5435  }
5436 
5437  BLI_freelistN(&ordered);
5438 
5439  if (workspace_src == workspace_dst) {
5440  return OPERATOR_CANCELLED;
5441  }
5442 
5443  win->workspace_hook->temp_workspace_store = workspace_dst;
5446 
5447  return OPERATOR_FINISHED;
5448 }
5449 
5451 {
5452  /* identifiers */
5453  ot->name = "Cycle Workspace";
5454  ot->description = "Cycle through workspaces";
5455  ot->idname = "SCREEN_OT_workspace_cycle";
5456 
5457  /* api callbacks */
5460 
5461  ot->flag = 0;
5462 
5463  RNA_def_enum(ot->srna,
5464  "direction",
5467  "Direction",
5468  "Direction to cycle through");
5469 }
5470 
5473 /* -------------------------------------------------------------------- */
5477 /* called in spacetypes.c */
5479 {
5480  /* generic UI stuff */
5485 
5486  /* screen tools */
5511 
5512  /*frame changes*/
5517 
5521 
5522  /* new/delete */
5525 }
5526 
5529 /* -------------------------------------------------------------------- */
5533 static void keymap_modal_set(wmKeyConfig *keyconf)
5534 {
5535  static const EnumPropertyItem modal_items[] = {
5536  {KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
5537  {KM_MODAL_APPLY, "APPLY", 0, "Apply", ""},
5538  {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap On", ""},
5539  {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap Off", ""},
5540  {0, NULL, 0, NULL, NULL},
5541  };
5542 
5543  /* Standard Modal keymap ------------------------------------------------ */
5544  wmKeyMap *keymap = WM_modalkeymap_ensure(keyconf, "Standard Modal Map", modal_items);
5545 
5546  WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");
5547 }
5548 
5550  wmDrag *drag,
5551  const wmEvent *UNUSED(event),
5552  const char **UNUSED(r_tooltip))
5553 {
5554  if (drag->type == WM_DRAG_PATH) {
5555  if (drag->icon == ICON_FILE_BLEND) {
5556  return true;
5557  }
5558  }
5559  return false;
5560 }
5561 
5562 static void blend_file_drop_copy(wmDrag *drag, wmDropBox *drop)
5563 {
5564  /* copy drag path to properties */
5565  RNA_string_set(drop->ptr, "filepath", drag->path);
5566 }
5567 
5568 /* called in spacetypes.c */
5570 {
5571  /* Screen Editing ------------------------------------------------ */
5572  WM_keymap_ensure(keyconf, "Screen Editing", 0, 0);
5573 
5574  /* Screen General ------------------------------------------------ */
5575  WM_keymap_ensure(keyconf, "Screen", 0, 0);
5576 
5577  /* Anim Playback ------------------------------------------------ */
5578  WM_keymap_ensure(keyconf, "Frames", 0, 0);
5579 
5580  /* dropbox for entire window */
5581  ListBase *lb = WM_dropboxmap_find("Window", 0, 0);
5582  WM_dropbox_add(lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy, NULL);
5583  WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy, NULL);
5584 
5585  keymap_modal_set(keyconf);
5586 }
5587 
typedef float(TangentPoint)[2]
struct WorkSpace * CTX_wm_workspace(const bContext *C)
Definition: context.c:704
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:985
struct SpaceNode * CTX_wm_space_node(const bContext *C)
Definition: context.c:854
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1296
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct Mask * CTX_data_edit_mask(const bContext *C)
Definition: context.c:1316
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
Definition: context.c:456
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct SpaceLink * CTX_wm_space_data(const bContext *C)
Definition: context.c:719
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:973
void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg)
Definition: context.c:1006
struct SpaceImage * CTX_wm_space_image(const bContext *C)
Definition: context.c:800
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
struct FCurve * BKE_fcurve_find_by_rna_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct AnimData **r_animdata, struct bAction **r_action, bool *r_driven, bool *r_special)
Definition: fcurve.c:390
@ G_TRANSFORM_WM
Definition: BKE_global.h:222
void BKE_icon_changed(const int icon_id)
Definition: icons.cc:678
void BKE_id_ordered_list(struct ListBase *ordered_lb, const struct ListBase *lb)
struct MaskLayer * BKE_mask_layer_active(struct Mask *mask)
Definition: mask.c:376
General operations, lookup, etc. for blender objects.
struct Object * BKE_object_pose_armature_get(struct Object *ob)
Definition: object.c:2487
bool BKE_object_pose_context_check(const struct Object *ob)
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
struct Depsgraph * BKE_scene_get_depsgraph(const struct Scene *scene, const struct ViewLayer *view_layer)
struct ScrArea * BKE_screen_find_area_xy(struct bScreen *screen, const int spacetype, int x, int y)
Definition: screen.c:1018
struct ARegion * BKE_area_find_region_type(const struct ScrArea *area, int type)
struct ScrEdge * BKE_screen_find_edge(const struct bScreen *screen, struct ScrVert *v1, struct ScrVert *v2)
void BKE_screen_remove_double_scredges(struct bScreen *screen)
Definition: screen.c:817
void BKE_spacedata_freelist(ListBase *lb)
Definition: screen.c:440
void BKE_screen_remove_unused_scrverts(struct bScreen *screen)
Definition: screen.c:878
void BKE_screen_remove_unused_scredges(struct bScreen *screen)
Definition: screen.c:833
struct ARegion * BKE_area_region_copy(const struct SpaceType *st, const struct ARegion *region)
void BKE_screen_remove_double_scrverts(struct bScreen *screen)
Definition: screen.c:765
double BKE_sound_sync_scene(struct Scene *scene)
void BKE_sound_stop_scene(struct Scene *scene)
void BKE_sound_play_scene(struct Scene *scene)
struct WorkSpace * BKE_workspace_active_get(struct WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition: workspace.c:535
struct WorkSpaceLayout * BKE_workspace_active_layout_get(const struct WorkSpaceInstanceHook *hook) GETTER_ATTRS
struct WorkSpaceLayout * BKE_workspace_layout_find(const struct WorkSpace *workspace, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_dlrbTree_init(DLRBT_Tree *tree)
Definition: DLRB_tree.c:40
void BLI_dlrbTree_free(DLRBT_Tree *tree)
Definition: DLRB_tree.c:66
DLRBT_Node * BLI_dlrbTree_search_next(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
Definition: DLRB_tree.c:256
DLRBT_Node * BLI_dlrbTree_search_prev(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
Definition: DLRB_tree.c:225
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
MINLINE int square_i(int a)
MINLINE int max_ii(int a, int b)
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:52
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2]) ATTR_WARN_UNUSED_RESULT
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition: rct.c:446
int BLI_rcti_length_x(const rcti *rect, const int x)
Definition: rct.c:174
int BLI_rcti_length_y(const rcti *rect, const int y)
Definition: rct.c:185
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
#define ARRAY_SIZE(arr)
#define SWAP(type, a, b)
#define UNUSED(x)
#define ELEM(...)
#define IS_EQF(a, b)
#define IN_RANGE_INCL(a, b, c)
#define IFACE_(msgid)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ ID_RECALC_AUDIO_SEEK
Definition: DNA_ID.h:660
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:445
@ ADS_FILTER_ONLYSEL
@ SACTCONT_TIMELINE
@ FCURVE_ACTIVE
@ FCURVE_SELECTED
@ CU_3D
@ ME_AUTOSMOOTH
#define OB_MODE_ALL_WEIGHT_PAINT
@ OB_MODE_EDIT
@ OB_MODE_OBJECT
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVE
@ OB_GPENCIL
@ OB_RESTRICT_VIEWPORT
#define OBEDIT_FROM_VIEW_LAYER(view_layer)
#define SUBFRA
#define CFRA
#define PSFRA
#define SCE_KEYS_NO_SELONLY
#define AUDIO_SYNC
#define FPS
#define SCE_FRAME_DROP
#define PRVRANGEON
#define PEFRA
#define RGN_ALIGN_ENUM_FROM_MASK(align)
@ RGN_ALIGN_BOTTOM
@ RGN_ALIGN_LEFT
@ RGN_ALIGN_TOP
@ RGN_ALIGN_RIGHT
@ RGN_SPLIT_PREV
@ RGN_ALIGN_NONE
@ RGN_ALIGN_QSPLIT
#define AREAMAP_FROM_SCREEN(screen)
#define AREAMINX
@ SCREENFULL
@ SCREENMAXIMIZED
@ SCREENNORMAL
@ AREA_FLAG_ACTIONZONES_UPDATE
@ HEADER_NO_PULLDOWN
@ RGN_FLAG_DYNAMIC_SIZE
@ RGN_FLAG_HIDDEN
@ RGN_FLAG_TOO_SMALL
@ RGN_FLAG_HIDDEN_BY_USER
eScreen_Redraws_Flag
@ TIME_SEQ
@ TIME_ALL_IMAGE_WIN
@ TIME_ALL_BUTS_WIN
@ TIME_FOLLOW
@ TIME_REGION
@ TIME_ALL_3D_WIN
@ TIME_CLIPS
@ TIME_NODES
@ TIME_ALL_ANIM_WIN
eRegionType
@ RGN_TYPE_TOOL_HEADER
@ RGN_TYPE_EXECUTE
@ RGN_TYPE_UI
@ RGN_TYPE_WINDOW
@ RGN_TYPE_PREVIEW
@ RGN_TYPE_NAV_BAR
@ RGN_TYPE_FOOTER
@ RGN_TYPE_HEADER
#define AREAGRID
eSpace_Type
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_CONSOLE
@ SPACE_OUTLINER
@ SPACE_STATUSBAR
@ SPACE_TOPBAR
@ SPACE_NODE
@ SPACE_USERPREF
@ SPACE_FILE
@ SPACE_PROPERTIES
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_EMPTY
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ SPACE_INFO
@ SIPO_MODE_DRIVERS
#define SPACE_TYPE_ANY
#define FRAMENUMBER_MIN_CLAMP(cfra)
@ V2D_KEEPTOT_STRICT
@ V2D_SCROLL_HORIZONTAL
@ V2D_SCROLL_VERTICAL
#define RV3D_GPULIGHT_UPDATE
#define RV3D_VIEW_CAMERA
#define RV3D_CAMOB
#define RV3D_VIEWLOCK_INIT
@ RV3D_LOCK_ROTATION
@ RV3D_BOXCLIP
#define RV3D_PERSP
@ RV3D_VIEW_AXIS_ROLL_0
#define RV3D_VIEW_USER
#define RV3D_ORTHO
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
@ ACHANNEL_SETFLAG_CLEAR
Definition: ED_anim_api.h:508
void ED_drivers_editor_init(struct bContext *C, struct ScrArea *area)
Definition: graph_utils.c:55
@ ANIMTYPE_FCURVE
Definition: ED_anim_api.h:207
@ ANIMCONT_DRIVERS
Definition: ED_anim_api.h:122
@ ANIMFILTER_DATA_VISIBLE
Definition: ED_anim_api.h:295
@ ANIMFILTER_NODUPLIS
Definition: ED_anim_api.h:328
bool ED_space_clip_check_show_maskedit(struct SpaceClip *sc)
Definition: clip_editor.c:557
bool ED_space_image_check_show_maskedit(struct SpaceImage *sima, struct Object *obedit)
Definition: image_edit.c:484
bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit)
Definition: image_edit.c:460
struct Mesh * ED_mesh_context(struct bContext *C)
Definition: mesh_data.c:1360
struct Object * ED_object_active_context(const struct bContext *C)
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:745
void ED_screen_global_areas_sync(struct wmWindow *win)
Definition: screen_edit.c:945
void ED_region_visibility_change_update(struct bContext *C, struct ScrArea *area, struct ARegion *region)
Definition: area.c:2032
void ED_screen_full_prevspace(struct bContext *C, ScrArea *area)
Definition: screen_edit.c:1168
int ED_area_global_min_size_y(const ScrArea *area)
Definition: area.c:3382
void ED_screen_draw_split_preview(struct ScrArea *area, const int dir, const float fac)
Definition: screen_draw.c:476
#define ED_screen_verts_iter(win, screen, vert_name)
Definition: ED_screen.h:192
struct ScrArea * ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *area, const short state)
Definition: screen_edit.c:1324
#define ED_screen_areas_iter(win, screen, area_name)
Definition: ED_screen.h:189
void ED_region_remove(struct bContext *C, struct ScrArea *area, struct ARegion *region)
Definition: screen_edit.c:563
void ED_area_tag_redraw_no_rebuild(ScrArea *area)
Definition: area.c:754
int ED_area_global_max_size_y(const ScrArea *area)
Definition: area.c:3387
void ED_region_toggle_hidden(struct bContext *C, struct ARegion *region)
Definition: area.c:2059
void ED_screen_animation_timer(struct bContext *C, int redraws, int sync, int enable)
Definition: screen_edit.c:1517
int ED_area_headersize(void)
Definition: area.c:3363
bool ED_area_is_global(const ScrArea *area)
Definition: area.c:3393
void ED_region_tag_redraw_no_rebuild(struct ARegion *region)
Definition: area.c:686
void ED_refresh_viewport_fps(struct bContext *C)
Definition: screen_edit.c:1486
struct WorkSpaceLayout * ED_workspace_layout_duplicate(struct Main *bmain, struct WorkSpace *workspace, const struct WorkSpaceLayout *layout_old, struct wmWindow *win) ATTR_NONNULL()
@ SPACE_CONTEXT_CYCLE_NEXT
Definition: ED_screen.h:455
@ SPACE_CONTEXT_CYCLE_PREV
Definition: ED_screen.h:454
void ED_update_for_newframe(struct Main *bmain, struct Depsgraph *depsgraph)
Definition: screen_edit.c:1617
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:667
void ED_screen_draw_join_shape(struct ScrArea *sa1, struct ScrArea *sa2)
Definition: screen_draw.c:435
bool ED_workspace_layout_cycle(struct WorkSpace *workspace, const short direction, struct bContext *C) ATTR_NONNULL()
void ED_area_init(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area)
Definition: area.c:1906
void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2)
Definition: area.c:2346
@ AZONE_REGION
@ AZONE_FULLSCREEN
@ AZONE_REGION_SCROLL
@ AZONE_AREA
@ ANIMPLAY_FLAG_JUMPED
@ ANIMPLAY_FLAG_NO_SYNC
@ ANIMPLAY_FLAG_REVERSE
@ ANIMPLAY_FLAG_SYNC
@ ANIMPLAY_FLAG_USE_NEXT_FRAME
@ AZ_SCROLL_HOR
@ AZ_SCROLL_VERT
AZEdge
@ AE_LEFT_TO_TOPRIGHT
@ AE_RIGHT_TO_TOPLEFT
@ AE_BOTTOM_TO_TOPLEFT
@ AE_TOP_TO_BOTTOMRIGHT
bool ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene)
char ED_view3d_lock_view_from_index(int index)
void ED_view3d_lastview_store(struct RegionView3D *rv3d)
Definition: view3d_utils.c:487
bool ED_view3d_lock(struct RegionView3D *rv3d)
bool ED_view3d_context_user_region(struct bContext *C, struct View3D **r_v3d, struct ARegion **r_region)
Definition: space_view3d.c:107
void ED_view3d_quadview_update(struct ScrArea *area, struct ARegion *region, bool do_clip)
Definition: view3d_utils.c:939
static AppView * view
bool GPU_mem_stats_supported(void)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
StructRNA RNA_SpaceProperties
StructRNA RNA_Space
StructRNA RNA_Preferences
StructRNA RNA_Camera
StructRNA RNA_PreferencesView
StructRNA RNA_Area
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
#define UI_REGION_OVERLAP_MARGIN
Definition: UI_interface.h:100
#define UI_UNIT_Y
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr)
void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop)
#define UI_NAVIGATION_REGION_WIDTH
Definition: UI_interface.h:246
struct uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void uiItemS(uiLayout *layout)
#define UI_DPI_FAC
Definition: UI_interface.h:309
bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event, const char **r_tooltip)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
uiBut * UI_context_active_but_prop_get(const struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop, int *r_index)
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *pup)
#define UI_UNIT_X
uiPopupMenu * UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL()
float UI_view2d_view_to_region_x(const struct View2D *v2d, float x)
float UI_view2d_view_to_region_y(const struct View2D *v2d, float y)
char UI_view2d_mouse_in_scrollers_ex(const struct ARegion *region, const struct View2D *v2d, int x, int y, int *r_scroll)
void UI_view2d_curRect_validate(struct View2D *v2d)
Definition: view2d.c:851
@ WIN_ALIGN_LOCATION_CENTER
Definition: WM_api.h:177
@ WIN_ALIGN_ABSOLUTE
Definition: WM_api.h:176
#define NC_WINDOW
Definition: WM_types.h:277
@ OPTYPE_INTERNAL
Definition: WM_types.h:175
@ OPTYPE_BLOCKING
Definition: WM_types.h:157
@ OPTYPE_UNDO_GROUPED
Definition: WM_types.h:180
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define WM_DRAG_PATH
Definition: WM_types.h:876
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:197
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:204
#define NC_SCREEN
Definition: WM_types.h:278
#define NC_SCENE
Definition: WM_types.h:279
#define NA_EDITED
Definition: WM_types.h:462
#define KM_PRESS
Definition: WM_types.h:242
#define WM_EVENT_CURSOR_MOTION_THRESHOLD
Definition: WM_types.h:648
#define ND_FRAME
Definition: WM_types.h:334
#define KM_NOTHING
Definition: WM_types.h:241
#define ND_WORKSPACE_SET
Definition: WM_types.h:328
#define ND_LAYOUTBROWSE
Definition: WM_types.h:321
#define ND_LAYOUTDELETE
Definition: WM_types.h:322
#define KM_RELEASE
Definition: WM_types.h:243
void ANIM_anim_channels_select_set(bAnimContext *ac, eAnimChannels_SetFlag sel)
void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datatype, eAnimFilter_Flags filter, void *channel_data, eAnim_ChannelType channel_type)
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
Definition: anim_filter.c:405
void region_toggle_hidden(bContext *C, ARegion *region, const bool do_fade)
Definition: area.c:2043
void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free)
Definition: area.c:2067
return(oflags[bm->toolflag_index].f &oflag) !=0
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
bool closest(btVector3 &v)
static float is_left(const float p0[2], const float p1[2], const float p2[2])
Definition: convexhull_2d.c:51
double time
Scene scene
const Depsgraph * depsgraph
static CCL_NAMESPACE_BEGIN const double alpha
uint col
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
int count
void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction_flag)
void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys)
short compare_ak_cfraPtr(void *node, void *data)
void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active)
void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_flag)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static int box_select_exec(bContext *C, wmOperator *op)
Definition: mask_select.c:446
static ulong * next
static ulong state[N]
bool isfinite(uchar)
Definition: image.cpp:44
static void area(int d1, int d2, int e1, int e2, float weights[2])
bool active
all scheduled work for the GPU.
Object * ED_pose_object_from_context(bContext *C)
Definition: pose_edit.c:76
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
Definition: rna_access.c:6343
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
Definition: rna_access.c:6331
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:6550
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3562
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
int RNA_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int step)
Definition: rna_access.c:3608
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2317
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:6366
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3543
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2964
void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
Definition: rna_access.c:2690
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
Definition: rna_access.c:1902
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:6685
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
Definition: rna_access.c:1657
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3611
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
const EnumPropertyItem rna_enum_region_type_items[]
Definition: rna_screen.c:35
const EnumPropertyItem rna_enum_space_type_items[]
Definition: rna_space.c:72
int area_getorientation(ScrArea *area, ScrArea *sb)
Definition: screen_edit.c:285
int screen_area_join(bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2)
Definition: screen_edit.c:396
ScrArea * area_split(const wmWindow *win, bScreen *screen, ScrArea *area, char dir, float fac, int merge)
Definition: screen_edit.c:107
ScrEdge * screen_geom_area_map_find_active_scredge(const ScrAreaMap *area_map, const rcti *bounds_rect, const int mx, const int my)
void screen_geom_select_connected_edge(const wmWindow *win, ScrEdge *edge)
bool screen_geom_edge_is_horizontal(ScrEdge *se)
ScrEdge * screen_geom_find_active_scredge(const wmWindow *win, const bScreen *screen, const int mx, const int my)
int screen_geom_area_width(const ScrArea *area)
int screen_geom_area_height(const ScrArea *area)
#define AZONESPOTW
Definition: screen_intern.h:32
#define AZONEFADEIN
Definition: screen_intern.h:34
#define AZONEFADEOUT
Definition: screen_intern.h:35
void SCREEN_OT_screenshot(struct wmOperatorType *ot)
Definition: screendump.c:231
static int region_flip_exec(bContext *C, wmOperator *UNUSED(op))
Definition: screen_ops.c:3988
static void screen_animation_region_tag_redraw(bContext *C, ScrArea *area, ARegion *region, const Scene *scene, eScreen_Redraws_Flag redraws)
Definition: screen_ops.c:4336
static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
Definition: screen_ops.c:4847
static void SCREEN_OT_area_options(wmOperatorType *ot)
Definition: screen_ops.c:3554
static int screen_delete_exec(bContext *C, wmOperator *UNUSED(op))
Definition: screen_ops.c:5074
bool ED_operator_editarmature(bContext *C)
Definition: screen_ops.c:437
static int frame_jump_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:2851
static int area_split_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:2253
static void area_swap_cancel(bContext *C, wmOperator *op)
Definition: screen_ops.c:1246
static void actionzone_exit(wmOperator *op)
Definition: screen_ops.c:955
static void SCREEN_OT_region_context_menu(wmOperatorType *ot)
Definition: screen_ops.c:4216
static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:1819
static void keymap_modal_set(wmKeyConfig *keyconf)
Definition: screen_ops.c:5533
static void SCREEN_OT_region_scale(wmOperatorType *ot)
Definition: screen_ops.c:2744
#define KM_MODAL_APPLY
Definition: screen_ops.c:97
static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
Definition: screen_ops.c:4903
static int screen_maximize_area_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3122
bool ED_operator_uvmap(bContext *C)
Definition: screen_ops.c:525
static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:1251
void ED_operatortypes_screen(void)
Definition: screen_ops.c:5478
bool ED_operator_graphedit_active(bContext *C)
Definition: screen_ops.c:314
bool ED_operator_action_active(bContext *C)
Definition: screen_ops.c:282
bool ED_operator_sequencer_active_editable(bContext *C)
Definition: screen_ops.c:324
bool ED_operator_animview_active(bContext *C)
Definition: screen_ops.c:246
static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:1794
bool ED_operator_node_editable(bContext *C)
Definition: screen_ops.c:303
bool ED_operator_screen_mainwinactive(bContext *C)
Definition: screen_ops.c:168
static int screen_animation_cancel_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:4712
static bool area_split_menu_init(bContext *C, wmOperator *op)
Definition: screen_ops.c:1955
static void area_move_set_limits(wmWindow *win, bScreen *screen, int dir, int *bigger, int *smaller, bool *use_bigger_smaller_snap)
Definition: screen_ops.c:1448
static bool match_region_with_redraws(const ScrArea *area, eRegionType regiontype, eScreen_Redraws_Flag redraws, bool from_anim_edit)
Definition: screen_ops.c:4242
static void ed_screens_statusbar_menu_create(uiLayout *layout, void *UNUSED(arg))
Definition: screen_ops.c:4168
static void region_scale_validate_size(RegionMoveData *rmd)
Definition: screen_ops.c:2583
static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:1264
static bool space_context_cycle_poll(bContext *C)
Definition: screen_ops.c:5328
static bool area_split_apply(bContext *C, wmOperator *op)
Definition: screen_ops.c:2034
bool ED_operator_console_active(bContext *C)
Definition: screen_ops.c:344
static void context_cycle_prop_get(bScreen *screen, const ScrArea *area, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition: screen_ops.c:5339
static bool screen_animation_region_supports_time_follow(eSpace_Type spacetype, eRegionType regiontype)
Definition: screen_ops.c:4234
float ED_region_blend_alpha(ARegion *region)
Definition: screen_ops.c:5116
static void SCREEN_OT_animation_play(wmOperatorType *ot)
Definition: screen_ops.c:4685
static bool area_join_init(bContext *C, wmOperator *op, ScrArea *sa1, ScrArea *sa2)
Definition: screen_ops.c:3239
static void SCREEN_OT_workspace_cycle(wmOperatorType *ot)
Definition: screen_ops.c:5450
#define KM_MODAL_CANCEL
Definition: screen_ops.c:96
static void area_move_exit(bContext *C, wmOperator *op)
Definition: screen_ops.c:1767
bool ED_operator_info_active(bContext *C)
Definition: screen_ops.c:339
static void blend_file_drop_copy(wmDrag *drag, wmDropBox *drop)
Definition: screen_ops.c:5562
static int screen_new_exec(bContext *C, wmOperator *UNUSED(op))
Definition: screen_ops.c:5042
void ED_keymap_screen(wmKeyConfig *keyconf)
Definition: screen_ops.c:5569
static int screen_animation_play_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:4673
static AZone * area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const bool test_only)
Definition: screen_ops.c:771
bool ED_operator_editable_mesh(bContext *C)
Definition: screen_ops.c:398
static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:2627
static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
Definition: screen_ops.c:5207
bool ED_operator_editmesh_auto_smooth(bContext *C)
Definition: screen_ops.c:428
static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:3315
#define TIMEOUT
Definition: screen_ops.c:5113
static void SCREEN_OT_actionzone(wmOperatorType *ot)
Definition: screen_ops.c:1132
static int space_context_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: screen_ops.c:5363
static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:3352
static void actionzone_apply(bContext *C, wmOperator *op, int type)
Definition: screen_ops.c:966
static void region_scale_cancel(bContext *UNUSED(C), wmOperator *op)
Definition: screen_ops.c:2739
bool ED_operator_scene(bContext *C)
Definition: screen_ops.c:183
AZone * ED_area_azones_update(ScrArea *area, const int xy[2])
Definition: screen_ops.c:950
bool ED_operator_object_active_local_editable(bContext *C)
Definition: screen_ops.c:378
static int region_toggle_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3928
bool ED_operator_screenactive(bContext *C)
Definition: screen_ops.c:133
#define KM_MODAL_SNAP_ON
Definition: screen_ops.c:98
bool ED_operator_regionactive(bContext *C)
Definition: screen_ops.c:105
static int area_snap_calc_location(const bScreen *screen, const enum AreaMoveSnapType snap_type, const int delta, const int origval, const int dir, const int bigger, const int smaller)
Definition: screen_ops.c:1589
static bool actionzone_area_poll(bContext *C)
Definition: screen_ops.c:701
bool ED_operator_editsurfcurve_region_view3d(bContext *C)
Definition: screen_ops.c:550
int ED_screen_animation_play(bContext *C, int sync, int mode)
Definition: screen_ops.c:4641
void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
Definition: screen_ops.c:4080
static int marker_jump_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3026
static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdata)
Definition: screen_ops.c:1941
static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd)
Definition: screen_ops.c:2603
static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
Definition: screen_ops.c:3003
static bool space_type_set_or_cycle_poll(bContext *C)
Definition: screen_ops.c:5255
static int drivers_editor_show_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:4921
struct RegionAlphaInfo RegionAlphaInfo
static ScrEdge * area_findsharededge(bScreen *screen, ScrArea *area, ScrArea *sb)
Definition: screen_ops.c:2006
static bool ed_spacetype_test(bContext *C, int type)
Definition: screen_ops.c:221
bool ED_operator_object_active(bContext *C)
Definition: screen_ops.c:355
bool ED_operator_editsurfcurve(bContext *C)
Definition: screen_ops.c:541
static void SCREEN_OT_frame_jump(wmOperatorType *ot)
Definition: screen_ops.c:2890
static void SCREEN_OT_redo_last(wmOperatorType *ot)
Definition: screen_ops.c:3743
static int space_type_set_or_cycle_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:5261
static bool area_swap_init(wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:1221
static void area_move_apply(bContext *C, wmOperator *op)
Definition: screen_ops.c:1759
#define TIMESTEP
Definition: screen_ops.c:5114
bool ED_operator_editcurve_3d(bContext *C)
Definition: screen_ops.c:569
bool ED_operator_objectmode(bContext *C)
Definition: screen_ops.c:201
static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
Definition: screen_ops.c:3732
static int header_toggle_menus_exec(bContext *C, wmOperator *UNUSED(op))
Definition: screen_ops.c:4049
static bool area_split_init(bContext *C, wmOperator *op)
Definition: screen_ops.c:1967
static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot)
Definition: screen_ops.c:4980
bool ED_operator_sequencer_active(bContext *C)
Definition: screen_ops.c:319
static void SCREEN_OT_animation_step(wmOperatorType *ot)
Definition: screen_ops.c:4592
static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot)
Definition: screen_ops.c:4061
static int area_join_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3302
bool ED_operator_scene_editable(bContext *C)
Definition: screen_ops.c:192
static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:995
static void SCREEN_OT_delete(wmOperatorType *ot)
Definition: screen_ops.c:5085
bool ED_operator_image_active(bContext *C)
Definition: screen_ops.c:329
static void SCREEN_OT_space_type_set_or_cycle(wmOperatorType *ot)
Definition: screen_ops.c:5300
bool ED_operator_view3d_active(bContext *C)
Definition: screen_ops.c:230
static ScrArea * screen_actionzone_area(bScreen *screen, const AZone *az)
Definition: screen_ops.c:933
static const EnumPropertyItem prop_direction_items[]
Definition: screen_ops.c:2403
static int info_log_show_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:4998
static ScrEdge * screen_area_edge_from_cursor(const bContext *C, const int cursor[2], ScrArea **r_sa1, ScrArea **r_sa2)
Definition: screen_ops.c:1156
static AZone * screen_actionzone_find_xy(bScreen *screen, const int xy[2])
Definition: screen_ops.c:921
static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3576
bool ED_operator_node_active(bContext *C)
Definition: screen_ops.c:292
struct sAreaSplitData sAreaSplitData
void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
Definition: screen_ops.c:4127
static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
Definition: screen_ops.c:3171
static bool azone_clipped_rect_calc(const AZone *az, rcti *r_rect_clip)
Definition: screen_ops.c:727
static bool blend_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(r_tooltip))
Definition: screen_ops.c:5549
static bool repeat_history_poll(bContext *C)
Definition: screen_ops.c:3616
bool ED_operator_posemode_local(bContext *C)
Definition: screen_ops.c:500
static void SCREEN_OT_frame_offset(wmOperatorType *ot)
Definition: screen_ops.c:2828
static void view3d_localview_update_rv3d(struct RegionView3D *rv3d)
Definition: screen_ops.c:3761
static int repeat_history_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3695
static int area_max_regionsize(ScrArea *area, ARegion *scalear, AZEdge edge)
Definition: screen_ops.c:2449
bool ED_operator_nla_active(bContext *C)
Definition: screen_ops.c:334
bool ED_operator_object_active_local_editable_ex(bContext *C, const Object *ob)
Definition: screen_ops.c:373
bool ED_operator_screenactive_nobackground(bContext *C)
Definition: screen_ops.c:144
bool ED_operator_uvedit_space_image(bContext *C)
Definition: screen_ops.c:518
static void region_scale_exit(wmOperator *op)
Definition: screen_ops.c:2514
static void SCREEN_OT_space_context_cycle(wmOperatorType *ot)
Definition: screen_ops.c:5379
bool ED_operator_region_view3d_active(bContext *C)
Definition: screen_ops.c:235
bool ED_operator_object_active_editable(bContext *C)
Definition: screen_ops.c:366
bool ED_operator_posemode_exclusive(bContext *C)
check for pose mode (no mixed modes)
Definition: screen_ops.c:453
struct sAreaMoveData sAreaMoveData
static bool region_toggle_poll(bContext *C)
Definition: screen_ops.c:3948
static int screen_context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
Definition: screen_ops.c:4181
bool ED_operator_camera(bContext *C)
Definition: screen_ops.c:642
static int region_quadview_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3793
bool ED_operator_editcurve(bContext *C)
Definition: screen_ops.c:560
static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: screen_ops.c:3665
struct sActionzoneData sActionzoneData
static void area_split_exit(bContext *C, wmOperator *op)
Definition: screen_ops.c:2077
static void SCREEN_OT_area_swap(wmOperatorType *ot)
Definition: screen_ops.c:1313
static int frame_offset_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:2809
static void area_swap_exit(bContext *C, wmOperator *op)
Definition: screen_ops.c:1237
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
Definition: screen_ops.c:4614
bool ED_operator_areaactive(bContext *C)
Definition: screen_ops.c:119
bool ED_operator_editmesh_region_view3d(bContext *C)
Definition: screen_ops.c:418
static void SCREEN_OT_area_split(wmOperatorType *ot)
Definition: screen_ops.c:2409
void ED_region_visibility_change_update_animated(bContext *C, ScrArea *area, ARegion *region)
Definition: screen_ops.c:5170
bool ED_operator_object_active_editable_mesh(bContext *C)
Definition: screen_ops.c:384
static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot)
Definition: screen_ops.c:3598
static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:1341
bool ED_operator_posemode_context(bContext *C)
Definition: screen_ops.c:471
static void SCREEN_OT_repeat_history(wmOperatorType *ot)
Definition: screen_ops.c:3711
bool ED_operator_posemode(bContext *C)
Definition: screen_ops.c:484
static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op))
Definition: screen_ops.c:3625
bool ED_operator_editmball(bContext *C)
Definition: screen_ops.c:607
static int area_move_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:1781
static void SCREEN_OT_new(wmOperatorType *ot)
Definition: screen_ops.c:5056
static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
Definition: screen_ops.c:4736
static int userpref_show_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:4865
static void fullscreen_click_rcti_init(rcti *rect, const short UNUSED(x1), const short UNUSED(y1), const short x2, const short y2)
Definition: screen_ops.c:721
static void SCREEN_OT_area_dupli(wmOperatorType *ot)
Definition: screen_ops.c:1385
#define KM_MODAL_SNAP_OFF
Definition: screen_ops.c:99
bool ED_operator_file_active(bContext *C)
Definition: screen_ops.c:277
static void area_split_preview_update_cursor(bContext *C, wmOperator *op)
Definition: screen_ops.c:2106
struct sAreaSwapData sAreaSwapData
static void SCREEN_OT_region_quadview(wmOperatorType *ot)
Definition: screen_ops.c:3909
static void SCREEN_OT_screen_set(wmOperatorType *ot)
Definition: screen_ops.c:3102
static void actionzone_cancel(bContext *UNUSED(C), wmOperator *op)
Definition: screen_ops.c:1127
bool ED_operator_editmesh_view3d(bContext *C)
Definition: screen_ops.c:413
static void area_split_cancel(bContext *C, wmOperator *op)
Definition: screen_ops.c:2265
static bool screen_active_editable(bContext *C)
Definition: screen_ops.c:654
static bool ED_operator_screenactive_norender(bContext *C)
Definition: screen_ops.c:153
static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:2114
static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:2522
bool ED_operator_editsurf(bContext *C)
Definition: screen_ops.c:580
static void SCREEN_OT_repeat_last(wmOperatorType *ot)
Definition: screen_ops.c:3646
static bool area_join_apply(bContext *C, wmOperator *op)
Definition: screen_ops.c:3264
struct sAreaJoinData sAreaJoinData
static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:1028
bScreen * ED_screen_animation_no_scrub(const wmWindowManager *wm)
Definition: screen_ops.c:4627
static void region_blend_end(bContext *C, ARegion *region, const bool is_running)
Definition: screen_ops.c:5140
static int space_workspace_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: screen_ops.c:5406
void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
Definition: screen_ops.c:4155
static void areas_do_frame_follow(bContext *C, bool middle)
Definition: screen_ops.c:2767
struct RegionMoveData RegionMoveData
static void SCREEN_OT_area_move(wmOperatorType *ot)
Definition: screen_ops.c:1864
bool ED_operator_mask(bContext *C)
Definition: screen_ops.c:616
static void SCREEN_OT_marker_jump(wmOperatorType *ot)
Definition: screen_ops.c:3067
bool ED_operator_editlattice(bContext *C)
Definition: screen_ops.c:598
static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:3482
static int fullscreen_back_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:4825
bool ED_operator_outliner_active_no_editobject(bContext *C)
Definition: screen_ops.c:264
static bool region_flip_poll(bContext *C)
Definition: screen_ops.c:4016
bool ED_operator_editmesh(bContext *C)
Definition: screen_ops.c:404
static bool ed_object_hidden(const Object *ob)
Definition: screen_ops.c:349
bool ED_operator_object_active_editable_ex(bContext *UNUSED(C), const Object *ob)
Definition: screen_ops.c:361
static const EnumPropertyItem space_context_cycle_direction[]
Definition: screen_ops.c:5322
bool ED_operator_uvedit(bContext *C)
Definition: screen_ops.c:511
static void area_join_cancel(bContext *C, wmOperator *op)
Definition: screen_ops.c:3344
bool ED_operator_outliner_active(bContext *C)
Definition: screen_ops.c:259
bool ED_operator_object_active_editable_font(bContext *C)
Definition: screen_ops.c:391
static void region_quadview_init_rv3d(ScrArea *area, ARegion *region, const char viewlock, const char view, const char persp)
Definition: screen_ops.c:3770
static void SCREEN_OT_region_flip(wmOperatorType *ot)
Definition: screen_ops.c:4029
static void area_move_apply_do(const bContext *C, int delta, const int origval, const int dir, const int bigger, const int smaller, const enum AreaMoveSnapType snap_type)
Definition: screen_ops.c:1683
static void area_join_exit(bContext *C, wmOperator *op)
Definition: screen_ops.c:3283
static int screen_animation_step_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
Definition: screen_ops.c:4389
static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata)
Definition: screen_ops.c:3227
static bool area_move_init(bContext *C, wmOperator *op)
Definition: screen_ops.c:1548
static void area_move_cancel(bContext *C, wmOperator *op)
Definition: screen_ops.c:1810
static bool screen_maximize_area_poll(bContext *C)
Definition: screen_ops.c:3159
static void SCREEN_OT_region_blend(wmOperatorType *ot)
Definition: screen_ops.c:5233
static int area_swap_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:1300
AZone * ED_area_actionzone_find_xy(ScrArea *area, const int xy[2])
Definition: screen_ops.c:945
bool ED_operator_buttons_active(bContext *C)
Definition: screen_ops.c:287
static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: screen_ops.c:2284
static void SCREEN_OT_info_log_show(struct wmOperatorType *ot)
Definition: screen_ops.c:5024
static int keyframe_jump_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:2913
static int screen_set_exec(bContext *C, wmOperator *op)
Definition: screen_ops.c:3090
static void SCREEN_OT_region_toggle(wmOperatorType *ot)
Definition: screen_ops.c:3961
static void SCREEN_OT_area_join(wmOperatorType *ot)
Definition: screen_ops.c:3454
bool ED_operator_editfont(bContext *C)
Definition: screen_ops.c:589
static bool is_split_edge(const int alignment, const AZEdge edge)
Definition: screen_ops.c:2506
int(* snap_size)(const struct ARegion *region, int size, int axis)
Definition: BKE_screen.h:181
struct wmTimer * regiontimer
void * regiondata
struct ARegion * prev
struct ARegion * next
ListBase handlers
short alignment
short regiontype
struct ARegionType * type
short y2
float alpha
struct AZone * next
AZEdge edge
ARegion * region
short x1
short x2
AZScrollDirection direction
short y1
struct ActKeyColumn * next
struct ActKeyColumn * prev
struct BMesh * bm
Definition: BKE_editmesh.h:52
int totface
Definition: bmesh_class.h:297
EditNurb * editnurb
short flag
Definition: DNA_ID.h:273
int recalc
Definition: DNA_ID.h:295
int icon_id
Definition: DNA_ID.h:294
void * data
Definition: DNA_listBase.h:42
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase screens
Definition: BKE_main.h:161
ListBase workspaces
Definition: BKE_main.h:181
void * data
char restrictflag
void * data
Definition: RNA_types.h:52
ARegion * child_region
Definition: screen_ops.c:5109
ARegion * region
Definition: screen_ops.c:5109
ScrArea * area
Definition: screen_ops.c:5108
ScrArea * area
Definition: screen_ops.c:2441
ARegion * region
Definition: screen_ops.c:2440
float viewquat[4]
struct RegionView3D * localvd
short flag
struct RenderData r
ListBase markers
struct AudioData audio
ListBase areabase
ScrVert * v2
ScrVert * v3
ScrVert * v1
ScrVert * v4
ScrVert * v1
ScrVert * v2
short editflag
ARegion * region
double lagging_frame_count
struct bNodeTree * edittree
char alpha_vert
short keeptot
char alpha_hor
struct Object * camera
Wrapper for bScreen.
short datatype
Definition: ED_anim_api.h:75
void * data
Definition: ED_anim_api.h:73
char do_refresh
short redraws_flag
ListBase vertbase
struct wmTimer * animtimer
char scrubbing
ListBase areabase
struct ARegion * active_region
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
ScrArea * sa1
Definition: screen_ops.c:695
ScrArea * sa2
Definition: screen_ops.c:695
ScrArea * sa1
Definition: screen_ops.c:3221
void * draw_callback
Definition: screen_ops.c:3223
ScrArea * sa2
Definition: screen_ops.c:3222
enum sAreaMoveData::AreaMoveSnapType snap_type
@ SNAP_FRACTION_AND_ADJACENT
Definition: screen_ops.c:1438
@ SNAP_BIGGER_SMALLER_ONLY
Definition: screen_ops.c:1442
ScrEdge * nedge
Definition: screen_ops.c:1935
ScrArea * narea
Definition: screen_ops.c:1937
void * draw_callback
Definition: screen_ops.c:1932
ScrArea * sarea
Definition: screen_ops.c:1936
ScrArea * sa1
Definition: screen_ops.c:1218
ScrArea * sa2
Definition: screen_ops.c:1218
short y
Definition: DNA_vec_types.h:34
short x
Definition: DNA_vec_types.h:34
char path[1024]
Definition: WM_types.h:909
int icon
Definition: WM_types.h:905
int type
Definition: WM_types.h:907
struct PointerRNA * ptr
Definition: WM_types.h:953
int y
Definition: WM_types.h:581
short val
Definition: WM_types.h:579
int x
Definition: WM_types.h:581
short type
Definition: WM_types.h:577
void * customdata
Definition: WM_types.h:631
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
const char * undo_group
Definition: WM_types.h:728
struct ReportList * reports
struct wmOperator * prev
struct wmOperatorType * type
struct PointerRNA * ptr
double timestep
Definition: WM_types.h:696
void * customdata
Definition: WM_types.h:702
double delta
Definition: WM_types.h:707
double duration
Definition: WM_types.h:705
struct wmEvent * eventstate
ScrAreaMap global_areas
struct WorkSpaceInstanceHook * workspace_hook
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
#define G(x, y, z)
void WM_operator_free_all_after(wmWindowManager *wm, struct wmOperator *op)
Definition: wm.c:327
void WM_cursor_modal_set(wmWindow *win, int val)
Definition: wm_cursors.c:207
void WM_cursor_set(wmWindow *win, int curs)
Definition: wm_cursors.c:142
void WM_cursor_modal_restore(wmWindow *win)
Definition: wm_cursors.c:216
@ WM_CURSOR_CROSS
Definition: wm_cursors.h:42
@ WM_CURSOR_H_SPLIT
Definition: wm_cursors.h:56
@ WM_CURSOR_S_ARROW
Definition: wm_cursors.h:63
@ WM_CURSOR_E_ARROW
Definition: wm_cursors.h:64
@ WM_CURSOR_N_ARROW
Definition: wm_cursors.h:62
@ WM_CURSOR_STOP
Definition: wm_cursors.h:37
@ WM_CURSOR_V_SPLIT
Definition: wm_cursors.h:57
@ WM_CURSOR_SWAP_AREA
Definition: wm_cursors.h:53
@ WM_CURSOR_W_ARROW
Definition: wm_cursors.h:65
wmDropBox * WM_dropbox_add(ListBase *lb, const char *idname, bool(*poll)(bContext *, wmDrag *, const wmEvent *, const char **), void(*copy)(wmDrag *, wmDropBox *), void(*cancel)(struct Main *, wmDrag *, wmDropBox *))
Definition: wm_dragdrop.c:96
ListBase * WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
Definition: wm_dragdrop.c:77
void WM_draw_cb_exit(wmWindow *win, void *handle)
Definition: wm_draw.c:375
void * WM_draw_cb_activate(wmWindow *win, void(*draw)(const struct wmWindow *, void *), void *customdata)
Definition: wm_draw.c:362
int WM_operator_repeat_last(bContext *C, wmOperator *op)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
wmEvent * wm_event_add(wmWindow *win, const wmEvent *event_to_add)
int WM_operator_repeat(bContext *C, wmOperator *op)
bool WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void wm_event_init_from_window(wmWindow *win, wmEvent *event)
void WM_event_remove_handlers(bContext *C, ListBase *handlers)
void WM_event_add_mousemove(wmWindow *win)
@ RIGHTMOUSE
@ EVT_MODAL_MAP
@ EVT_ACTIONZONE_FULLSCREEN
@ EVT_ACTIONZONE_REGION
@ EVT_TABKEY
@ EVT_LEFTCTRLKEY
@ EVT_ACTIONZONE_AREA
@ MOUSEMOVE
@ LEFTMOUSE
@ MIDDLEMOUSE
@ EVT_ESCKEY
@ TIMERREGION
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:852
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
Definition: wm_keymap.c:985
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
Definition: wm_keymap.c:888
void WM_operator_properties_border(wmOperatorType *ot)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
const char * WM_operatortype_name(struct wmOperatorType *ot, struct PointerRNA *properties)
int WM_operator_redo_popup(bContext *C, wmOperator *op)
bool WM_operator_winactive(bContext *C)
wmOperator * WM_operator_last_redo(const bContext *C)
void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer)
Definition: wm_window.c:1669
bScreen * WM_window_get_active_screen(const wmWindow *win)
Definition: wm_window.c:2372
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
Definition: wm_window.c:2286
WorkSpace * WM_window_get_active_workspace(const wmWindow *win)
Definition: wm_window.c:2335
bool WM_window_is_temp_screen(const wmWindow *win)
Definition: wm_window.c:2383
void WM_window_rect_calc(const wmWindow *win, rcti *r_rect)
Definition: wm_window.c:2146
void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect)
Definition: wm_window.c:2154
wmWindow * WM_window_open(bContext *C, const char *title, int x, int y, int sizex, int sizey, int space_type, bool dialog, bool temp, WindowAlignment alignment)
Definition: wm_window.c:764
wmTimer * WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep)
Definition: wm_window.c:1632