From 7cd3e663f9f686bcd4d68880593b72c8dd6a1b24 Mon Sep 17 00:00:00 2001
From: Luke Campagnola <luke.campagnola@gmail.com>
Date: Wed, 10 Jul 2013 00:02:16 -0400
Subject: [PATCH] experimental GL video widget temporary fix for text parameter
 ignoring expanded option Don't use os.EX_OK in pg.exit()

---
 examples/VideoSpeedTest.py                |  5 ++
 examples/VideoTemplate.ui                 | 73 +++++++++++++++------
 examples/VideoTemplate_pyqt.py            | 65 +++++++++++++------
 examples/VideoTemplate_pyside.py          | 65 +++++++++++++------
 examples/parametertree.py                 | 15 +++--
 pyqtgraph/__init__.py                     |  2 +-
 pyqtgraph/graphicsItems/ROI.py            |  8 ++-
 pyqtgraph/parametertree/parameterTypes.py |  8 ++-
 pyqtgraph/widgets/RawImageWidget.py       | 78 +++++++++++++++++++----
 9 files changed, 243 insertions(+), 76 deletions(-)

diff --git a/examples/VideoSpeedTest.py b/examples/VideoSpeedTest.py
index dd392189..d7a4e1e0 100644
--- a/examples/VideoSpeedTest.py
+++ b/examples/VideoSpeedTest.py
@@ -130,8 +130,13 @@ def update():
 
     if ui.rawRadio.isChecked():
         ui.rawImg.setImage(data[ptr%data.shape[0]], lut=useLut, levels=useScale)
+        ui.stack.setCurrentIndex(1)
+    elif ui.rawGLRadio.isChecked():
+        ui.rawGLImg.setImage(data[ptr%data.shape[0]], lut=useLut, levels=useScale)
+        ui.stack.setCurrentIndex(2)
     else:
         img.setImage(data[ptr%data.shape[0]], autoLevels=False, levels=useScale, lut=useLut)
+        ui.stack.setCurrentIndex(0)
         #img.setImage(data[ptr%data.shape[0]], autoRange=False)
         
     ptr += 1
diff --git a/examples/VideoTemplate.ui b/examples/VideoTemplate.ui
index 3dddb928..d73b0dc9 100644
--- a/examples/VideoTemplate.ui
+++ b/examples/VideoTemplate.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>985</width>
-    <height>674</height>
+    <width>695</width>
+    <height>798</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -17,33 +17,62 @@
    <layout class="QGridLayout" name="gridLayout_2">
     <item row="1" column="0" colspan="4">
      <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0">
-       <widget class="RawImageWidget" name="rawImg" native="true">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="GraphicsView" name="graphicsView"/>
-      </item>
-      <item row="1" column="0">
+      <item row="3" column="0">
        <widget class="QRadioButton" name="rawRadio">
         <property name="text">
-         <string>RawImageWidget (unscaled; faster)</string>
+         <string>RawImageWidget</string>
         </property>
         <property name="checked">
          <bool>true</bool>
         </property>
        </widget>
       </item>
-      <item row="1" column="1">
+      <item row="2" column="0">
        <widget class="QRadioButton" name="gfxRadio">
         <property name="text">
-         <string>GraphicsView + ImageItem (scaled; slower)</string>
+         <string>GraphicsView + ImageItem</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0">
+       <widget class="QStackedWidget" name="stack">
+        <property name="currentIndex">
+         <number>2</number>
+        </property>
+        <widget class="QWidget" name="page">
+         <layout class="QGridLayout" name="gridLayout_3">
+          <item row="0" column="0">
+           <widget class="GraphicsView" name="graphicsView"/>
+          </item>
+         </layout>
+        </widget>
+        <widget class="QWidget" name="page_2">
+         <layout class="QGridLayout" name="gridLayout_4">
+          <item row="0" column="0">
+           <widget class="RawImageWidget" name="rawImg" native="true">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+        <widget class="QWidget" name="page_3">
+         <layout class="QGridLayout" name="gridLayout_5">
+          <item row="0" column="0">
+           <widget class="RawImageGLWidget" name="rawGLImg" native="true"/>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <widget class="QRadioButton" name="rawGLRadio">
+        <property name="text">
+         <string>RawGLImageWidget</string>
         </property>
        </widget>
       </item>
@@ -250,6 +279,12 @@
    <extends>QDoubleSpinBox</extends>
    <header>pyqtgraph</header>
   </customwidget>
