Exemplo n.º 1
0
static int workspace_append(bContext *C, const char *directory, const char *idname)
{
  wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
  PointerRNA opptr;
  int retval;

  WM_operator_properties_create_ptr(&opptr, ot);
  RNA_string_set(&opptr, "directory", directory);
  RNA_string_set(&opptr, "filename", idname);
  RNA_boolean_set(&opptr, "autoselect", false);

  retval = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &opptr);

  WM_operator_properties_free(&opptr);

  return retval;
}
Exemplo n.º 2
0
static int add_driver_button_exec(bContext *C, wmOperator *op)
{
	short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
	if (ELEM(mapping_type, CREATEDRIVER_MAPPING_NONE, CREATEDRIVER_MAPPING_NONE_ALL)) {
		/* Just create driver with no targets */
		return add_driver_button_none(C, op, mapping_type);
	}
	else {
		/* Create Driver using Eyedropper */
		wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
		
		/* XXX: We assume that it's fine to use the same set of properties, since they're actually the same... */
		WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, op->ptr);
		
		return OPERATOR_FINISHED;
	}
}
Exemplo n.º 3
0
static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
	PointerRNA ptr;
	PropertyRNA *prop;
	bool is_undo;
	FileBrowseOp *fbo;
	char *str;

	if (CTX_wm_space_file(C)) {
		BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector, one already open");
		return OPERATOR_CANCELLED;
	}

	UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop, &is_undo);

	if (!prop)
		return OPERATOR_CANCELLED;

	str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL);

	/* useful yet irritating feature, Shift+Click to open the file
	 * Alt+Click to browse a folder in the OS's browser */
	if (event->shift || event->alt) {
		wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
		PointerRNA props_ptr;

		if (event->alt) {
			char *lslash = (char *)BLI_last_slash(str);
			if (lslash)
				*lslash = '\0';
		}


		WM_operator_properties_create_ptr(&props_ptr, ot);
		RNA_string_set(&props_ptr, "filepath", str);
		WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
		WM_operator_properties_free(&props_ptr);

		MEM_freeN(str);
		return OPERATOR_CANCELLED;
	}
	else {
		PropertyRNA *prop_relpath;
		const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath";
		fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp");
		fbo->ptr = ptr;
		fbo->prop = prop;
		fbo->is_undo = is_undo;
		op->customdata = fbo;

		RNA_string_set(op->ptr, path_prop, str);
		MEM_freeN(str);

		/* normally ED_fileselect_get_params would handle this but we need to because of stupid
		 * user-prefs exception - campbell */
		if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
			if (!RNA_property_is_set(op->ptr, prop_relpath)) {
				/* annoying exception!, if were dealing with the user prefs, default relative to be off */
				RNA_property_boolean_set(op->ptr, prop_relpath, U.flag & USER_RELPATHS && (ptr.data != &U));
			}
		}
		WM_event_add_fileselect(C, op);

		return OPERATOR_RUNNING_MODAL;
	}
}
Exemplo n.º 4
0
static int edittranslation_exec(bContext *C, wmOperator *op)
{
  uiBut *but = UI_context_active_but_get(C);
  int ret = OPERATOR_CANCELLED;

  if (but) {
    wmOperatorType *ot;
    PointerRNA ptr;
    char popath[FILE_MAX];
    const char *root = U.i18ndir;
    const char *uilng = BLT_lang_get();

    uiStringInfo but_label = {BUT_GET_LABEL, NULL};
    uiStringInfo rna_label = {BUT_GET_RNA_LABEL, NULL};
    uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL};
    uiStringInfo but_tip = {BUT_GET_TIP, NULL};
    uiStringInfo rna_tip = {BUT_GET_RNA_TIP, NULL};
    uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL};
    uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL};
    uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL};
    uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, NULL};
    uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, NULL};

    if (!BLI_is_dir(root)) {
      BKE_report(op->reports,
                 RPT_ERROR,
                 "Please set your Preferences' 'Translation Branches "
                 "Directory' path to a valid directory");
      return OPERATOR_CANCELLED;
    }
    ot = WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0);
    if (ot == NULL) {
      BKE_reportf(op->reports,
                  RPT_ERROR,
                  "Could not find operator '%s'! Please enable ui_translate add-on "
                  "in the User Preferences",
                  EDTSRC_I18N_OP_NAME);
      return OPERATOR_CANCELLED;
    }
    /* Try to find a valid po file for current language... */
    edittranslation_find_po_file(root, uilng, popath, FILE_MAX);
    /* printf("po path: %s\n", popath); */
    if (popath[0] == '\0') {
      BKE_reportf(
          op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root);
      return OPERATOR_CANCELLED;
    }

    UI_but_string_info_get(C,
                           but,
                           &but_label,
                           &rna_label,
                           &enum_label,
                           &but_tip,
                           &rna_tip,
                           &enum_tip,
                           &rna_struct,
                           &rna_prop,
                           &rna_enum,
                           &rna_ctxt,
                           NULL);

    WM_operator_properties_create_ptr(&ptr, ot);
    RNA_string_set(&ptr, "lang", uilng);
    RNA_string_set(&ptr, "po_file", popath);
    RNA_string_set(&ptr, "but_label", but_label.strinfo);
    RNA_string_set(&ptr, "rna_label", rna_label.strinfo);
    RNA_string_set(&ptr, "enum_label", enum_label.strinfo);
    RNA_string_set(&ptr, "but_tip", but_tip.strinfo);
    RNA_string_set(&ptr, "rna_tip", rna_tip.strinfo);
    RNA_string_set(&ptr, "enum_tip", enum_tip.strinfo);
    RNA_string_set(&ptr, "rna_struct", rna_struct.strinfo);
    RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo);
    RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo);
    RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo);
    ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);

    /* Clean up */
    if (but_label.strinfo) {
      MEM_freeN(but_label.strinfo);
    }
    if (rna_label.strinfo) {
      MEM_freeN(rna_label.strinfo);
    }
    if (enum_label.strinfo) {
      MEM_freeN(enum_label.strinfo);
    }
    if (but_tip.strinfo) {
      MEM_freeN(but_tip.strinfo);
    }
    if (rna_tip.strinfo) {
      MEM_freeN(rna_tip.strinfo);
    }
    if (enum_tip.strinfo) {
      MEM_freeN(enum_tip.strinfo);
    }
    if (rna_struct.strinfo) {
      MEM_freeN(rna_struct.strinfo);
    }
    if (rna_prop.strinfo) {
      MEM_freeN(rna_prop.strinfo);
    }
    if (rna_enum.strinfo) {
      MEM_freeN(rna_enum.strinfo);
    }
    if (rna_ctxt.strinfo) {
      MEM_freeN(rna_ctxt.strinfo);
    }

    return ret;
  }
  else {
    BKE_report(op->reports, RPT_ERROR, "Active button not found");
    return OPERATOR_CANCELLED;
  }
}
Exemplo n.º 5
0
/* mouse coordinate converversion happens here */
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
{
    bContext *C = C_void_ptr;
    wmWindowManager *wm = CTX_wm_manager(C);
    GHOST_TEventType type = GHOST_GetEventType(evt);
    int time = GHOST_GetEventTime(evt);

    if (type == GHOST_kEventQuit) {
        WM_exit(C);
    }
    else {
        GHOST_WindowHandle ghostwin = GHOST_GetEventWindow(evt);
        GHOST_TEventDataPtr data = GHOST_GetEventData(evt);
        wmWindow *win;

        /* Ghost now can call this function for life resizes, but it should return if WM didn't initialize yet.
         * Can happen on file read (especially full size window)  */
        if ((wm->initialized & WM_INIT_WINDOW) == 0) {
            return 1;
        }
        if (!ghostwin) {
            /* XXX - should be checked, why are we getting an event here, and */
            /* what is it? */
            puts("<!> event has no window");
            return 1;
        }
        else if (!GHOST_ValidWindow(g_system, ghostwin)) {
            /* XXX - should be checked, why are we getting an event here, and */
            /* what is it? */
            puts("<!> event has invalid window");
            return 1;
        }
        else {
            win = GHOST_GetWindowUserData(ghostwin);
        }

        switch (type) {
        case GHOST_kEventWindowDeactivate:
            wm_event_add_ghostevent(wm, win, type, time, data);
            win->active = 0; /* XXX */

            /* clear modifiers for inactive windows */
            win->eventstate->alt = 0;
            win->eventstate->ctrl = 0;
            win->eventstate->shift = 0;
            win->eventstate->oskey = 0;
            win->eventstate->keymodifier = 0;

            break;
        case GHOST_kEventWindowActivate:
        {
            GHOST_TEventKeyData kdata;
            wmEvent event;
            int wx, wy;
            const int keymodifier = ((query_qual(SHIFT)     ? KM_SHIFT : 0) |
                                     (query_qual(CONTROL)   ? KM_CTRL  : 0) |
                                     (query_qual(ALT)       ? KM_ALT   : 0) |
                                     (query_qual(OS)        ? KM_OSKEY : 0));

            /* Win23/GHOST modifier bug, see T40317 */
#ifndef WIN32
//#  define USE_WIN_ACTIVATE
#endif

            wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */

            win->active = 1;
//				window_handle(win, INPUTCHANGE, win->active);

            /* bad ghost support for modifier keys... so on activate we set the modifiers again */

            /* TODO: This is not correct since a modifier may be held when a window is activated...
             * better solve this at ghost level. attempted fix r54450 but it caused bug [#34255]
             *
             * For now don't send GHOST_kEventKeyDown events, just set the 'eventstate'.
             */
            kdata.ascii = '\0';
            kdata.utf8_buf[0] = '\0';

            if (win->eventstate->shift) {
                if ((keymodifier & KM_SHIFT) == 0) {
                    kdata.key = GHOST_kKeyLeftShift;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_SHIFT) {
                    win->eventstate->shift = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->ctrl) {
                if ((keymodifier & KM_CTRL) == 0) {
                    kdata.key = GHOST_kKeyLeftControl;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_CTRL) {
                    win->eventstate->ctrl = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->alt) {
                if ((keymodifier & KM_ALT) == 0) {
                    kdata.key = GHOST_kKeyLeftAlt;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_ALT) {
                    win->eventstate->alt = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->oskey) {
                if ((keymodifier & KM_OSKEY) == 0) {
                    kdata.key = GHOST_kKeyOS;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_OSKEY) {
                    win->eventstate->oskey = KM_MOD_FIRST;
                }
            }
#endif

#undef USE_WIN_ACTIVATE


            /* keymodifier zero, it hangs on hotkeys that open windows otherwise */
            win->eventstate->keymodifier = 0;

            /* entering window, update mouse pos. but no event */
            wm_get_cursor_position(win,  &wx, &wy);

            win->eventstate->x = wx;
            win->eventstate->y = wy;

            win->addmousemove = 1;   /* enables highlighted buttons */

            wm_window_make_drawable(wm, win);

            /* window might be focused by mouse click in configuration of window manager
             * when focus is not following mouse
             * click could have been done on a button and depending on window manager settings
             * click would be passed to blender or not, but in any case button under cursor
             * should be activated, so at max next click on button without moving mouse
             * would trigger it's handle function
             * currently it seems to be common practice to generate new event for, but probably
             * we'll need utility function for this? (sergey)
             */
            wm_event_init_from_window(win, &event);
            event.type = MOUSEMOVE;
            event.prevx = event.x;
            event.prevy = event.y;

            wm_event_add(win, &event);

            break;
        }
        case GHOST_kEventWindowClose:
        {
            wm_window_close(C, wm, win);
            break;
        }
        case GHOST_kEventWindowUpdate:
        {
            if (G.debug & G_DEBUG_EVENTS) {
                printf("%s: ghost redraw %d\n", __func__, win->winid);
            }

            wm_window_make_drawable(wm, win);
            WM_event_add_notifier(C, NC_WINDOW, NULL);

            break;
        }
        case GHOST_kEventWindowSize:
        case GHOST_kEventWindowMove:
        {
            GHOST_TWindowState state;
            state = GHOST_GetWindowState(win->ghostwin);
            win->windowstate = state;

            /* stop screencast if resize */
            if (type == GHOST_kEventWindowSize) {
                WM_jobs_stop(wm, win->screen, NULL);
            }

            /* win32: gives undefined window size when minimized */
            if (state != GHOST_kWindowStateMinimized) {
                GHOST_RectangleHandle client_rect;
                int l, t, r, b, scr_w, scr_h;
                int sizex, sizey, posx, posy;

                client_rect = GHOST_GetClientBounds(win->ghostwin);
                GHOST_GetRectangle(client_rect, &l, &t, &r, &b);

                GHOST_DisposeRectangle(client_rect);

                wm_get_desktopsize(&scr_w, &scr_h);
                sizex = r - l;
                sizey = b - t;
                posx = l;
                posy = scr_h - t - win->sizey;

                /*
                 * Ghost sometimes send size or move events when the window hasn't changed.
                 * One case of this is using compiz on linux. To alleviate the problem
                 * we ignore all such event here.
                 *
                 * It might be good to eventually do that at Ghost level, but that is for
                 * another time.
                 */
                if (win->sizex != sizex ||
                        win->sizey != sizey ||
                        win->posx != posx ||
                        win->posy != posy)
                {
                    win->sizex = sizex;
                    win->sizey = sizey;
                    win->posx = posx;
                    win->posy = posy;

                    /* debug prints */
                    if (G.debug & G_DEBUG_EVENTS) {
                        const char *state_str;
                        state = GHOST_GetWindowState(win->ghostwin);

                        if (state == GHOST_kWindowStateNormal) {
                            state_str = "normal";
                        }
                        else if (state == GHOST_kWindowStateMinimized) {
                            state_str = "minimized";
                        }
                        else if (state == GHOST_kWindowStateMaximized) {
                            state_str = "maximized";
                        }
                        else if (state == GHOST_kWindowStateFullScreen) {
                            state_str = "fullscreen";
                        }
                        else {
                            state_str = "<unknown>";
                        }

                        printf("%s: window %d state = %s\n", __func__, win->winid, state_str);

                        if (type != GHOST_kEventWindowSize) {
                            printf("win move event pos %d %d size %d %d\n",
                                   win->posx, win->posy, win->sizex, win->sizey);
                        }
                    }

                    wm_window_make_drawable(wm, win);
                    wm_draw_window_clear(win);
                    WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
                    WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);

#if defined(__APPLE__) || defined(WIN32)
                    /* OSX and Win32 don't return to the mainloop while resize */
                    wm_event_do_handlers(C);
                    wm_event_do_notifiers(C);
                    wm_draw_update(C);
#endif
                }
            }
            break;
        }

        case GHOST_kEventOpenMainFile:
        {
            PointerRNA props_ptr;
            wmWindow *oldWindow;
            const char *path = GHOST_GetEventData(evt);

            if (path) {
                wmOperatorType *ot = WM_operatortype_find("WM_OT_open_mainfile", false);
                /* operator needs a valid window in context, ensures
                 * it is correctly set */
                oldWindow = CTX_wm_window(C);
                CTX_wm_window_set(C, win);

                WM_operator_properties_create_ptr(&props_ptr, ot);
                RNA_string_set(&props_ptr, "filepath", path);
                WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
                WM_operator_properties_free(&props_ptr);

                CTX_wm_window_set(C, oldWindow);
            }
            break;
        }
        case GHOST_kEventDraggingDropDone:
        {
            wmEvent event;
            GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
            int wx, wy;

            /* entering window, update mouse pos */
            wm_get_cursor_position(win, &wx, &wy);
            win->eventstate->x = wx;
            win->eventstate->y = wy;

            wm_event_init_from_window(win, &event);  /* copy last state, like mouse coords */

            /* activate region */
            event.type = MOUSEMOVE;
            event.prevx = event.x;
            event.prevy = event.y;

            wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
            win->active = 1;

            wm_event_add(win, &event);


            /* make blender drop event with custom data pointing to wm drags */
            event.type = EVT_DROP;
            event.val = KM_RELEASE;
            event.custom = EVT_DATA_DRAGDROP;
            event.customdata = &wm->drags;
            event.customdatafree = 1;

            wm_event_add(win, &event);

            /* printf("Drop detected\n"); */

            /* add drag data to wm for paths: */

            if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
                GHOST_TStringArray *stra = ddd->data;
                int a, icon;

                for (a = 0; a < stra->count; a++) {
                    printf("drop file %s\n", stra->strings[a]);
                    /* try to get icon type from extension */
                    icon = ED_file_extension_icon((char *)stra->strings[a]);

                    WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0, WM_DRAG_NOP);
                    /* void poin should point to string, it makes a copy */
                    break; /* only one drop element supported now */
                }
            }

            break;
        }
        case GHOST_kEventNativeResolutionChange:
            // printf("change, pixel size %f\n", GHOST_GetNativePixelSize(win->ghostwin));

            U.pixelsize = wm_window_pixelsize(win);
            BKE_userdef_state();
            WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
            WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);

            break;
        case GHOST_kEventTrackpad:
        {
            GHOST_TEventTrackpadData *pd = data;

            wm_convert_cursor_position(win, &pd->x, &pd->y);
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }
        case GHOST_kEventCursorMove:
        {
            GHOST_TEventCursorData *cd = data;

            wm_convert_cursor_position(win, &cd->x, &cd->y);
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }
        default:
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }

    }
    return 1;
}