summaryrefslogtreecommitdiff
path: root/chromium/third_party/catapult/tracing/tracing/ui/brushing_state.html
blob: 371cfafefa310ecb788b833c84087eca0049167f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/tracing/base/guid.html">
<link rel="import" href="/tracing/base/iteration_helpers.html">
<link rel="import" href="/tracing/model/event_set.html">
<link rel="import" href="/tracing/model/selection_state.html">

<script>
'use strict';

tr.exportTo('tr.ui.b', function() {
  var EventSet = tr.model.EventSet;
  var SelectionState = tr.model.SelectionState;

  function BrushingState() {
    this.guid_ = tr.b.GUID.allocateSimple();
    this.selection_ = new EventSet();
    this.findMatches_ = new EventSet();
    this.analysisViewRelatedEvents_ = new EventSet();
    this.analysisLinkHoveredEvents_ = new EventSet();
    this.appliedToModel_ = undefined;
    this.viewSpecificBrushingStates_ = {};
  }
  BrushingState.prototype = {
    get guid() {
      return this.guid_;
    },

    clone: function() {
      var that = new BrushingState();
      that.selection_ = this.selection_;
      that.findMatches_ = this.findMatches_;
      that.analysisViewRelatedEvents_ = this.analysisViewRelatedEvents_;
      that.analysisLinkHoveredEvents_ = this.analysisLinkHoveredEvents_;
      that.viewSpecificBrushingStates_ = this.viewSpecificBrushingStates_;

      return that;
    },

    equals: function(that) {
      if (!this.selection_.equals(that.selection_))
        return false;
      if (!this.findMatches_.equals(that.findMatches_))
        return false;
      if (!this.analysisViewRelatedEvents_.equals(
          that.analysisViewRelatedEvents_)) {
        return false;
      }
      if (!this.analysisLinkHoveredEvents_.equals(
          that.analysisLinkHoveredEvents_)) {
        return false;
      }
      // We currently do not take the view-specific brushing states into
      // account. If we did, every change of the view-specific brushing state
      // of any view would cause a redraw of the whole UI (see the
      // BrushingStateController.currentBrushingState setter).
      return true;
    },

    get selectionOfInterest() {
      if (this.selection_.length)
        return this.selection_;

      if (this.highlight_.length)
        return this.highlight_;

      if (this.analysisViewRelatedEvents_.length)
        return this.analysisViewRelatedEvents_;

      if (this.analysisLinkHoveredEvents_.length)
        return this.analysisLinkHoveredEvents_;

      return this.selection_;
    },

    get selection() {
      return this.selection_;
    },

    set selection(selection) {
      if (this.appliedToModel_)
        throw new Error('Cannot mutate this state right now');
      if (selection === undefined)
        selection = new EventSet();
      this.selection_ = selection;
    },

    get findMatches() {
      return this.findMatches_;
    },

    set findMatches(findMatches) {
      if (this.appliedToModel_)
        throw new Error('Cannot mutate this state right now');
      if (findMatches === undefined)
        findMatches = new EventSet();
      this.findMatches_ = findMatches;
    },

    get analysisViewRelatedEvents() {
      return this.analysisViewRelatedEvents_;
    },

    set analysisViewRelatedEvents(analysisViewRelatedEvents) {
      if (this.appliedToModel_)
        throw new Error('Cannot mutate this state right now');
      if (analysisViewRelatedEvents === undefined)
        analysisViewRelatedEvents = new EventSet();
      this.analysisViewRelatedEvents_ = analysisViewRelatedEvents;
    },

    get analysisLinkHoveredEvents() {
      return this.analysisLinkHoveredEvents_;
    },

    set analysisLinkHoveredEvents(analysisLinkHoveredEvents) {
      if (this.appliedToModel_)
        throw new Error('Cannot mutate this state right now');
      if (analysisLinkHoveredEvents === undefined)
        analysisLinkHoveredEvents = new EventSet();
      this.analysisLinkHoveredEvents_ = analysisLinkHoveredEvents;
    },

    get isAppliedToModel() {
      return this.appliedToModel_ !== undefined;
    },

    get viewSpecificBrushingStates() {
      return this.viewSpecificBrushingStates_;
    },

    set viewSpecificBrushingStates(viewSpecificBrushingStates) {
      this.viewSpecificBrushingStates_ = viewSpecificBrushingStates;
    },

    get dimmedEvents_() {
      var dimmedEvents = new EventSet();
      dimmedEvents.addEventSet(this.findMatches);
      dimmedEvents.addEventSet(this.analysisViewRelatedEvents_);
      return dimmedEvents;
    },

    get brightenedEvents_() {
      var brightenedEvents = new EventSet();
      brightenedEvents.addEventSet(this.selection_);
      brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);
      return brightenedEvents;
    },

    /**
     * This function sets the SelectionStates according to these rules:
     *
     * - Events in ONE of findMatches or analysisViewRelatedEvents
     * are set to SelectionState.BRIGHTENED0.
     * - Events in BOTH of findMatches and analysisViewRelatedEvents
     * are set to SelectionState.BRIGHTENED1.
     * - Events in ONE of selection or analysisLinkHoveredEvents
     * are set to SelectionState.DIMMED1.
     * - Events in BOTH selection and analysisLinkHoveredEvents
     * are set to SelectionState.DIMMED2.
     * - Events not in any of the above are set to SelectionState.NONE
     * if there are no events in selection or analysisLinkHoveredEvents
     * (i.e. model is "default bright") or SelectionState.DIMMED0 (i.e.
     * model is "default dimmed").
     *
     * It is up to the caller to assure that all of the SelectionStates
     * are the same before calling this function. Normally,
     * this is done by calling unapplyFromModelSelectionState on the
     * old brushing state first.
     */
    applyToEventSelectionStates: function(model) {
      this.appliedToModel_ = model;

      var dimmedEvents = this.dimmedEvents_;

      // It's possible for this to get called with an undefined model pointer.
      // If so, skip adjusting the defaults.
      if (model) {
        var newDefaultState = (
            dimmedEvents.length ? SelectionState.DIMMED0 : SelectionState.NONE);

        // Since all the states are the same, we can get the current default
        // state by looking at the first element.
        var currentDefaultState = tr.b.getFirstElement(
            model.getDescendantEvents()).selectionState;

        // If the default state was changed, then we have to iterate through
        // and reset all the events to the new default state.
        if (currentDefaultState !== newDefaultState)
          for (var e of model.getDescendantEvents())
            e.selectionState = newDefaultState;
      }

      // Now we apply the other rules above.
      var score;
      for (var e of dimmedEvents) {
        score = 0;
        if (this.findMatches_.contains(e))
          score++;
        if (this.analysisViewRelatedEvents_.contains(e))
          score++;
        e.selectionState = SelectionState.getFromDimmingLevel(score);
      }

      for (var e of this.brightenedEvents_) {
        score = 0;
        if (this.selection_.contains(e))
          score++;
        if (this.analysisLinkHoveredEvents_.contains(e))
          score++;
        e.selectionState = SelectionState.getFromBrighteningLevel(score);
      }

    },

    transferModelOwnershipToClone: function(that) {
      if (!this.appliedToModel_)
        throw new Error('Not applied');
      // Assumes this.equals(that).
      that.appliedToModel_ = this.appliedToModel_;
      this.appliedToModel_ = undefined;
    },

    /**
     * Unapplies this brushing state from the model selection state.
     * Resets all the SelectionStates to their default value (DIMMED0 or NONE)
     * and returns the default selection states. The caller should store this
     * value and pass it into applyFromModelSelectionStat when that is called.
     */
    unapplyFromEventSelectionStates: function() {
      if (!this.appliedToModel_)
        throw new Error('Not applied');
      var model = this.appliedToModel_;
      this.appliedToModel_ = undefined;

      var dimmedEvents = this.dimmedEvents_;
      var defaultState = (
          dimmedEvents.length ? SelectionState.DIMMED0 : SelectionState.NONE);

      for (var e of this.brightenedEvents_)
        e.selectionState = defaultState;
      for (var e of dimmedEvents)
        e.selectionState = defaultState;
      return defaultState;
    }
  };

  return {
    BrushingState: BrushingState
  };
});
</script>