+  <customwidget>
+   <class>RawImageGLWidget</class>
+   <extends>QWidget</extends>
+   <header>pyqtgraph.widgets.RawImageWidget</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
diff --git a/examples/VideoTemplate_pyqt.py b/examples/VideoTemplate_pyqt.py
index c3430e2d..f61a5e46 100644
--- a/examples/VideoTemplate_pyqt.py
+++ b/examples/VideoTemplate_pyqt.py
@@ -1,9 +1,9 @@
 # -*- coding: utf-8 -*-
 
-# Form implementation generated from reading ui file './examples/VideoTemplate.ui'
+# Form implementation generated from reading ui file './VideoTemplate.ui'
 #
-# Created: Sun Nov  4 18:24:20 2012
-#      by: PyQt4 UI code generator 4.9.1
+# Created: Tue Jul  9 23:38:17 2013
+#      by: PyQt4 UI code generator 4.9.3
 #
 # WARNING! All changes made in this file will be lost!
 
@@ -17,31 +17,55 @@ except AttributeError:
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName(_fromUtf8("MainWindow"))
-        MainWindow.resize(985, 674)
+        MainWindow.resize(695, 798)
         self.centralwidget = QtGui.QWidget(MainWindow)
         self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
         self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
         self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
         self.gridLayout = QtGui.QGridLayout()
         self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
-        self.rawImg = RawImageWidget(self.centralwidget)
+        self.rawRadio = QtGui.QRadioButton(self.centralwidget)
+        self.rawRadio.setChecked(True)
+        self.rawRadio.setObjectName(_fromUtf8("rawRadio"))
+        self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
+        self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
+        self.gfxRadio.setObjectName(_fromUtf8("gfxRadio"))
+        self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
+        self.stack = QtGui.QStackedWidget(self.centralwidget)
+        self.stack.setObjectName(_fromUtf8("stack"))
+        self.page = QtGui.QWidget()
+        self.page.setObjectName(_fromUtf8("page"))
+        self.gridLayout_3 = QtGui.QGridLayout(self.page)
+        self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
+        self.graphicsView = GraphicsView(self.page)
+        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
+        self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
+        self.stack.addWidget(self.page)
+        self.page_2 = QtGui.QWidget()
+        self.page_2.setObjectName(_fromUtf8("page_2"))
+        self.gridLayout_4 = QtGui.QGridLayout(self.page_2)
+        self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4"))
+        self.rawImg = RawImageWidget(self.page_2)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
         self.rawImg.setSizePolicy(sizePolicy)
         self.rawImg.setObjectName(_fromUtf8("rawImg"))
-        self.gridLayout.addWidget(self.rawImg, 0, 0, 1, 1)
-        self.graphicsView = GraphicsView(self.centralwidget)
-        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
-        self.gridLayout.addWidget(self.graphicsView, 0, 1, 1, 1)
-        self.rawRadio = QtGui.QRadioButton(self.centralwidget)
-        self.rawRadio.setChecked(True)
-        self.rawRadio.setObjectName(_fromUtf8("rawRadio"))
-        self.gridLayout.addWidget(self.rawRadio, 1, 0, 1, 1)
-        self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
-        self.gfxRadio.setObjectName(_fromUtf8("gfxRadio"))
-        self.gridLayout.addWidget(self.gfxRadio, 1, 1, 1, 1)
+        self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
+        self.stack.addWidget(self.page_2)
+        self.page_3 = QtGui.QWidget()
+        self.page_3.setObjectName(_fromUtf8("page_3"))
+        self.gridLayout_5 = QtGui.QGridLayout(self.page_3)
+        self.gridLayout_5.setObjectName(_fromUtf8("gridLayout_5"))
+        self.rawGLImg = RawImageGLWidget(self.page_3)
+        self.rawGLImg.setObjectName(_fromUtf8("rawGLImg"))
+        self.gridLayout_5.addWidget(self.rawGLImg, 0, 0, 1, 1)
+        self.stack.addWidget(self.page_3)
+        self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
+        self.rawGLRadio = QtGui.QRadioButton(self.centralwidget)
+        self.rawGLRadio.setObjectName(_fromUtf8("rawGLRadio"))
+        self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
         self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
         self.label = QtGui.QLabel(self.centralwidget)
         self.label.setObjectName(_fromUtf8("label"))
@@ -130,12 +154,14 @@ class Ui_MainWindow(object):
         MainWindow.setCentralWidget(self.centralwidget)
 
         self.retranslateUi(MainWindow)
