|
05-20-2016, 11:42 AM
|
#1
|
Human being with feelings
Join Date: May 2012
Location: PA, USA
Posts: 356
|
IGraphics - Draw on top
I know this have been discussed before, but I can't find a solution.
I need to force a draw command for a bitmap to be on top of everything in the GUI. I know that graphics are drawn based on the order they are added, but this bitmap I have is only occasionally shown. I can't add it last because the GUI is resizable, and different elements are shown depending on the layout.
Any way of doing this without modifying IGraphics?
|
|
|
05-20-2016, 03:15 PM
|
#2
|
Human being with feelings
Join Date: Dec 2015
Posts: 331
|
IControl::Hide(bool hide)? Show and hide your controls as needed?
Or maybe what you want is a single control that looks different (size, bitmap) when the GUI is resized. It's no problem to subclass a control and make its bitmap (including size) and location settable.
Last edited by earlevel; 05-20-2016 at 04:41 PM.
|
|
|
05-20-2016, 06:03 PM
|
#3
|
Human being with feelings
Join Date: May 2012
Location: PA, USA
Posts: 356
|
Thanks for the suggestion.
I should have been more descriptive. I have a drag-and-drop control. The user drags the bitmap, and drops it into another control. The functionality is working perfectly, just the drawing.
As the bitmap is dragged across the GUI, it comes in contact with all other types of controls (i.e., knobs, meters, etc.). Since some of these controls are added/removed dynamically, it is hard for the bitmap to not be drawn behind a few controls.
I was looking for some method to force a control temporarily to the top of the GUI stack. In this case, only when a user is doing the drag-and-drop function. That is why I was thinking it would be nice to have some sort of FORCE command.
|
|
|
05-20-2016, 06:28 PM
|
#4
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Well you could create one control that will be the last in your control list and then you could pass mRECT and control number of control you are dragging to this control and set it dirty. In your last control Draw function you could call:
Code:
IControl* pControl = mGraphics->GetControl(i);
pControl->Draw(mRect);
Don't forget to pass your dragged control mRECT to last control mRECT, they must be the same.
This last control will be some sort of TMP control that will always be on top. When you are creating it set rect to 0,0,0,0...
|
|
|
05-20-2016, 09:56 PM
|
#5
|
Human being with feelings
Join Date: Dec 2015
Posts: 331
|
Quote:
Originally Posted by random_id
I was looking for some method to force a control temporarily to the top of the GUI stack. In this case, only when a user is doing the drag-and-drop function. That is why I was thinking it would be nice to have some sort of FORCE command.
|
As Youlean pointed out, you can still do it the way I said. However, these answers were based on your original request, "Any way of doing this without modifying IGraphics?"
Personally, if it's as you describe, I'd modify IGraphics:: Draw. Add the ability to set a member variable (say, mFloatControl, with an accessor SetFloatControl—which you give the index of the control you want to float, or -1 for none). Then in Draw's control loop, skip mFloatControl, if set, and when the control loop finishes, draw the control of index mFloatControl. Very little code.
When you mouseDown with whatever condition on the control to allow drag, call SetFloatControl with he control's index; you could optionally change the control bitmap to highlight it, track the drag of your control as you are doing now, change the bitmap back on release (if you changed it), and SetFloatControl(-1).
|
|
|
05-21-2016, 02:44 AM
|
#6
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
|
I'm not sure if it's relevant, but a while ago I have added some code to IPlug to reorder controls on the fly. I could be persuaded to share the code...
|
|
|
05-21-2016, 05:25 AM
|
#7
|
Human being with feelings
Join Date: May 2012
Location: PA, USA
Posts: 356
|
@earlevel - Thanks for the suggestion. I think this might be something I will have to try.
Quote:
Originally Posted by Tale
I'm not sure if it's relevant, but a while ago I have added some code to IPlug to reorder controls on the fly. I could be persuaded to share the code...
|
Is this in your repo? If not, what type of persuasion do you require? Pretty Please?
|
|
|
05-21-2016, 05:51 AM
|
#8
|
Human being with feelings
Join Date: Apr 2014
Posts: 84
|
Quote:
Originally Posted by Tale
reorder controls on the fly
|
That's a good idea, I could use it!
My problem is that I want to add a right-click menu to my knob class and customize the look of this menu (half-transparent dark bg, white letters).
After reading the WDL-OL code it seems to me it is not possible without modifying the framework. Is it correct?
|
|
|
05-21-2016, 10:35 AM
|
#9
|
Human being with feelings
Join Date: May 2012
Location: PA, USA
Posts: 356
|
I managed to find a working solution.
In IControl, I added a DrawPriority variable and Set and Get methods. In the constructor, I set the value to 0.
In the IGraphics:: Draw method, I enclosed the entire drawing loop with another loop that goes from 0 to 1. Each control's priority is checked, so all of the 0 controls are drawn first, and then the 1s are drawn.
In my control that has the drag-and-drop, I set the priority to 1 when the user is dragging, and then return the value to 0 with the OnMouseUp(). This allows the bitmap to be drawn on top of everything.
I am not sure what type of performance hit this takes, since it is one more loop during each draw. I haven't tested that.
|
|
|
05-21-2016, 12:21 PM
|
#10
|
Human being with feelings
Join Date: Feb 2009
Posts: 60
|
Quote:
Originally Posted by random_id
I am not sure what type of performance hit this takes, since it is one more loop during each draw. I haven't tested that.
|
One way to reduce the overhead of the second loop is by counting the number of priority 1 controls (or setting a bool flag if any are found) in the priority 0 loop. Then do the priority 1 loop only in cases where there are any controls in a priority 1 state. You could even improve that a little by remembering the index of the first control found in the priority 1 state and starting the priority 1 loop at that index. Could even record first and last index of priority 1 controls and loop over just that range ...
|
|
|
05-22-2016, 02:46 AM
|
#11
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
|
Quote:
Originally Posted by random_id
Is this in your repo? If not, what type of persuasion do you require? Pretty Please?
|
Time, and effort mostly... It is not in my public repository (because it is from a closed-source project), so I have to look it up, extract it in some usuable way.
Maybe I will post it at GitHub at some point, but for now here is a diff:
Code:
diff --git a/WDL/IPlug/IGraphics.cpp b/WDL/IPlug/IGraphics.cpp
index e36cc27..a8808d9 100644
--- a/WDL/IPlug/IGraphics.cpp
+++ b/WDL/IPlug/IGraphics.cpp
@@ -260,6 +260,19 @@ void IGraphics::AttachKeyCatcher(IControl* pControl)
mKeyCatcher = pControl;
}
+int IGraphics::ReorderControl(int controlIdx, int delta)
+{
+ int newIdx = controlIdx + delta, n = mControls.GetSize();
+ if (controlIdx >= 0 && controlIdx < n && newIdx >= 0 && newIdx < n)
+ {
+ IControl* tmp = mControls.Get(controlIdx);
+ mControls.Set(controlIdx, mControls.Get(newIdx));
+ mControls.Set(newIdx, tmp);
+ return newIdx;
+ }
+ return controlIdx;
+}
+
void IGraphics::HideControl(int paramIdx, bool hide)
{
int i, n = mControls.GetSize();
diff --git a/WDL/IPlug/IGraphics.h b/WDL/IPlug/IGraphics.h
index b7b4afe..7646cad 100644
--- a/WDL/IPlug/IGraphics.h
+++ b/WDL/IPlug/IGraphics.h
@@ -155,6 +155,12 @@ public:
IControl* GetControl(int idx) { return mControls.Get(idx); }
int GetNControls() { return mControls.GetSize(); }
+
+ // Returns control index, or -1 if not found.
+ int FindControl(IControl* pControl) { return mControls.Find(pControl); }
+ // Swaps controlIdx and newIdx = controlIdx + delta, returns newIdx.
+ int ReorderControl(int controlIdx, int delta);
+
void HideControl(int paramIdx, bool hide);
void GrayOutControl(int paramIdx, bool gray);
|
|
|
05-22-2016, 03:25 AM
|
#12
|
Human being with feelings
Join Date: Apr 2014
Posts: 84
|
Quote:
Originally Posted by random_id
I am not sure what type of performance hit this takes, since it is one more loop during each draw. I haven't tested that.
|
I think, actually if this drag-and-drop activity is not one of the main and the most frequent usecases, and if there are not that much other different "special" GUI actions, then adding one more loop to the IGraphics: raw() is not well justified, because you have to a) modify the framework and loose portability, and b) the complexity of this solution is comparable to the Youlean's one.
So if it's possible to implement Youlean's suggestion in a bug-free way (like no unreasonable freezing of the GUI or something), it'd be better. At least I'll try this way first and see how it goes.
Parser thinks this is funny.
Upd: Some more thoughts to consider before implementing the reordering of the draw list.
As a pro-argument, protected mControls is a WDL_PtrList that has all the methods to easily reorder itself (as Tale does), it could be very useful sometimes, but IGraphics doesn't make use of them.
As a con- one, if for some reason you have your controls stacked on the GUI (small ones on top of a bigger one, for instance. Looks nice sometimes) you'll get it all messed up.
Last edited by 1eqinfinity; 05-22-2016 at 05:06 AM.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 05:46 PM.
|