浏览代码

UI: Change preview handles/outline and add hover

VodBox 6 年之前
父节点
当前提交
6c880fb3c8
共有 4 个文件被更改,包括 160 次插入36 次删除
  1. 12 0
      UI/source-tree.cpp
  2. 11 0
      UI/source-tree.hpp
  3. 135 36
      UI/window-basic-preview.cpp
  4. 2 0
      UI/window-basic-preview.hpp

+ 12 - 0
UI/source-tree.cpp

@@ -35,6 +35,7 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
 	  sceneitem    (sceneitem_)
 {
 	setAttribute(Qt::WA_TranslucentBackground);
+	setMouseTracking(true);
 
 	obs_source_t *source = obs_sceneitem_get_source(sceneitem);
 	const char *name = obs_source_get_name(source);
@@ -911,6 +912,8 @@ SourceTree::SourceTree(QWidget *parent_) : QListView(parent_)
 		"*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" \
 		"*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" \
 		"*[bgColor=\"8\"]{background-color:rgba(255,255,255,33%);}"));
+
+	setMouseTracking(true);
 }
 
 void SourceTree::ResetWidgets()
@@ -1264,6 +1267,15 @@ void SourceTree::dropEvent(QDropEvent *event)
 	QListView::dropEvent(event);
 }
 
+void SourceTree::mouseMoveEvent(QMouseEvent *event)
+{
+	QPoint pos = event->pos();
+	SourceTreeItem *item = qobject_cast<SourceTreeItem *>
+		(childAt(pos));
+
+	currentHover = item;
+}
+
 void SourceTree::selectionChanged(
 		const QItemSelection &selected,
 		const QItemSelection &deselected)

+ 11 - 0
UI/source-tree.hpp

@@ -142,6 +142,8 @@ class SourceTree : public QListView {
 		return reinterpret_cast<SourceTreeModel *>(model());
 	}
 
+	SourceTreeItem *currentHover;
+
 public:
 	inline SourceTreeItem *GetItemWidget(int idx)
 	{
@@ -149,6 +151,14 @@ public:
 		return reinterpret_cast<SourceTreeItem *>(widget);
 	}
 
+	inline SourceTreeItem *GetHoveredItem()
+	{
+		if (underMouse()) {
+			return currentHover;
+		}
+		return nullptr;
+	}
+
 	explicit SourceTree(QWidget *parent = nullptr);
 
 	inline bool IgnoreReorder() const {return ignoreReorder;}
@@ -175,6 +185,7 @@ public slots:
 protected:
 	virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
 	virtual void dropEvent(QDropEvent *event) override;
+	virtual void mouseMoveEvent(QMouseEvent *event) override;
 
 	virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
 };

+ 135 - 36
UI/window-basic-preview.cpp

@@ -612,6 +612,9 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
 		mouseDown    = false;
 		mouseMoved   = false;
 		cropping     = false;
+
+		OBSSceneItem item = GetItemAtPos(pos, true);
+		hovered = item;
 	}
 }
 
@@ -1158,6 +1161,8 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
 		return;
 
 	if (mouseDown) {
+		hovered = nullptr;
+
 		vec2 pos = GetMouseEventPos(event);
 
 		if (!mouseMoved && !mouseOverItems &&
@@ -1194,10 +1199,22 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
 		}
 
 		mouseMoved = true;
+	} else {
+		vec2 pos = GetMouseEventPos(event);
+		OBSSceneItem item = GetItemAtPos(pos, true);
+
+		hovered = item;
 	}
 }
 
-static void DrawCircleAtPos(float x, float y)
+void OBSBasicPreview::leaveEvent(QEvent *event)
+{
+	hovered = nullptr;
+
+	UNUSED_PARAMETER(event);
+}
+
+static void DrawSquareAtPos(float x, float y)
 {
 	struct vec3 pos;
 	vec3_set(&pos, x, y, 0.0f);
@@ -1209,11 +1226,73 @@ static void DrawCircleAtPos(float x, float y)
 	gs_matrix_push();
 	gs_matrix_identity();
 	gs_matrix_translate(&pos);
-	gs_matrix_scale3f(HANDLE_RADIUS, HANDLE_RADIUS, 1.0f);
-	gs_draw(GS_LINESTRIP, 0, 0);
+
+	gs_matrix_translate3f(-HANDLE_RADIUS, -HANDLE_RADIUS, 0.0f);
+	gs_matrix_scale3f(HANDLE_RADIUS*2, HANDLE_RADIUS*2, 1.0f);
+	gs_draw(GS_TRISTRIP, 0, 0);
 	gs_matrix_pop();
 }
 
