Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c')
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
new file mode 100644
index 00000000000..7e57b48c77c
--- /dev/null
+++ b/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
@@ -0,0 +1,262 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file button2d_manipulator.c
+ * \ingroup wm
+ *
+ * \name Button Manipulator
+ *
+ * 2D Manipulator, also works in 3D views.
+ *
+ * \brief Single click button action for use in manipulator groups.
+ *
+ * \note Currently only basic icon & vector-shape buttons are supported.
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_select.h"
+#include "GPU_batch.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+
+/* own includes */
+#include "../manipulator_geometry.h"
+#include "../manipulator_library_intern.h"
+
+typedef struct ButtonManipulator2D {
+ wmManipulator manipulator;
+ bool is_init;
+ /* Use an icon or shape */
+ int icon;
+ Gwn_Batch *shape_batch[2];
+} ButtonManipulator2D;
+
+#define CIRCLE_RESOLUTION 32
+
+/* -------------------------------------------------------------------- */
+
+static void button2d_geom_draw_backdrop(
+ const wmManipulator *mpr, const float color[4], const bool select)
+{
+ glLineWidth(mpr->line_width);
+
+ Gwn_VertFormat *format = immVertexFormat();
+ uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ immUniformColor4fv(color);
+
+ /* TODO, other draw styles */
+ imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
+
+ immUnbindProgram();
+
+ UNUSED_VARS(select);
+}
+
+static void button2d_draw_intern(
+ const bContext *UNUSED(C), wmManipulator *mpr,
+ const bool select, const bool highlight)
+{
+ ButtonManipulator2D *button = (ButtonManipulator2D *)mpr;
+
+ if (button->is_init == false) {
+ button->is_init = true;
+ PropertyRNA *prop = RNA_struct_find_property(mpr->ptr, "icon");
+ if (RNA_property_is_set(mpr->ptr, prop)) {
+ button->icon = RNA_property_enum_get(mpr->ptr, prop);
+ }
+ else {
+ prop = RNA_struct_find_property(mpr->ptr, "shape");
+ const uint polys_len = RNA_property_string_length(mpr->ptr, prop);
+ /* We shouldn't need the +1, but a NULL char is set. */
+ char *polys = MEM_mallocN(polys_len + 1, __func__);
+ RNA_property_string_get(mpr->ptr, prop, polys);
+ button->shape_batch[0] = GPU_batch_wire_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
+ button->shape_batch[1] = GPU_batch_tris_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
+ MEM_freeN(polys);
+ }
+ }
+
+ float color[4];
+ float matrix_final[4][4];
+
+ manipulator_color_get(mpr, highlight, color);
+ WM_manipulator_calc_matrix_final(mpr, matrix_final);
+
+ gpuPushMatrix();
+ gpuMultMatrix(matrix_final);
+
+ glEnable(GL_BLEND);
+
+ if (select == false) {
+ if (button->shape_batch[0] != NULL) {
+ glEnable(GL_LINE_SMOOTH);
+ glLineWidth(1.0f);
+ for (uint i = 0; i < ARRAY_SIZE(button->shape_batch) && button->shape_batch[i]; i++) {
+ /* Invert line color for wire. */
+ color[0] = 1.0f - color[0];
+ color[1] = 1.0f - color[1];
+ color[2] = 1.0f - color[2];
+
+ GWN_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR);
+ GWN_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color));
+ GWN_batch_draw(button->shape_batch[i]);
+ }
+ glDisable(GL_LINE_SMOOTH);
+ gpuPopMatrix();
+ }
+ else if (button->icon != ICON_NONE) {
+ button2d_geom_draw_backdrop(mpr, color, select);
+ gpuPopMatrix();
+ UI_icon_draw(
+ mpr->matrix_basis[3][0] - (ICON_DEFAULT_WIDTH / 2.0) * U.ui_scale,
+ mpr->matrix_basis[3][1] - (ICON_DEFAULT_HEIGHT / 2.0) * U.ui_scale,
+ button->icon);
+ }
+ else {
+ gpuPopMatrix();
+ }
+ }
+ glDisable(GL_BLEND);
+}
+
+static void manipulator_button2d_draw_select(const bContext *C, wmManipulator *mpr, int select_id)
+{
+ GPU_select_load_id(select_id);
+ button2d_draw_intern(C, mpr, true, false);
+}
+
+static void manipulator_button2d_draw(const bContext *C, wmManipulator *mpr)
+{
+ const bool is_highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0;
+
+ glEnable(GL_BLEND);
+ button2d_draw_intern(C, mpr, false, is_highlight);
+ glDisable(GL_BLEND);
+}
+
+static int manipulator_button2d_test_select(
+ bContext *C, wmManipulator *mpr, const wmEvent *event)
+{
+ float point_local[2];
+
+ if (0) {
+ /* correct, but unnecessarily slow. */
+ if (manipulator_window_project_2d(
+ C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false)
+ {
+ return -1;
+ }
+ }
+ else {
+ copy_v2_v2(point_local, (float [2]){UNPACK2(event->mval)});
+ sub_v2_v2(point_local, mpr->matrix_basis[3]);
+ mul_v2_fl(point_local, 1.0f / (mpr->scale_basis * U.ui_scale));
+ }
+ /* The 'mpr->scale_final' is already applied when projecting. */
+ if (len_squared_v2(point_local) < 1.0f) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static int manipulator_button2d_cursor_get(wmManipulator *mpr)
+{
+ if (RNA_boolean_get(mpr->ptr, "show_drag")) {
+ return BC_NSEW_SCROLLCURSOR;
+ }
+ return CURSOR_STD;
+}
+
+static void manipulator_button2d_free(wmManipulator *mpr)
+{
+ ButtonManipulator2D *shape = (ButtonManipulator2D *)mpr;
+
+ for (uint i = 0; i < ARRAY_SIZE(shape->shape_batch); i++) {
+ GWN_BATCH_DISCARD_SAFE(shape->shape_batch[i]);
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Button Manipulator API
+ *
+ * \{ */
+
+static void MANIPULATOR_WT_button_2d(wmManipulatorType *wt)
+{
+ /* identifiers */
+ wt->idname = "MANIPULATOR_WT_button_2d";
+
+ /* api callbacks */
+ wt->draw = manipulator_button2d_draw;
+ wt->draw_select = manipulator_button2d_draw_select;
+ wt->test_select = manipulator_button2d_test_select;
+ wt->cursor_get = manipulator_button2d_cursor_get;
+ wt->free = manipulator_button2d_free;
+
+ wt->struct_size = sizeof(ButtonManipulator2D);
+
+ /* rna */
+ PropertyRNA *prop;
+ prop = RNA_def_property(wt->srna, "icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_icon_items);
+
+ /* Passed to 'GPU_batch_from_poly_2d_encoded' */
+ RNA_def_property(wt->srna, "shape", PROP_STRING, PROP_BYTESTRING);
+
+ /* Currently only used for cursor display. */
+ RNA_def_boolean(wt->srna, "show_drag", true, "Show Drag", "");
+}
+
+void ED_manipulatortypes_button_2d(void)
+{
+ WM_manipulatortype_append(MANIPULATOR_WT_button_2d);
+}
+
+/** \} */ // Button Manipulator API