JetSegGraph.py revision 6b065d0f7161fe54e6f58fd2b8ad6c650b2d3657
125e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar"""
225e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar File:
325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar JetSegGraph.py
425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar Contents and purpose:
625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar Draws the event graph and progress bar
725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar Copyright (c) 2008 Android Open Source Project
9e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner
10e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner Licensed under the Apache License, Version 2.0 (the "License");
11e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner you may not use this file except in compliance with the License.
12e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner You may obtain a copy of the License at
1325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
1425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar      http://www.apache.org/licenses/LICENSE-2.0
1525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
1625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar Unless required by applicable law or agreed to in writing, software
17255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth distributed under the License is distributed on an "AS IS" BASIS,
18255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner See the License for the specific language governing permissions and
2089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola limitations under the License.
210855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis"""
22255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth
2384a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar
2425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbarimport  wx
2578c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Chengimport logging
264a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbar
2725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbarfrom JetUtils import *
28821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbarfrom JetDefs import *
2925e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
3090edac0e8b35f766599362b6301863229f0ddcdbChris LattnerGRAPH_COLORS = [
3125e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar                '#C0E272',
3225e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar                '#85CF89',
339a7e2ccf574368b60455f8c8975030475a1f3ce0Daniel Dunbar                '#CF9683',
3486e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner                '#749EDE',
3525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar                '#9FB5B1',
3686e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner                '#B095BF',
3725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar                '#FE546D',
38e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner                '#B3BB97',
39e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner                '#FFFFB8',
40e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner
417092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                ]
42e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner
43e18e0c58dcd740c64e962fefde44249d685d0568Chris LattnerPROGRESS_BAR = '#0000CC'
44e18e0c58dcd740c64e962fefde44249d685d0568Chris LattnerEOS_BAR = '#095000'
45e18e0c58dcd740c64e962fefde44249d685d0568Chris LattnerAPP_BAR = '#B3BB97'
46e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner
4725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
4825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbarclass Marker():
4925e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    """ Defines portions of the graph for events """
501f7210e808373fa92be3a2d4fa653a6f79d5088bCraig Topper    def __init__(self, sEventType, iEventId, sName, sStartMbt, sEndMbt, iStartMeasure, ppqn):
511f7210e808373fa92be3a2d4fa653a6f79d5088bCraig Topper        self.sEventType = sEventType
5225e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar        self.iEventId = iEventId
53f9efd83166401bca542c6702ea329f9901c4e04bRafael Espindola        self.sName = sName
54f9efd83166401bca542c6702ea329f9901c4e04bRafael Espindola        self.StartMbt = ConvertStrTimeToTuple(sStartMbt)
55f9efd83166401bca542c6702ea329f9901c4e04bRafael Espindola        self.EndMbt = ConvertStrTimeToTuple(sEndMbt)
56d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola        self.iStartMeasure = iStartMeasure
57d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola        self.iStart = 0
58529a01df02ad221e8e55097a8ee36b85234eb078Rafael Espindola        self.iEnd = 0
59d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola        self.iWidth = 0
60d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola        self.iHeight = 0
61ca93138e11f404a19553049a569f1fa6ad491b67Charles Davis        self.iTop = 0
6291d9a1c0f7c598d51c50f80bc9e8dfc1494f78c1Charles Davis        self.iUpdate = False
6391d9a1c0f7c598d51c50f80bc9e8dfc1494f78c1Charles Davis        self.sColor = '#FFFFB8'
640855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis        self.ppqn = ppqn
650855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis        self.isDirty = False
6649cb9b88867426d1a430f248550d3cc785a68fe4Rafael Espindola
67ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola    def CalcCoord(self, step, height, ColorFct):
687d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        """ Calculates the coordinates in pixels for graphing the shaded regions """
697d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        #measures
707d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        iStartM = self.StartMbt[0] - self.iStartMeasure
717d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        iEndM = self.EndMbt[0] - self.iStartMeasure
727092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar        self.iStart = step * iStartM
737768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        self.iEnd = step * iEndM
747768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        #beats
75a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola        self.iStart = self.iStart + ((step / 4.0) * (self.StartMbt[1]-1))
76a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola        self.iEnd = self.iEnd + ((step / 4.0) * (self.EndMbt[1]-1))
77a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola        #ticks
78a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola        pctTickOfBeat = (float(self.StartMbt[2]) / float(self.ppqn))
79a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola        self.iStart = self.iStart + ((pctTickOfBeat * (step / 4.0)))
801674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer        pctTickOfBeat = (float(self.EndMbt[2]) / float(self.ppqn))
81547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola        self.iEnd = self.iEnd + ((pctTickOfBeat * (step / 4.0)))
82547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola
831fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola        self.iWidth = self.iEnd - self.iStart
841fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola
85c25dad8750083829d9a8935ce40d0734e5488f8eRafael Espindola        self.iHeight = height
86c25dad8750083829d9a8935ce40d0734e5488f8eRafael Espindola        self.sColor = ColorFct()
873185f5c35322cbd10040ab20f265042d477efe62Charles Davis        self.iUpdate = False
8838ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis
893185f5c35322cbd10040ab20f265042d477efe62Charles Davisclass SegmentGraph(wx.Panel):
90381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    """ Draws the player graph bar """
9125e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    def __init__(self, parent, pos=wx.DefaultPosition, size=wx.DefaultSize, ClickCallbackFct=None, showLabels=True, showClips=True, showAppEvts=True):
9225e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar        wx.Panel.__init__(self, parent, -1, pos=pos, size=size, style=wx.BORDER_STATIC)
9325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar        self.iLocationInMs = 0
9425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar        self.iLengthInMs = 0
9589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.iLengthInMeasures = 0
9689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.iMarkerTop = 15
9789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.iScaleTop = 0
9889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.iEdges = 5
9989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.iStartMeasure = 0
10089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.iMidiMode = False
10189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.ClickCallbackFct = ClickCallbackFct
10289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola        self.iColor = 0
103dda1bdc962a314bf4fca86f4cd4802ff6c55b172Bill Wendling        self.showLabels = showLabels
104dda1bdc962a314bf4fca86f4cd4802ff6c55b172Bill Wendling        self.showClips = showClips
105dda1bdc962a314bf4fca86f4cd4802ff6c55b172Bill Wendling        self.showAppEvts = showAppEvts
106dda1bdc962a314bf4fca86f4cd4802ff6c55b172Bill Wendling
10738ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis        self.font = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, 'Courier')
10838ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis
10938ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis        self.Markers = []
11038ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
11138ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis        self.Bind(wx.EVT_PAINT, self.OnPaint)
112ca93138e11f404a19553049a569f1fa6ad491b67Charles Davis        self.Bind(wx.EVT_SIZE, self.OnSize)
11338ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
11438ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis
1150fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner        #initialize buffer
1160fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner        self.OnSize(None)
1170dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
11891bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    def ClearGraph(self):
11991bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner        """ Clears the graph values """
12056591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner        self.iLocationInMs = 0
1210dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach        self.iLengthInMs = 0
12291bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner        self.iLengthInMeasures = 0
12391bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner        self.iMarkerTop = 15
12491bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner        self.iScaleTop = 0
1250fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner        self.iEdges = 5
126d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner        self.iStartMeasure = 0
12786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        self.iMidiMode = False
12886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        self.iColor = 0
12986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        self.Markers = []
13086e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        self.iLocationInMs = 0
13186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        self.DoDrawing()
13286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner
133d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner    def LoadSegment(self, segment, segMarker=None, iMidiMode=False, showLabels=True, showClips=True, showAppEvts=True):
1340dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach        """ Loads up the segment drawing the graph """
135d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner        if segment is None:
136d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner            self.ClearGraph()
137d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner            return None
138d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner        self.iMidiMode = iMidiMode
1390dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach        self.showLabels = showLabels
1400fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner        self.showClips = showClips
1410fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner        self.showAppEvts = showAppEvts
1420dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach        self.Markers = []
1430fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner        self.iLocationInMs = 0
1440dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach        info = MidiSegInfo(segment)
14584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar        #disable graph for debugging
14684a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar        #return info
1470dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach        self.iLengthInMs = info.iLengthInMs
1486a4824c466bbfbcbe7dc4d95ec1e23a14ec73d87Dan Gohman        self.ppqn = info.ppqn
1497092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar        self.StartMbt = mbtFct(ConvertStrTimeToTuple(segment.start), 1)
1507768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        self.EndMbt = mbtFct(ConvertStrTimeToTuple(segment.end), 1)
1517d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        self.LengthMbt = None
1527d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        self.iStartMeasure = self.StartMbt[0]
1537768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        self.iLengthInMeasures = self.EndMbt[0] - self.StartMbt[0]
1547768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
15584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar        for jet_event in segment.jetevents:
1561674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer            if self.showClips and jet_event.event_type == JetDefs.E_CLIP:
1571674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer                self.AddMarker(JetDefs.E_CLIP, jet_event.event_id, jet_event.event_name, mbtFct(jet_event.event_start,1), mbtFct(jet_event.event_end,1), self.iStartMeasure, self.ppqn)
1587768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            elif jet_event.event_type == JetDefs.E_EOS:
1597d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger                self.AddMarker(JetDefs.E_EOS, jet_event.event_id, jet_event.event_name, mbtFct(jet_event.event_end,1), mbtFct(jet_event.event_end,1), self.iStartMeasure, self.ppqn)
1607d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger            elif self.showAppEvts and jet_event.event_type == JetDefs.E_APP:
1617768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola                self.AddMarker(JetDefs.E_APP, jet_event.event_id, jet_event.event_name, mbtFct(jet_event.event_start,1), mbtFct(jet_event.event_end,1), self.iStartMeasure, self.ppqn)
1627768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1637768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        if segMarker is not None:
1647768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            self.AddMarker(JetDefs.E_CLIP, 0, segMarker[0], mbtFct(segMarker[1],1), mbtFct(segMarker[2],1), self.iStartMeasure, self.ppqn)
1657768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1667768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        self.DoDrawing()
1677768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        return info
1687768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1697768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    def AddMarker(self, sEventType, iEventId, sName, sStartMbt, sEndMbt, iStartMeasure, ppqn):
1707768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        """ Adds a marker to the list """
1717768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        if not CompareMbt(sStartMbt, sEndMbt):
1727768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            sEndMbt = sStartMbt
1737d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        self.Markers.append(Marker(sEventType, iEventId, sName, sStartMbt, sEndMbt, iStartMeasure, ppqn))
1747d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger
1757768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    def OnLeftDown(self, event):
1767768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        """ Calls the function assicated with an event """
1777768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        pt = event.GetPosition()
1787768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        for Marker in self.Markers:
1797768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            if pt[0] >= Marker.iStart and pt[0] <= Marker.iEnd and pt[1] >= Marker.iTop and pt[1] <= Marker.iTop + Marker.iHeight:
1807768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola                if self.ClickCallbackFct != None:
1817768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola                    self.ClickCallbackFct(Marker.sName, Marker.iEventId)
1827d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger
1837768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    def GetAColor(self):
1847d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        """ Gets a color """
1857d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        color = GRAPH_COLORS[self.iColor]
1867768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        self.iColor = self.iColor + 1
1877768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        if self.iColor >= len(GRAPH_COLORS):
1887768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            self.iColor = 0
1897768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        return color
1907768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1911674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer    def OnSize(self, event=None):
192381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar        """ Repaints for resizing of screen """
193fb76fe09297ee292129e44d723127f2408602a3dDan Gohman        if OsWindows():
194381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            # The Buffer init is done here, to make sure the buffer is always
195381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            # the same size as the Window
1967768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            Size  = self.GetClientSizeTuple()
1977768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1987d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger            # Make new offscreen bitmap: this bitmap will always have the
1997d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger            # current drawing in it, so it can be used to save the image to
2007768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            # a file, or whatever.
2017d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger            self._Buffer = wx.EmptyBitmap(*Size)
2027768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        self.DoDrawing(None)
2037768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        if event is not None:
2047768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola            event.Skip()
2050dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
206410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis    def OnPaint(self, event=None):
207410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis        """ Painting of windows """
208410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis        if OsWindows():
209410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis            dc = wx.BufferedPaintDC(self, self._Buffer)
210410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis        else:
211410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis            dc = wx.AutoBufferedPaintDC(self)
212410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis            dc.Background = wx.Brush(wx.WHITE)
213410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis        self.DoDrawing(dc)
214410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis
215410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis    def DoDrawing(self, dc=None):
216410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis        """ Does the actual drawing of the control """
217d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola        if dc is None:
218d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola            if OsWindows():
219d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola                dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer)
220fb76fe09297ee292129e44d723127f2408602a3dDan Gohman            else:
221381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                dc = wx.AutoBufferedPaintDC(self)
222381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                dc.Background = wx.Brush(wx.WHITE)
223381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar
224381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar        dc.Clear()
225381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar
226381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar        self.iColor = 0
227381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar        gWidth, gHeight = self.GetSize()
228ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola        gWidth = gWidth - (self.iEdges * 2)
229381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar        step = int(gWidth / (self.iLengthInMeasures + .01))
2308bca4106dfc2945723251db10e340183f3e372ddRafael Espindola
2318bca4106dfc2945723251db10e340183f3e372ddRafael Espindola        for Marker in self.Markers:
2328bca4106dfc2945723251db10e340183f3e372ddRafael Espindola            Marker.CalcCoord(step, gHeight, self.GetAColor)
2333e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
234a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner        """ eliminate overlaps; establish colors """
235a5c783280f83df5c60a8ed9e32c61b05a11048e3Kevin Enderby        iClips = 0
2363e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach        iMarkers = 0
2373e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach        for index, Marker in enumerate(self.Markers):
2383e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach            if Marker.sEventType == JetDefs.E_CLIP:
239ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach                iClips = iClips + 1
240ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach                iOverlaps = 1
241ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach                for index1, Marker1 in enumerate(self.Markers):
242ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach                    if Marker.sEventType == JetDefs.E_CLIP:
243fb76fe09297ee292129e44d723127f2408602a3dDan Gohman                        if index != index1 and not Marker1.iUpdate:
244381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                            if Marker.iStart <= Marker1.iStart and Marker.iEnd <= Marker1.iEnd and Marker.iEnd >= Marker1.iStart:
245381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                                iOverlaps = iOverlaps + 1
246381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                                Marker.iUpdate = True
247381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                                Marker1.iUpdate = True
248381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                            if not Marker.iUpdate and Marker.iStart >= Marker1.iStart and Marker.iEnd >= Marker1.iEnd and Marker.iStart <= Marker1.iEnd:
249381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                                iOverlaps = iOverlaps + 1
250381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                                Marker.iUpdate = True
251381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                                Marker1.iUpdate = True
252381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                if iOverlaps > 1:
253381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                    iTop = 0
254821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar                    for index1, Marker1 in enumerate(self.Markers):
25525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar                        if Marker.sEventType == JetDefs.E_CLIP:
256484291c27319668ad99cb87def000254357736fbRafael Espindola                            if Marker1.iUpdate:
257484291c27319668ad99cb87def000254357736fbRafael Espindola                                Marker1.iHeight = gHeight / iOverlaps
258484291c27319668ad99cb87def000254357736fbRafael Espindola                                Marker1.iTop = iTop * Marker1.iHeight
259484291c27319668ad99cb87def000254357736fbRafael Espindola                                iTop = iTop + 1
260484291c27319668ad99cb87def000254357736fbRafael Espindola            elif Marker.sEventType == JetDefs.E_APP:
261484291c27319668ad99cb87def000254357736fbRafael Espindola                iMarkers = iMarkers + 1
262484291c27319668ad99cb87def000254357736fbRafael Espindola
263484291c27319668ad99cb87def000254357736fbRafael Espindola        for Marker in self.Markers:
264484291c27319668ad99cb87def000254357736fbRafael Espindola            if Marker.sEventType == JetDefs.E_CLIP:
265fb76fe09297ee292129e44d723127f2408602a3dDan Gohman                dc.SetPen(wx.Pen(Marker.sColor))
266a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar                dc.SetBrush(wx.Brush(Marker.sColor))
267a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner                dc.DrawRectangle(Marker.iStart + self.iEdges, Marker.iTop, Marker.iWidth, Marker.iHeight)
26825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar                width, height = dc.GetTextExtent(Marker.sName)
269fb76fe09297ee292129e44d723127f2408602a3dDan Gohman                k = ((Marker.iStart + Marker.iEnd) / 2) - (width/2) + self.iEdges
27095cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby                if self.showLabels or self.iMidiMode:
27195cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby                    dc.DrawText(Marker.sName, k, ((Marker.iTop+Marker.iHeight/2) - (height*.5)))
27295cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby                if self.iMidiMode:
27395cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby                    self.iMidiModeStart = Marker.iStart
27495cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby            elif Marker.sEventType == JetDefs.E_EOS:
275b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                dc.SetPen(wx.Pen(EOS_BAR))
276b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                dc.SetBrush(wx.Brush(EOS_BAR))
277b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                dc.DrawRectangle(Marker.iStart + self.iEdges, Marker.iTop, 1, Marker.iHeight)
278b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                width, height = dc.GetTextExtent(Marker.sName)
279b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                k = Marker.iStart - (width/2) + self.iEdges
280b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                dc.DrawText(Marker.sName, k, ((Marker.iTop+Marker.iHeight/2) - (height*.5)))
281b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner            elif Marker.sEventType == JetDefs.E_APP:
282b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                dc.SetPen(wx.Pen(APP_BAR))
283b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                dc.SetBrush(wx.Brush(APP_BAR))
284b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                dc.DrawRectangle(Marker.iStart + self.iEdges, Marker.iTop, 1, Marker.iHeight)
285b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                width, height = dc.GetTextExtent(Marker.sName)
286b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                k = Marker.iStart - (width/2) + self.iEdges
287b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                if self.showLabels or self.iMidiMode:
288b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner                    dc.DrawText(Marker.sName, k, ((Marker.iTop+Marker.iHeight/2) - (height*.5)))
289b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
290b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
291b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner        """ Draw scale """
292b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner        if gWidth == 0:
2938f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola            iDiv = 50
2948f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola        else:
2958f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola            iDiv = (gWidth)/18
2968f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola        if iDiv == 0:
2978f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola            iDiv = 50
29899328add833807f12a4950c7de29fb2a5df04703Chris Lattner        scale = ((self.iLengthInMeasures / iDiv) + 1)
29999328add833807f12a4950c7de29fb2a5df04703Chris Lattner        if scale == 0:
30099328add833807f12a4950c7de29fb2a5df04703Chris Lattner            scale = 1
30199328add833807f12a4950c7de29fb2a5df04703Chris Lattner        beatStep = step / 4.0
30299328add833807f12a4950c7de29fb2a5df04703Chris Lattner        dc.SetFont(self.font)
30399328add833807f12a4950c7de29fb2a5df04703Chris Lattner        j = 0
3040dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach        lastEnd = 0
3059eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner        num = range(self.iStartMeasure, self.iStartMeasure + self.iLengthInMeasures + 1, 1)
3064e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner        dc.SetPen(wx.Pen('#5C5142'))
3074e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner        for i in range(0, (self.iLengthInMeasures+1)*step, step):
3084e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner            k = i + self.iEdges
3097092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar            dc.DrawLine(k, self.iScaleTop, k, self.iScaleTop+8)
3109eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            if i != (self.iLengthInMeasures)*step:
3119eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner                for iBeat in range(1,4):
3127092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                    k = i+(iBeat * beatStep) + self.iEdges
3134e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner                    dc.DrawLine(k, self.iScaleTop, k, self.iScaleTop+4)
3149eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            width, height = dc.GetTextExtent(str(num[j]))
3159eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            k = i-(width/2) + self.iEdges
3169eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            if k > lastEnd:
3179eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner                if j == 0 or (j % scale) == 0:
31836a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer                    dc.DrawText(str(num[j]), k, self.iScaleTop+8)
31936a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer                lastEnd = k + width
32036a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer            j = j + 1
3210dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
3220df4a80e2063424929bbfaa61dd7973062218ad4Eric Christopher        """ Updates the location bar in case screen moved or resized """
3239be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner        if self.iLocationInMs > 0 and self.iLengthInMs > 0:
3249be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner            iOffset = 0
3259be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner            if self.iMidiMode:
3269be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner                iOffset = self.iMidiModeStart
3277092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar
3287092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar            till = gWidth * (self.iLocationInMs / self.iLengthInMs)
3298751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar            dc.SetPen(wx.Pen(PROGRESS_BAR))
330c90a1fcf9f44858b20e0f5f7e0b98049aec7a1e0Evan Cheng            dc.SetBrush(wx.Brush(PROGRESS_BAR))
3319be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner            dc.DrawRectangle(self.iEdges + iOffset, gHeight-6, till, 3)
332482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher
333482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher    def UpdateLocation(self, iLocationInMs):
3344d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher        """ Updates the location bar """
335482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher        #disable graph for debugging
336482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher        #return info
337482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher
338482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher        self.iLocationInMs = iLocationInMs
3394d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher        if self.iLocationInMs > 0 and self.iLengthInMs > 0:
3400dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach            if OsWindows():
341ff96a12db635daf4f88cfea899e63a885dfaa9edCharles Davis                dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer)
34284a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar            else:
34384a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar                dc = wx.AutoBufferedPaintDC(self)
34484a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar                dc.Background = wx.Brush(wx.WHITE)
34584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar
346c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko            iOffset = 0
347381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            if self.iMidiMode:
348381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                iOffset = self.iMidiModeStart
349381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar
350aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner            gWidth, gHeight = self.GetSize()
351381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            gWidth = gWidth - (self.iEdges * 2)
352fb76fe09297ee292129e44d723127f2408602a3dDan Gohman
353fb76fe09297ee292129e44d723127f2408602a3dDan Gohman            till = gWidth * (self.iLocationInMs / self.iLengthInMs)
354381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            dc.SetPen(wx.Pen(PROGRESS_BAR))
355381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            dc.SetBrush(wx.Brush(PROGRESS_BAR))
356381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            dc.DrawRectangle(self.iEdges + iOffset, gHeight-6, till, 3)
357381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            self.isDirty = True
358381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar        else:
359381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar            if self.isDirty:
360381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar                self.DoDrawing()
36189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola                self.isDirty = False
362debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola