scide: LookupDialog - redo lookup on classes after partial lookup
[supercollider.git] / HelpSource / Guides / News-Qt-GUI.schelp
blob028e84ddbff5e373c4d9dd246257dea38d02fa66
1 title:: What's new in Qt GUI
2 summary:: A summary of new features and differences in Qt GUI
3 categories:: GUI, News
5 This document is intended for those already familiar with graphical user interface programming in SuperCollider. If you are new to this topic, you are suggested to first read the link::Guides/GUI-Introduction::.
7 For the purpose of this guide, let's switch to the Qt GUI:
9 code::
10 GUI.qt
13 SECTION:: View hierarchy
15 SUBSECTION:: Every view can be a window
17 Every view can be displayed as a window on its own, without the use of the Window class. Hence, most methods that are present in Window, are also present in View.
19 For example, you can display any view without embedding it in a Window or another container view using the link::Classes/View#-front:: method. For this reason, it is valid to omit the 'parent' argument at view construction - any view without a parent can be shown as a window:
21 code::
23 x = SoundFileView().front;
24 x.load(Platform.resourceDir +/+ "sounds/a11wlk01.wav");
28 SUBSECTION:: Every view can be a container
30 Every view can contain other views (i.e. act as their parent). For this reason, if you want to group several views together, you can simply use a View as the container:
32 code::
34 v=View(bounds:300@300);
35 5.do { |i|
36     Slider(v).moveTo(i * 25 + 10, 10);
38 v.front;
43 SECTION:: Layout management
45 The Qt layout system allows you to forget about pixels - it manages the size and position of child views in a parent automatically.
47 SUBSECTION:: Intrinsic view sizes
49 You may have noticed in the examples above that, besides omitting the code::parent:: argument, we sometimes omitted the code::bounds:: argument as well, at view construction. This is possible because views have intrinsically defined preferred and minimum sizes. See the link::Guides/GUI-Layout-Management#intrinsic_view_sizes#Intrinsic view sizes:: section of the Layout Management guide.
51 SUBSECTION:: Layout classes
53 A collection of layout classes allows you to associate one of them with a parent view and several child views, and it will manage positions and sizes of the children automatically according to their size preferences and constraints. It will also do that dynamically, as you resize the window:
55 code::
57 w = Window.new(bounds:Rect(100,100,300,80)).layout_(
58     VLayout (
59         HLayout(
60             Button().states_([["Super"]]),
61             TextField().string_("Collider")
62         ),
63         Button().states_([["SuperCollider"]])
64     )
65 ).front;
69 See the link::Guides/GUI-Layout-Management:: guide for detailed explanation.
72 SECTION:: Color management
74 SUBSECTION:: The palette
76 Qt has the notion of the color palette - a collection of colors from wich the views pick when drawing themselves. It is represented by the link::Classes/QPalette:: class, and can be set on a view using link::Classes/View#-palette::.
78 By default, a window will get the global palette ( link::Classes/QtGUI#*palette:: ), and the palette is inherited by child views from their parent. Thus, changing the parent's palette will also affect its children, unless the palette has been overridden on a particular child. You can easily change the appearance of the whole GUI by changing the global palette.
80 SUBSECTION:: Predefined palettes
82 There are two predefined palettes ( link::Classes/QPalette#*light:: and link::Classes/QPalette#*dark:: ), and you can also access the native palette of your operating system ( link::Classes/QPalette#*system:: ):
84 Try changing the global palette with the code below; if you have the Qt GUI active, this will affect this window as well:
86 code::
87 QtGUI.palette = QPalette.dark;
89 QtGUI.palette = QPalette.light;
91 QtGUI.palette = QPalette.system;
94 SECTION:: View actions and hooks
96 SUBSECTION:: Mouse and key event propagation
98 In addition to key events, mouse events can also propagate to parent views.
100 Also, the control over event propagation works differently in Qt. See link::Classes/View#key_and_mouse_event_propagation#Key and mouse event propagation:: for detailed explanation.
102 Moreover, you can make a view transparent for mouse events using link::Classes/View#-acceptsMouse::, which will forward all mouse events to the view under, regardless of whether they are in a parent-child relationship.
104 code::
106 var win, parent, child, sibling1, sibling2;
107 win = Window(bounds:Rect(30,30,300,300));
108 parent = Slider2D(win, win.bounds.moveTo(0,0).insetBy(50,50));
110 // A StaticText will propagate mouse clicks to parent by default:
111 child = StaticText(parent, Rect(100,-50,150,150))
112     .align_(\bottomLeft)
113     .string_("\npropagate\nto\nSlider2D")
114     .background_(Color.red.alpha_(0.4));
116 // This StaticText is not a child of Slider2D so will propagate mouse
117 // clicks to the window instead:
118 sibling1 = StaticText(win, Rect(0,0,150,150))
119     .align_(\topLeft)
120     .string_("propagate\nto\nWindow")
121     .background_(Color.cyan.alpha_(0.4));
123 // This StaticText is not a child of Slider2D, but is made transparent for mouse events:
124 sibling2 = StaticText(win, Rect(150,150,150,150))
125     .align_(\bottomRight)
126     .string_("ignore")
127     .background_(Color.green.alpha_(0.4))
128     .acceptsMouse_(false);
129 win.view.mouseDownAction = { win.background = Color.red(0.6) };
130 win.view.mouseUpAction = { win.view.palette = QPalette() };
131 win.front;
135 SUBSECTION:: Extended mouse interaction
137 Many Qt views already implement some kind of strong::mouse wheel:: interaction. For example, you can scroll a ScrollView, ListView and TreeView using the mouse wheel. You can also change the value of a Slider or a Knob using the mouse wheel. In addition, you can assign an action of your own to the mouse wheel event using link::Classes/View#-mouseWheelAction:::
139 There's another two handy new mouse actions triggered when the strong::mouse enters or leaves:: the view: link::Classes/View#-mouseEnterAction:: and link::Classes/View#-mouseLeaveAction:::.
141 code::
143 var val = 1.0;
144 t=StaticText(bounds:Rect(30,30,100,100))
145     .font_(Font(size:25))
146     .align_(\center)
147     .string_(val.asString)
148     .stringColor_(Color.red)
149     .background_(Color.black)
150     .front;
151 t.mouseEnterAction = { t.background = Color.white };
152 t.mouseLeaveAction = { t.background = Color.black };
153 t.mouseWheelAction = { |v,x,y,mod,dx,dy|
154     if(dy > 0) { val = val + 0.05 } { val = val - 0.05 };
155     val = val.clip(0,2).round(0.01);
156     t.string = val.asString;
157     t.stringColor = Color.red(val);
164 SUBSECTION:: Hooks for position and size change
166 Since views can be automatically repositioned and resized by link::#layout_management#layouts::, or by the user (if they are windows), it may come handy to make your view respond to these changes using link::Classes/View#-onMove:: and link::Classes/View#-onResize::.
168 code::
170 var view, update;
171 update = { |v|
172     var bounds = v.bounds;
173     v.string = "%@%\n%x%".format(
174         bounds.left,
175         bounds.top,
176         bounds.height,
177         bounds.width
178     );
181 x = StaticText(bounds:Rect(100,100,200,200)).align_(\center).font_(Font(size:25));
182 x.onMove = update;
183 x.onResize = update;
184 update.(x);
186 x.front;
190 SECTION:: Enhancements
192 SUBSECTION:: Stethoscope
194 Qt brings a new implementation of link::Classes/Stethoscope:: that uses emphasis::shared memory:: to allow highly efficient monitoring of buses on any strong::local server::.
196 All the 'scope' methods of various classes (like Server, Bus, Function, etc.) are wired to this new implementation, so you don't need to worry about instantiating a Stethoscope yourself.
198 code::
199 Server.local.scope;
202 SUBSECTION:: SoundFileView
204 link::Classes/SoundFileView:: has strong::infinite display resolution::. This means you can always zoom into the waveform until you see a single sound frame.
206 It also offers convenient strong::mouse interaction:: for zooming in and scrolling:
207 list::
208 ## shift + right-click + mouse-up/down = strong::zoom::
209 ## right-click + mouse-left/right = strong::scroll::
212 code::
214 var x = SoundFileView().front;
215 x.load(Platform.resourceDir +/+ "sounds/a11wlk01.wav");
219 Alternatively to displaying a soundfile, you can allocate an empty amount of display frames, and fill it strong::part by part:: with data to display (see documentation of link::Classes/SoundFileView#-alloc:: and link::Classes/SoundFileView#-set::). This allows, for example, to implement efficient monitoring of recording into a Buffer.
221 code::
223 var v, s;
224 v = SoundFileView().front;
225 s = Signal.sineFill(1000, 1.0/[1,2,3,4]);
226 v.alloc(5000, samplerate: 500);
227 3.do { |i| v.set( i * 2000, s * (1/(i+1)) ) };
231 SUBSECTION:: EnvelopeView
233 link::Classes/EnvelopeView:: offers two different strong::display styles::: in addition to traditional style where nodes are drawn as rectangles with labels inside, it can draw nodes as small dots, with labels next to them. See link::Classes/EnvelopeView#-style::.
235 code::
237 var w, e, m;
238 e = EnvelopeView()
239     .value_([[0,0.4,0.6,1.0],[0,0.7,0.5,0.56]])
240     .strings_(["alpha", "beta", "gamma", "delta"])
241     .thumbWidth_(60)
242     .style_(\dots);
243 m = PopUpMenu()
244     .items_(["Dot Style", "Rect Style"])
245     .action_({e.style = m.value});
246 w = Window()
247     .layout_(VLayout(m,e))
248     .front;
252 You can enforce a strong::strict order of nodes:: on the time axis. In this case, a node can not move to position before the previous node, or after the next node. See link::Classes/EnvelopeView#-keepHorizontalOrder:: and the example below.
254 You can also control how a strong::selection of nodes:: behaves when it is strong::moved::: it can either keep its form rigidly and block all movement when meeting view edges or other nodes, or it can adjust its form to the obstacles, allowing the movement of those nodes that are not blocked individually. See link::Classes/EnvelopeView#-elasticSelection:: and the following example.
256 Example: try selecting several nodes (by clicking on them with Shift key pressed) and moving them around, then use the menu to switch the way selection behaves, and repeat:
258 code::
260 var w, e, m;
261 e = EnvelopeView()
262     .value_([
263         [0, 0.1, 0.3, 0.4, 0.55, 0.7, 1.0],
264         [0, 1.0, 0.7, 0.3, 0.5, 0.2, 0]
265     ])
266     .keepHorizontalOrder_(true)
267     .elasticSelection_(true)
268     .front;
269 m = PopUpMenu()
270     .items_(["Elastic Selection", "Rigid Selection"])
271     .action_({e.elasticSelection = m.value == 0});
272 w = Window()
273     .layout_(VLayout(m,e))
274     .front;
278 SUBSECTION:: ScrollView
280 link::Classes/ScrollView:: allows to strong::replace the canvas:: that holds its child views with an arbitrary view. This allows great flexibility, including using a link::#layout_management#layout:: to manage the child views. See link::Classes/ScrollView#-canvas:: for explanation, and this link::Classes/ScrollView#examples#example::.
283 SECTION:: New views
285 SUBSECTION:: TreeView
287 link::Classes/TreeView:: is a powerful addition to the group of views that display a strong::set of items:: (including ListView and PopUpMenu). It displays items organized in a strong::hierarchical:: manner, akin to filesystem browsers.
289 Unlike ListView, where items are only arranged in one column, TreeView may consist of strong::several columns::: each item occupies a row, and may contain one text value for each column. Columns also have strong::labeled headers::.
291 Moreover, each data field of an item may also strong::contain another view::, giving you a great potential for interactivity with items.
293 SUBSECTION:: WebView
295 link::Classes/WebView:: is the core component for strong::web page browsing::. It is also implemented in the Cocoa GUI, but we list it here nonetheless.
297 It is a view that displays web pages, with web technology support comparable to widespread desktop web browsers.
299 NOTE:: There may currently be some issues with displaying multimedia content. ::
301 code::
303 w = WebView(bounds: Window.screenBounds.insetBy(100,40))
304     .url_("http://supercollider.sourceforge.net/")
305     .front;