COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :
Old 05-20-2016, 11:42 AM   #1
random_id
Human being with feelings
 
random_id's Avatar
 
Join Date: May 2012
Location: PA, USA
Posts: 356
Default 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?
__________________
Website: LVC-Audio
random_id is offline   Reply With Quote
Old 05-20-2016, 03:15 PM   #2
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

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.
earlevel is offline   Reply With Quote
Old 05-20-2016, 06:03 PM   #3
random_id
Human being with feelings
 
random_id's Avatar
 
Join Date: May 2012
Location: PA, USA
Posts: 356
Default

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.
__________________
Website: LVC-Audio
random_id is offline   Reply With Quote
Old 05-20-2016, 06:28 PM   #4
Youlean
Human being with feelings
 
Youlean's Avatar
 
Join Date: May 2015
Location: Serbia
Posts: 654
Default

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...
Youlean is offline   Reply With Quote
Old 05-20-2016, 09:56 PM   #5
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by random_id View Post
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).
earlevel is offline   Reply With Quote
Old 05-21-2016, 02:44 AM   #6
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
Default

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...
Tale is offline   Reply With Quote
Old 05-21-2016, 05:25 AM   #7
random_id
Human being with feelings
 
random_id's Avatar
 
Join Date: May 2012
Location: PA, USA
Posts: 356
Default

@earlevel - Thanks for the suggestion. I think this might be something I will have to try.


Quote:
Originally Posted by Tale View Post
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?
__________________
Website: LVC-Audio
random_id is offline   Reply With Quote
Old 05-21-2016, 05:51 AM   #8
1eqinfinity
Human being with feelings
 
Join Date: Apr 2014
Posts: 84
Default

Quote:
Originally Posted by Tale View Post
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?
__________________
soundcloud.com/crimsonbrain
1eqinfinity is offline   Reply With Quote
Old 05-21-2016, 10:35 AM   #9
random_id
Human being with feelings
 
random_id's Avatar
 
Join Date: May 2012
Location: PA, USA
Posts: 356
Default

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.
__________________
Website: LVC-Audio
random_id is offline   Reply With Quote
Old 05-21-2016, 12:21 PM   #10
tonecarver
Human being with feelings
 
Join Date: Feb 2009
Posts: 60
Default

Quote:
Originally Posted by random_id View Post
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 ...
tonecarver is offline   Reply With Quote
Old 05-22-2016, 02:46 AM   #11
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
Default

Quote:
Originally Posted by random_id View Post
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);
Tale is offline   Reply With Quote
Old 05-22-2016, 03:25 AM   #12
1eqinfinity
Human being with feelings
 
Join Date: Apr 2014
Posts: 84
Default

Quote:
Originally Posted by random_id View Post
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.
__________________
soundcloud.com/crimsonbrain

Last edited by 1eqinfinity; 05-22-2016 at 05:06 AM.
1eqinfinity is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 05:46 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.