|
59 | 59 | end |
60 | 60 |
|
61 | 61 | methods |
62 | | - function obj = AlyxPanel(parent, active) |
| 62 | + function obj = AlyxPanel(parent, url) |
63 | 63 | % Constructor to build all the UI elements and set callbacks to |
64 | 64 | % the relevant functions. If a handle to parant UI object is |
65 | 65 | % not specified, a seperate figure is created. An optional |
66 | 66 | % handle to a logging display panal may be provided, otherwise |
67 | | - % one is created. If the active flag is set to false, the panel |
68 | | - % is inactive and the instance of Alyx will be set to headless. |
69 | | - % The panel defaults to active only if the databaseURL field is |
70 | | - % populated in the paths. |
| 67 | + % one is created. The panel will be rendered inactive and the |
| 68 | + % instance of Alyx will be set to headless if an empty database |
| 69 | + % URL is provided, or if no URL is provided and the databaseURL |
| 70 | + % field is not populated in the paths. |
71 | 71 | % |
72 | 72 | % See also Alyx |
73 | | - |
| 73 | + noParent = ~nargin || isempty(parent); |
74 | 74 | obj.AlyxInstance = Alyx('',''); |
75 | | - if ~nargin % No parant object: create new figure |
| 75 | + if noParent % No parant object: create new figure |
76 | 76 | f = figure('Name', 'alyx GUI',... |
77 | 77 | 'MenuBar', 'none',... |
78 | 78 | 'Toolbar', 'none',... |
|
91 | 91 | % be set by any other GUI that instantiates this object (e.g. |
92 | 92 | % MControl using this as a panel. |
93 | 93 | obj.NewExpSubject.addlistener('SelectionChanged', @(src, evt)obj.dispWaterReq(src, evt)); |
| 94 | + else |
| 95 | + % We'll need the figure handle for adding a context menu |
| 96 | + f = ancestor(parent, 'Figure'); |
94 | 97 | end |
95 | 98 |
|
96 | 99 | % Check to see if there is a remote database url defined in |
97 | 100 | % the paths, if so activate AlyxPanel |
98 | 101 | if nargin < 2 |
99 | 102 | url = char(getOr(dat.paths, 'databaseURL', '')); |
100 | | - active = ~isempty(url); |
101 | 103 | end |
102 | 104 |
|
| 105 | + obj.AlyxInstance.BaseURL = url; |
103 | 106 | obj.RootContainer = uix.Panel('Parent', parent, 'Title', 'Alyx'); |
104 | 107 | alyxbox = uiextras.VBox('Parent', obj.RootContainer); |
105 | 108 |
|
|
114 | 117 | 'Callback', @(~,~)obj.login); |
115 | 118 | loginbox.Widths = [-1 75]; |
116 | 119 |
|
117 | | - % If active flag set as false, make Alyx headless |
118 | | - if ~active |
| 120 | + % If URL is empty, make Alyx headless |
| 121 | + if isempty(url) |
119 | 122 | obj.AlyxInstance.Headless = true; |
120 | 123 | set(obj.LoginButton, 'Enable', 'off') |
121 | 124 | end |
|
195 | 198 | 'Enable', 'off',... |
196 | 199 | 'Callback', @(~,~)obj.launchSessionURL); |
197 | 200 |
|
198 | | - if ~nargin |
| 201 | + if noParent |
199 | 202 | % logging message area |
200 | 203 | obj.LoggingDisplay = uicontrol('Parent', parent, 'Style', 'listbox',... |
201 | 204 | 'Enable', 'inactive', 'String', {}); |
|
204 | 207 | % Use parent's logging display |
205 | 208 | obj.LoggingDisplay = findobj('Tag', 'Logging Display'); |
206 | 209 | end |
| 210 | + obj.log('using database %s', obj.AlyxInstance.BaseURL) |
| 211 | + % Add context menu for changing database |
| 212 | + c = uicontextmenu(f); |
| 213 | + obj.RootContainer.UIContextMenu = c; |
| 214 | + uimenu(c, 'Label', 'Change database URL', ... |
| 215 | + 'MenuSelectedFcn', @(~,~)obj.changeURL()); |
207 | 216 | end |
208 | 217 |
|
209 | 218 | function delete(obj) |
@@ -301,6 +310,25 @@ function login(obj, varargin) |
301 | 310 | obj.dispWaterReq() |
302 | 311 | end |
303 | 312 |
|
| 313 | + function changeURL(obj, url) |
| 314 | + % Sets the database URL of the AlyxInstance. When called with |
| 315 | + % no inputs, the user is prompted to type in a new URL. If |
| 316 | + % logged in, the current token is deleted before changing URL |
| 317 | + % (unless the new URL is identical). |
| 318 | + current = obj.AlyxInstance.BaseURL; |
| 319 | + if nargin == 1 % Prompt user for input |
| 320 | + prompt = sprintf(['Please enter a database URL to connect to.\n'... |
| 321 | + 'This will log you out of the current database.\n']); |
| 322 | + url = newid(prompt,'Database URL', [1 50], {current}); |
| 323 | + end |
| 324 | + % Return if user pressed 'Close' or 'x', or url unchanged |
| 325 | + if isempty(url) || strcmpi(url, current), return, end |
| 326 | + % Clear current token, if there is one |
| 327 | + if obj.AlyxInstance.IsLoggedIn, obj.login; end |
| 328 | + obj.AlyxInstance.BaseURL = url; % Change URL |
| 329 | + obj.log('using database %s', obj.AlyxInstance.BaseURL) |
| 330 | + end |
| 331 | + |
304 | 332 | function giveWater(obj) |
305 | 333 | % Callback to the give water button. Posts the value entered |
306 | 334 | % in the text box as either liquid or gel depending on the |
|
0 commit comments