1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.ide.eclipse.gltrace.views.detail;
18
19import com.android.ide.eclipse.gltrace.editors.GLCallGroups.GLCallNode;
20import com.android.ide.eclipse.gltrace.editors.GLFunctionTraceViewer;
21import com.android.ide.eclipse.gltrace.model.GLCall;
22import com.android.ide.eclipse.gltrace.model.GLTrace;
23import com.android.ide.eclipse.gltrace.state.IGLProperty;
24import com.android.ide.eclipse.gltrace.views.StateView;
25
26import org.eclipse.jface.action.IContributionItem;
27import org.eclipse.jface.action.IToolBarManager;
28import org.eclipse.jface.viewers.ISelection;
29import org.eclipse.jface.viewers.IStructuredSelection;
30import org.eclipse.jface.viewers.TreeSelection;
31import org.eclipse.swt.SWT;
32import org.eclipse.swt.custom.StackLayout;
33import org.eclipse.swt.layout.GridData;
34import org.eclipse.swt.widgets.Composite;
35import org.eclipse.swt.widgets.Control;
36import org.eclipse.ui.ISelectionListener;
37import org.eclipse.ui.IWorkbenchPart;
38import org.eclipse.ui.part.IPageSite;
39import org.eclipse.ui.part.Page;
40
41import java.util.Arrays;
42import java.util.List;
43
44public class DetailsPage extends Page implements ISelectionListener {
45    private GLTrace mTrace;
46
47    private IToolBarManager mToolBarManager;
48    private Composite mTopComposite;
49    private StackLayout mStackLayout;
50    private Composite mBlankComposite;
51
52    private List<IDetailProvider> mDetailProviders = Arrays.asList(
53            new ShaderSourceDetailsProvider(),
54            new ShaderUniformDetailsProvider(),
55            new TextureImageDetailsProvider(),
56            new VboDetailProvider(),
57            new GlDrawCallDetailProvider(),
58            new VertexAttribPointerDataDetailProvider());
59
60    public DetailsPage(GLTrace trace) {
61        mTrace = trace;
62    }
63
64    public void setInput(GLTrace trace) {
65        mTrace = trace;
66    }
67
68    @Override
69    public void createControl(Composite parent) {
70        mTopComposite = new Composite(parent, SWT.NONE);
71        mStackLayout = new StackLayout();
72        mTopComposite.setLayout(mStackLayout);
73        mTopComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
74
75        mBlankComposite = new Composite(mTopComposite, SWT.NONE);
76
77        mToolBarManager = getSite().getActionBars().getToolBarManager();
78
79        for (IDetailProvider provider : mDetailProviders) {
80            provider.createControl(mTopComposite);
81
82            for (IContributionItem item: provider.getToolBarItems()) {
83                mToolBarManager.add(item);
84            }
85        }
86
87        setDetailsProvider(null);
88    }
89
90    private void setDetailsProvider(IDetailProvider provider) {
91        for (IContributionItem item: mToolBarManager.getItems()) {
92            item.setVisible(false);
93        }
94
95        if (provider == null) {
96            setTopControl(mBlankComposite);
97        } else {
98            setTopControl(provider.getControl());
99
100            for (IContributionItem item: provider.getToolBarItems()) {
101                item.setVisible(true);
102            }
103        }
104
105        mToolBarManager.update(true);
106    }
107
108    private void setTopControl(Control c) {
109        mStackLayout.topControl = c;
110        mTopComposite.layout();
111    }
112
113    @Override
114    public Control getControl() {
115        return mTopComposite;
116    }
117
118    @Override
119    public void init(IPageSite pageSite) {
120        super.init(pageSite);
121        pageSite.getPage().addSelectionListener(this);
122    }
123
124    @Override
125    public void dispose() {
126        getSite().getPage().removeSelectionListener(this);
127
128        for (IDetailProvider provider : mDetailProviders) {
129            provider.disposeControl();
130        }
131
132        super.dispose();
133    }
134
135    @Override
136    public void setFocus() {
137    }
138
139    @Override
140    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
141        if (part instanceof GLFunctionTraceViewer) {
142            GLCall selectedCall = getSelectedCall((GLFunctionTraceViewer) part, selection);
143            if (selectedCall == null) {
144                return;
145            }
146
147            callSelected(selectedCall);
148            return;
149        } else if (part instanceof StateView) {
150            IGLProperty selectedProperty = getSelectedProperty((StateView) part, selection);
151            if (selectedProperty == null) {
152                return;
153            }
154
155            stateVariableSelected(selectedProperty);
156            return;
157        }
158
159        return;
160    }
161
162    private void stateVariableSelected(IGLProperty property) {
163        for (IDetailProvider p : mDetailProviders) {
164            if (!(p instanceof IStateDetailProvider)) {
165                continue;
166            }
167
168            IStateDetailProvider sp = (IStateDetailProvider) p;
169            if (sp.isApplicable(property)) {
170                sp.updateControl(property);
171                setDetailsProvider(sp);
172                return;
173            }
174        }
175
176        setDetailsProvider(null);
177        return;
178    }
179
180    private void callSelected(GLCall selectedCall) {
181        for (IDetailProvider p : mDetailProviders) {
182            if (!(p instanceof ICallDetailProvider)) {
183                continue;
184            }
185
186            ICallDetailProvider cp = (ICallDetailProvider) p;
187            if (cp.isApplicable(selectedCall)) {
188                cp.updateControl(mTrace, selectedCall);
189                setDetailsProvider(cp);
190                return;
191            }
192        }
193
194        setDetailsProvider(null);
195        return;
196    }
197
198    private GLCall getSelectedCall(GLFunctionTraceViewer part, ISelection selection) {
199        if (part.getTrace() != mTrace) {
200            return null;
201        }
202
203        if (!(selection instanceof TreeSelection)) {
204            return null;
205        }
206
207        Object data = ((TreeSelection) selection).getFirstElement();
208        if (data instanceof GLCallNode) {
209            return ((GLCallNode) data).getCall();
210        } else {
211            return null;
212        }
213    }
214
215    private IGLProperty getSelectedProperty(StateView view, ISelection selection) {
216        if (!(selection instanceof IStructuredSelection)) {
217            return null;
218        }
219
220        IStructuredSelection ssel = (IStructuredSelection) selection;
221        @SuppressWarnings("rawtypes")
222        List objects = ssel.toList();
223        if (objects.size() > 0) {
224            Object data = objects.get(0);
225            if (data instanceof IGLProperty) {
226                return (IGLProperty) data;
227            }
228        }
229
230        return null;
231    }
232}
233