+        self.stack.setCurrentIndex(2)
         QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
     def retranslateUi(self, MainWindow):
         MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
-        self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget (unscaled; faster)", None, QtGui.QApplication.UnicodeUTF8))
-        self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem (scaled; slower)", None, QtGui.QApplication.UnicodeUTF8))
+        self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8))
+        self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8))
+        self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8))
         self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8))
         self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8))
         self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8))
@@ -150,4 +176,5 @@ class Ui_MainWindow(object):
         self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8))
         self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
 
-from pyqtgraph import SpinBox, GradientWidget, GraphicsView, RawImageWidget
+from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget
+from pyqtgraph import GradientWidget, SpinBox, GraphicsView, RawImageWidget
diff --git a/examples/VideoTemplate_pyside.py b/examples/VideoTemplate_pyside.py
index d19e0f23..d0db5eff 100644
--- a/examples/VideoTemplate_pyside.py
+++ b/examples/VideoTemplate_pyside.py
@@ -1,9 +1,9 @@
 # -*- coding: utf-8 -*-
 
-# Form implementation generated from reading ui file './examples/VideoTemplate.ui'
+# Form implementation generated from reading ui file './VideoTemplate.ui'
 #
-# Created: Sun Nov  4 18:24:21 2012
-#      by: pyside-uic 0.2.13 running on PySide 1.1.0
+# Created: Tue Jul  9 23:38:19 2013
+#      by: pyside-uic 0.2.13 running on PySide 1.1.2
 #
 # WARNING! All changes made in this file will be lost!
 
@@ -12,31 +12,55 @@ from PySide import QtCore, QtGui
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName("MainWindow")
-        MainWindow.resize(985, 674)
+        MainWindow.resize(695, 798)
         self.centralwidget = QtGui.QWidget(MainWindow)
         self.centralwidget.setObjectName("centralwidget")
         self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
         self.gridLayout_2.setObjectName("gridLayout_2")
         self.gridLayout = QtGui.QGridLayout()
         self.gridLayout.setObjectName("gridLayout")
-        self.rawImg = RawImageWidget(self.centralwidget)
+        self.rawRadio = QtGui.QRadioButton(self.centralwidget)
+        self.rawRadio.setChecked(True)
+        self.rawRadio.setObjectName("rawRadio")
+        self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
+        self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
+        self.gfxRadio.setObjectName("gfxRadio")
+        self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
+        self.stack = QtGui.QStackedWidget(self.centralwidget)
+        self.stack.setObjectName("stack")
+        self.page = QtGui.QWidget()
+        self.page.setObjectName("page")
+        self.gridLayout_3 = QtGui.QGridLayout(self.page)
+        self.gridLayout_3.setObjectName("gridLayout_3")
+        self.graphicsView = GraphicsView(self.page)
+        self.graphicsView.setObjectName("graphicsView")
+        self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
+        self.stack.addWidget(self.page)
+        self.page_2 = QtGui.QWidget()
+        self.page_2.setObjectName("page_2")
+        self.gridLayout_4 = QtGui.QGridLayout(self.page_2)
+        self.gridLayout_4.setObjectName("gridLayout_4")
+        self.rawImg = RawImageWidget(self.page_2)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
         self.rawImg.setSizePolicy(sizePolicy)
         self.rawImg.setObjectName("rawImg")
-        self.gridLayout.addWidget(self.rawImg, 0, 0, 1, 1)
-        self.graphicsView = GraphicsView(self.centralwidget)
-        self.graphicsView.setObjectName("graphicsView")
-        self.gridLayout.addWidget(self.graphicsView, 0, 1, 1, 1)
-        self.rawRadio = QtGui.QRadioButton(self.centralwidget)
-        self.rawRadio.setChecked(True)
-        self.rawRadio.setObjectName("rawRadio")
-        self.gridLayout.addWidget(self.rawRadio, 1, 0, 1, 1)
-        self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
-        self.gfxRadio.setObjectName("gfxRadio")
-        self.gridLayout.addWidget(self.gfxRadio, 1, 1, 1, 1)
+        self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
+        self.stack.addWidget(self.page_2)
+        self.page_3 = QtGui.QWidget()
+        self.page_3.setObjectName("page_3")
+        self.gridLayout_5 = QtGui.QGridLayout(self.page_3)
+        self.gridLayout_5.setObjectName("gridLayout_5")
+        self.rawGLImg = RawImageGLWidget(self.page_3)
+        self.rawGLImg.setObjectName("rawGLImg")
+        self.gridLayout_5.addWidget(self.rawGLImg, 0, 0, 1, 1)
+        self.stack.addWidget(self.page_3)
+        self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
+        self.rawGLRadio = QtGui.QRadioButton(self.centralwidget)
+        self.rawGLRadio.setObjectName("rawGLRadio")
+        self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
         self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
         self.label = QtGui.QLabel(self.centralwidget)
         self.label.setObjectName("label")