+static void DrawLine(float x1, float y1, float x2, float y2, float thickness)
+{
+	struct matrix4 matrix;
+	gs_matrix_get(&matrix);
+
+	float ySide = (y1 == y2) ? (y1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
+	float xSide = (x1 == x2) ? (x1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
+
+	gs_render_start(true);
+
+	gs_vertex2f(x1, y1);
+	gs_vertex2f(x1 + (xSide * (thickness / matrix.x.x)),
+		y1 + (ySide * (thickness / matrix.y.y)));
+	gs_vertex2f(x2 + (xSide * (thickness / matrix.x.x)),
+		y2 + (ySide * (thickness / matrix.y.y)));
+	gs_vertex2f(x2, y2);
+	gs_vertex2f(x1, y1);
+
+	gs_vertbuffer_t *line = gs_render_save();
+
+	gs_load_vertexbuffer(line);
+	gs_draw(GS_TRISTRIP, 0, 0);
+	gs_vertexbuffer_destroy(line);
+}
+
+static void DrawRect(float thickness)
+{
+	struct matrix4 matrix;
+	gs_matrix_get(&matrix);
+
+	gs_render_start(true);
+
+	gs_vertex2f(0.0f, 0.0f);
+	gs_vertex2f(0.0f + (thickness / matrix.x.x), 0.0f);
+	gs_vertex2f(0.0f + (thickness / matrix.x.x), 1.0f);
+	gs_vertex2f(0.0f, 1.0f);
+	gs_vertex2f(0.0f, 0.0f);
+	gs_vertex2f(0.0f, 1.0f);
+	gs_vertex2f(0.0f, 1.0f - (thickness / matrix.y.y));
+	gs_vertex2f(1.0f, 1.0f - (thickness / matrix.y.y));
+	gs_vertex2f(1.0f, 1.0f);
+	gs_vertex2f(0.0f, 1.0f);
+	gs_vertex2f(1.0f, 1.0f);
+	gs_vertex2f(1.0f - (thickness / matrix.x.x), 1.0f);
+	gs_vertex2f(1.0f - (thickness / matrix.x.x), 0.0f);
+	gs_vertex2f(1.0f, 0.0f);
+	gs_vertex2f(1.0f, 1.0f);
+	gs_vertex2f(1.0f, 0.0f);
+	gs_vertex2f(1.0f, 0.0f + (thickness / matrix.y.y));
+	gs_vertex2f(0.0f, 0.0f + (thickness / matrix.y.y));
+	gs_vertex2f(0.0f, 0.0f);
+	gs_vertex2f(1.0f, 0.0f);
+
+	gs_vertbuffer_t *rect = gs_render_save();
+
+	gs_load_vertexbuffer(rect);
+	gs_draw(GS_TRISTRIP, 0, 0);
+	gs_vertexbuffer_destroy(rect);
+}
+
 static inline bool crop_enabled(const obs_sceneitem_crop *crop)
 {
 	return crop->left > 0  ||
@@ -1327,10 +1406,17 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
 		gs_matrix_pop();
 	}
 
-	if (!obs_sceneitem_selected(item))
-		return true;
-
 	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
+	OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
+
+	SourceTreeItem *hovItem = main->ui->sources->GetHoveredItem();
+	SourceTreeItem *curItem = main->GetItemWidgetFromSceneItem(item);
+
+	bool hover = (curItem && hovItem == curItem) || prev->hovered == item;
+	bool selected = obs_sceneitem_selected(item);
+
+	if (!selected && !hover)
+		return true;
 
 	matrix4 boxTransform;
 	matrix4 invBoxTransform;
@@ -1344,6 +1430,14 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
 		{{{1.f, 1.f, 0.f}}},
 	};
 
+	vec4 red;
+	vec4 green;
+	vec4 blue;
+
+	vec4_set(&red, 1.0f, 0.0f, 0.0f, 1.0f);
+	vec4_set(&green, 0.0f, 1.0f, 0.0f, 1.0f);
+	vec4_set(&blue, 0.0f, 0.5f, 1.0f, 1.0f);
+
 	bool visible = std::all_of(std::begin(bounds), std::end(bounds),
 			[&](const vec3 &b)
 	{
@@ -1359,45 +1453,50 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
 	obs_transform_info info;
 	obs_sceneitem_get_info(item, &info);
 
-	gs_load_vertexbuffer(main->circle);
-
 	gs_matrix_push();
 	gs_matrix_mul(&boxTransform);
 
-	DrawCircleAtPos(0.0f, 0.0f);
-	DrawCircleAtPos(0.0f, 1.0f);
-	DrawCircleAtPos(1.0f, 0.0f);
-	DrawCircleAtPos(1.0f, 1.0f);
-	DrawCircleAtPos(0.5f, 0.0f);
-	DrawCircleAtPos(0.0f, 0.5f);
-	DrawCircleAtPos(0.5f, 1.0f);
-	DrawCircleAtPos(1.0f, 0.5f);
-
 	obs_sceneitem_crop crop;
 	obs_sceneitem_get_crop(item, &crop);
 
+	gs_effect_t *eff = gs_get_effect();
+	gs_eparam_t *colParam = gs_effect_get_param_by_name(eff, "color");
+
 	if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) {
-		vec4 color;
-		gs_effect_t *eff = gs_get_effect();
-		gs_eparam_t *param = gs_effect_get_param_by_name(eff, "color");
-
-#define DRAW_SIDE(side, vb) \
-		if (crop.side > 0) \
-			vec4_set(&color, 0.0f, 1.0f, 0.0f, 1.0f); \
-		else \
-			vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f); \
-		gs_effect_set_vec4(param, &color); \
-		gs_load_vertexbuffer(main->vb); \
-		gs_draw(GS_LINESTRIP, 0, 0);
-
-		DRAW_SIDE(left,   boxLeft);
-		DRAW_SIDE(top,    boxTop);
-		DRAW_SIDE(right,  boxRight);
-		DRAW_SIDE(bottom, boxBottom);
+#define DRAW_SIDE(side, x1, y1, x2, y2) \
+		if (hover && !selected) \
+			gs_effect_set_vec4(colParam, &blue); \
+		else if (crop.side > 0) \
+			gs_effect_set_vec4(colParam, &green); \
+		DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2); \
+		gs_effect_set_vec4(colParam, &red);
+
+		DRAW_SIDE(left,   0.0f, 0.0f, 0.0f, 1.0f);
+		DRAW_SIDE(top,    0.0f, 0.0f, 1.0f, 0.0f);
+		DRAW_SIDE(right,  1.0f, 0.0f, 1.0f, 1.0f);
+		DRAW_SIDE(bottom, 0.0f, 1.0f, 1.0f, 1.0f);
 #undef DRAW_SIDE
 	} else {
-		gs_load_vertexbuffer(main->box);
-		gs_draw(GS_LINESTRIP, 0, 0);
+		if (!selected) {
+			gs_effect_set_vec4(colParam, &blue);
+			DrawRect(HANDLE_RADIUS / 2);
+		} else {
+			DrawRect(HANDLE_RADIUS / 2);
+		}
+	}
+
+	gs_load_vertexbuffer(main->box);
+	gs_effect_set_vec4(colParam, &red);
+
+	if (selected) {
+		DrawSquareAtPos(0.0f, 0.0f);
+		DrawSquareAtPos(0.0f, 1.0f);
+		DrawSquareAtPos(1.0f, 0.0f);
+		DrawSquareAtPos(1.0f, 1.0f);
+		DrawSquareAtPos(0.5f, 0.0f);
+		DrawSquareAtPos(0.0f, 0.5f);
+		DrawSquareAtPos(0.5f, 1.0f);
+		DrawSquareAtPos(1.0f, 0.5f);
 	}
 
 	gs_matrix_pop();

+ 2 - 0
UI/window-basic-preview.hpp

@@ -56,6 +56,7 @@ private:
 	bool         locked         = false;
 	bool         scrollMode     = false;
 	bool         fixedScaling   = false;
+	OBSSceneItem hovered        = nullptr;
 	int32_t      scalingLevel   = 0;
 	float        scalingAmount  = 1.0f;
 
@@ -98,6 +99,7 @@ public:
 	virtual void mousePressEvent(QMouseEvent *event) override;
 	virtual void mouseReleaseEvent(QMouseEvent *event) override;
 	virtual void mouseMoveEvent(QMouseEvent *event) override;
+	virtual void leaveEvent(QEvent *event) override;
 
 	void DrawOverflow();
 	void DrawSceneEditing();