@@ -125,12 +149,14 @@ class Ui_MainWindow(object):
         MainWindow.setCentralWidget(self.centralwidget)
 
         self.retranslateUi(MainWindow)
+        self.stack.setCurrentIndex(2)
         QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
     def retranslateUi(self, MainWindow):
         MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
-        self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget (unscaled; faster)", None, QtGui.QApplication.UnicodeUTF8))
-        self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem (scaled; slower)", None, QtGui.QApplication.UnicodeUTF8))
+        self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8))
+        self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8))
+        self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8))
         self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8))
         self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8))
         self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8))
@@ -145,4 +171,5 @@ class Ui_MainWindow(object):
         self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8))
         self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
 
-from pyqtgraph import SpinBox, GradientWidget, GraphicsView, RawImageWidget
+from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget
+from pyqtgraph import GradientWidget, SpinBox, GraphicsView, RawImageWidget
diff --git a/examples/parametertree.py b/examples/parametertree.py
index 4c5d7275..c600d1be 100644
--- a/examples/parametertree.py
+++ b/examples/parametertree.py
@@ -139,14 +139,19 @@ p.param('Save/Restore functionality', 'Restore State').sigActivated.connect(rest
 ## Create two ParameterTree widgets, both accessing the same data
 t = ParameterTree()
 t.setParameters(p, showTop=False)
-t.show()
 t.setWindowTitle('pyqtgraph example: Parameter Tree')
-t.resize(400,800)
 t2 = ParameterTree()
 t2.setParameters(p, showTop=False)
-t2.show()
-t2.resize(400,800)
-    
+
+win = QtGui.QWidget()
+layout = QtGui.QGridLayout()
+win.setLayout(layout)
+layout.addWidget(QtGui.QLabel("These are two views of the same data. They should always display the same values."), 0,  0, 1, 2)
+layout.addWidget(t, 1, 0, 1, 1)
+layout.addWidget(t2, 1, 1, 1, 1)
+win.show()
+win.resize(800,800)
+
 ## test save/restore
 s = p.saveState()
 p.restoreState(s)
diff --git a/pyqtgraph/__init__.py b/pyqtgraph/__init__.py
index d83e0ec0..b1a05835 100644
--- a/pyqtgraph/__init__.py
+++ b/pyqtgraph/__init__.py
@@ -255,7 +255,7 @@ def exit():
     ## close file handles
     os.closerange(3, 4096) ## just guessing on the maximum descriptor count..
     
-    os._exit(os.EX_OK)
+    os._exit(0)
     
 
 
diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py
index a5e25a2f..033aab42 100644
--- a/pyqtgraph/graphicsItems/ROI.py
+++ b/pyqtgraph/graphicsItems/ROI.py
@@ -49,7 +49,13 @@ class ROI(GraphicsObject):
     sigRegionChanged        Emitted any time the position of the ROI changes,
                             including while it is being dragged by the user.
     sigHoverEvent           Emitted when the mouse hovers over the ROI.
-    sigClicked              Emitted when the user clicks on the ROI
+    sigClicked              Emitted when the user clicks on the ROI.
+                            Note that clicking is disabled by default to prevent
+                            stealing clicks from objects behind the ROI. To 
+                            enable clicking, call 
+                            roi.setAcceptedMouseButtons(QtCore.Qt.LeftButton). 
+                            See QtGui.QGraphicsItem documentation for more 
+                            details.
     sigRemoveRequested      Emitted when the user selects 'remove' from the 
                             ROI's context menu (if available).
     ----------------------- ----------------------------------------------------
diff --git a/pyqtgraph/parametertree/parameterTypes.py b/pyqtgraph/parametertree/parameterTypes.py
index 28e1e618..51f0be64 100644
--- a/pyqtgraph/parametertree/parameterTypes.py
+++ b/pyqtgraph/parametertree/parameterTypes.py
@@ -619,9 +619,15 @@ class TextParameterItem(WidgetParameterItem):
         self.addChild(self.subItem)
 
     def treeWidgetChanged(self):
+        ## TODO: fix so that superclass method can be called
+        ## (WidgetParameter should just natively support this style)
+        #WidgetParameterItem.treeWidgetChanged(self)
         self.treeWidget().setFirstItemColumnSpanned(self.subItem, True)
         self.treeWidget().setItemWidget(self.subItem, 0, self.textBox)
-        self.setExpanded(True)
+        
+        # for now, these are copied from ParameterItem.treeWidgetChanged
+        self.setHidden(not self.param.opts.get('visible', True))
+        self.setExpanded(self.param.opts.get('expanded', True))
         
     def makeWidget(self):
         self.textBox = QtGui.QTextEdit()
diff --git a/pyqtgraph/widgets/RawImageWidget.py b/pyqtgraph/widgets/RawImageWidget.py
index ea5c98a0..a780f463 100644
--- a/pyqtgraph/widgets/RawImageWidget.py
+++ b/pyqtgraph/widgets/RawImageWidget.py
@@ -11,8 +11,8 @@ import numpy as np
 class RawImageWidget(QtGui.QWidget):
     """
     Widget optimized for very fast video display. 
-    Generally using an ImageItem inside GraphicsView is fast enough,
-    but if you need even more performance, this widget is about as fast as it gets (but only in unscaled mode).
+    Generally using an ImageItem inside GraphicsView is fast enough.
+    On some systems this may provide faster video. See the VideoSpeedTest example for benchmarking.
     """
     def __init__(self, parent=None, scaled=False):
         """
@@ -59,26 +59,82 @@ class RawImageWidget(QtGui.QWidget):
         p.end()
 
 if HAVE_OPENGL:
+    from OpenGL.GL import *
     class RawImageGLWidget(QtOpenGL.QGLWidget):
         """
         Similar to RawImageWidget, but uses a GL widget to do all drawing.
-        Generally this will be about as fast as using GraphicsView + ImageItem,
-        but performance may vary on some platforms.
+        Perfomance varies between platforms; see examples/VideoSpeedTest for benchmarking.
         """
         def __init__(self, parent=None, scaled=False):
             QtOpenGL.QGLWidget.__init__(self, parent=None)
             self.scaled = scaled
             self.image = None
+            self.uploaded = False
+            self.smooth = False
+            self.opts = None
 
-        def setImage(self, img):
-            self.image = fn.makeQImage(img)
+        def setImage(self, img, *args, **kargs):
+            """
+            img must be ndarray of shape (x,y), (x,y,3), or (x,y,4).
+            Extra arguments are sent to functions.makeARGB
+            """
+            self.opts = (img, args, kargs)
+            self.image = None
+            self.uploaded = False
             self.update()
 
-        def paintEvent(self, ev):
+        def initializeGL(self):
+            self.texture = glGenTextures(1)
+            
+        def uploadTexture(self):
+            glEnable(GL_TEXTURE_2D)
+            glBindTexture(GL_TEXTURE_2D, self.texture)
+            if self.smooth:
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
+            else:
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
+            #glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER)
+            shape = self.image.shape
+            
+            ### Test texture dimensions first
+            #glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
+            #if glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH) == 0:
+                #raise Exception("OpenGL failed to create 2D texture (%dx%d); too large for this hardware." % shape[:2])
+            
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, self.image.transpose((1,0,2)))
+            glDisable(GL_TEXTURE_2D)
+            
+        def paintGL(self):
             if self.image is None:
-                return
-            p = QtGui.QPainter(self)
-            p.drawImage(self.rect(), self.image)
-            p.end()
+                if self.opts is None:
+                    return
+                img, args, kwds = self.opts
+                kwds['useRGBA'] = True
+                self.image, alpha = fn.makeARGB(img, *args, **kwds)
+            
+            if not self.uploaded:
+                self.uploadTexture()
+            
+            glViewport(0, 0, self.width(), self.height())
+            glEnable(GL_TEXTURE_2D)
+            glBindTexture(GL_TEXTURE_2D, self.texture)
+            glColor4f(1,1,1,1)
+
+            glBegin(GL_QUADS)
+            glTexCoord2f(0,0)
+            glVertex3f(-1,-1,0)
+            glTexCoord2f(1,0)
+            glVertex3f(1, -1, 0)
+            glTexCoord2f(1,1)
+            glVertex3f(1, 1, 0)
+            glTexCoord2f(0,1)
+            glVertex3f(-1, 1, 0)
+            glEnd()
+            glDisable(GL_TEXTURE_3D)
+            
 
 
-- 
GitLab