wxSashWindow Problem

Hello friends,

I am trying to implement the equivalent of Dock windows in my application, but I got stuck right at the beginning:

I tried to make a derivative of wxSashWindow (SashSubPanel) for use as Dock panes, but unfortunately the children that I associate with it arent getting rendered to screen. I tried to add a Sizer to the wxSashWindow, but again no luck I also tried additionally deriving from wxPyPanel, but that too does no good.

I am including the source for my program along with this email. In advance, I apologize if this email bothers someone due to its size.

I would also like some information regarding how best to handle the resizes caused by pressing the SubPanel show/hide button. How can I make this class behave better with the other controls on the frame ? Is it necessary to make changes for this if SubPanels always exist within Dock windows (Dock yet to be coded) ?

from wxPython.wx import *
from wxPython.lib.buttons import wxGenBitmapTextToggleButton, wxGenToggleButton

class SubPanelButton(wxGenToggleButton):
    def OnPaint(self, event):
        (width, height) = self.GetClientSizeTuple()
        x1 = y1 = 0
        x2 = width-1
        y2 = height-1
        dc = wxBufferedPaintDC(self)
        if self.up:
            dc.SetBackground(wxBrush(self.GetBackgroundColour(), wxSOLID))
        else:
            dc.SetBackground(wxBrush(self.faceDnClr, wxSOLID))
        dc.Clear()
        self.DrawBezel(dc, x1, y1, x2, y2)
        self.DrawLabel(dc, width, height)
        if self.hasFocus and self.useFocusInd:
            self.DrawFocusIndicator(dc, width, height)

    def DrawFocusIndicator(self, dc, w, h):
        self.DrawLabel(dc, w, h)
                   def DrawBezel(self, dc, x1, y1, x2, y2):
        self.bezelWidth = 1
        # draw the upper left sides
        dc.SetBrush(wxBLACK_BRUSH)
        if self.up:
            dc.SetPen(self.highlightPen)
        else:
            dc.SetPen(self.shadowPen)
        for i in range(self.bezelWidth):
            dc.DrawLine(x1+i, y1, x1+i, y2-i)
            dc.DrawLine(x1, y1+i, x2-i, y1+i)

        # draw the lower right sides
        if self.up:
            dc.SetPen(self.shadowPen)
        else:
            dc.SetPen(self.highlightPen)
        for i in range(self.bezelWidth):
            dc.DrawLine(x1+i, y2-i, x2+1, y2-i)
            dc.DrawLine(x2-i, y1+i, x2-i, y2)
        dc.SetBrush(wxNullBrush)

       def DrawLabel(self, dc, width, height, dw=0, dy=0):
        bw = bh = 16 # arrow size

        dc.SetFont(self.GetFont())
        if self.IsEnabled():
            dc.SetTextForeground(self.GetForegroundColour())
        else:
            dc.SetTextForeground(wxSystemSettings_GetSystemColour(wxSYS_COLOUR_GRAYTEXT))

        label = self.GetLabel()
        tw, th = dc.GetTextExtent(label) # size of text
        if not self.up:
            dw = dy = self.labelDelta
        pos_x = bw/4
        pos_y = (height-bh)/2
        if self.hasFocus and self.useFocusInd:
            dc.SetBrush(wxBLACK_BRUSH)
            dc.SetPen(self.shadowPen) if self.up:
                dc.DrawPolygon([(pos_x,pos_y),(pos_x+5, pos_y+5),(pos_x,pos_y+10)], pos_x, pos_y )
            else:
                dc.DrawPolygon([(pos_x-2,pos_y+2),(pos_x+8, pos_y+2),(pos_x+3,pos_y+7)], pos_x, pos_y )
        else:
            dc.SetBrush(wxWHITE_BRUSH)
            dc.SetPen(self.highlightPen)
            if self.up:
                dc.DrawPolygon([(pos_x,pos_y),(pos_x+5, pos_y+5),(pos_x,pos_y+10)], pos_x, pos_y )
            else:
                dc.DrawPolygon([(pos_x-2,pos_y+2),(pos_x+8, pos_y+2),(pos_x+3,pos_y+7)], pos_x, pos_y )
        pos_x = pos_x + 2 # extra spacing from arrow
        dc.DrawText(label, pos_x + dw+bw, (height-th)/2+dy) # draw the text

class SubPanel(wxPyPanel):
    def __init__(self, parent, id, text, panel, isOpen = False, *args, **kwds):
        kwds["style"] = wxTAB_TRAVERSAL|wxSIMPLE_BORDER
        wxPyPanel.__init__(self, parent, id, *args, **kwds)

        self.panel_2 = panel
        global ID_B; ID_B = wxNewId()
        self.panel_2.Reparent(self)
        self.button_1 = SubPanelButton(self, ID_B , text)
        if isOpen:
            self.button_1.SetToggle(True)
            self.shown = True
        else:
            self.button_1.SetToggle(False)
            self.shown = False
        self.__set_properties()
        self.__do_layout()
        EVT_BUTTON(self, ID_B, self.OnButton)
                   def OnButton(self, event):
        if self.shown == True:
            self.sizer_1.Show( self.panel_2, False )
            self.panel_2.Show(False)
            self.shown = False
            w, h = self.button_1.GetSizeTuple()
            w = w+10
            self.sizer_1.Layout()
        else:
            self.sizer_1.Show( self.panel_2, True )
            self.panel_2.Show(True)
            self.shown = True
            w, h = self.button_1.GetSizeTuple()
            sz = self.panel_2.GetAdjustedBestSize()
            pw,ph = sz.width, sz.height
            w = w+10
            h = ph+h+10 #includes borders
            self.sizer_1.Layout()
        self.GetContainingSizer().SetItemMinSize(self,w,h)
        self.GetContainingSizer().Layout()
        self.GetParent().Layout()
                  def __set_properties(self):
        pass

    def __do_layout(self):
        self.sizer_1 = wxBoxSizer(wxVERTICAL)
        self.sizer_1.Add(self.button_1, 0, wxEXPAND, 0)
        self.panel_2.SetAutoLayout(1)
        self.panel_2.Show(False)
        self.sizer_1.Add(self.panel_2, 1, wxALL|wxEXPAND, 4)
        if self.shown:
            self.sizer_1.Show(self.panel_2, True )
        else:
            self.sizer_1.Show(self.panel_2, False )
        self.SetAutoLayout(1)
        self.SetSizer(self.sizer_1)
        self.sizer_1.Fit(self)
        self.sizer_1.Layout()
        self.sizer_1.SetSizeHints(self)

class SashSubPanel( wxSashWindow ):
    def __init__(self, parent, id, text, panel, isOpen = False, *args, **kwds):
        kwds["style"] = wxTAB_TRAVERSAL|wxSIMPLE_BORDER
## wxPyPanel.__init__(self, parent, id, *args, **kwds)
        wxSashWindow.__init__(self, parent, id, style=wxSW_3DSASH|wxCLIP_CHILDREN)

        self.panel_2 = panel
        global ID_B; ID_B = wxNewId()
## self.mainPanel = wxPyPanel( self, -1)
## self.panel_2.Reparent(self)
        self.button_1 = SubPanelButton(self, ID_B , text)
        if isOpen:
            self.button_1.SetToggle(True)
            self.shown = True
        else:
            self.button_1.SetToggle(False)
            self.shown = False
        self.__set_properties()
        self.__do_layout()
        EVT_BUTTON(self, ID_B, self.OnButton)
       
                   def OnButton(self, event):
        if self.shown == True:
            self.sizer_1.Show( self.panel_2, False )
            self.panel_2.Show(False)
            self.shown = False
            w, h = self.button_1.GetSizeTuple()
            w = w+10
            self.sizer_1.Layout()
        else:
            self.sizer_1.Show( self.panel_2, True )
            self.panel_2.Show(True)
            self.shown = True
            w, h = self.button_1.GetSizeTuple()
            sz = self.panel_2.GetAdjustedBestSize()
            pw,ph = sz.width, sz.height
            w = w+10
            h = ph+h+10 #includes borders
            self.sizer_1.Layout()
        self.GetContainingSizer().SetItemMinSize(self,w,h)
        self.GetContainingSizer().Layout()
        self.GetParent().Layout()
                  def __set_properties(self):
        wxSashWindow.SetSashVisible(self, wxSASH_BOTTOM, True)

    def __do_layout(self):
        self.sizer_1 = wxBoxSizer(wxVERTICAL)
        self.sizer_1.Add(self.button_1, 0, wxEXPAND, 0)
        self.panel_2.SetAutoLayout(1)
        self.panel_2.Show(False)
        self.sizer_1.Add(self.panel_2, 1, wxALL|wxEXPAND, 4)
        if self.shown:
            self.sizer_1.Show(self.panel_2, True )
        else:
            self.sizer_1.Show(self.panel_2, False )
        self.SetAutoLayout(1)
        self.SetSizer(self.sizer_1)
        self.SetAutoLayout(True)
        self.sizer_1.Fit(self)
        self.sizer_1.Layout()
        self.sizer_1.SetSizeHints(self)

class TheFrame(wxFrame):
       def __init__(self, *args, **kwds):
        kwds["style"] = wxDEFAULT_FRAME_STYLE
        wxFrame.__init__(self, *args, **kwds)
               p = wxPanel(self, -1)
        szz = wxBoxSizer(wxVERTICAL)
        b = wxButton(p, -1, "Hello")
        szz.Add(b, 0, wxEXPAND, 0)
        p.SetSizer(szz)
        szz.Fit(p)
        szz.Layout()
        szz.SetSizeHints(p)
               sp = SubPanel(self, -1, "Hello", p, True)
        sp.Show(True)
         p = wxPanel(self, -1)
        szz = wxBoxSizer(wxVERTICAL)
        b = wxButton(p, -1, "Hello")
        szz.Add(b, 0, wxEXPAND, 0)
        p.SetSizer(szz)
        szz.Fit(p)
        szz.Layout()
        szz.SetSizeHints(p)
               ssp = SashSubPanel(self, -1, "Hello", p, True)
        p.Reparent(ssp)
        ssp.Show(True)

               sz = wxBoxSizer(wxVERTICAL)
        sz.Add(sp, 1, wxEXPAND|wxALL, 4)
        sz.Add(ssp, 1, wxEXPAND|wxALL, 4)
        self.SetSizer(sz)
        sz.Fit(self)
        sz.Layout()
        sz.SetSizeHints(self)

class ProjectrolApp(wxApp):
    def OnInit(self):
        wxInitAllImageHandlers()
        mainFrame = TheFrame(None, -1, "Hello")
        self.SetTopWindow(mainFrame)
        mainFrame.Show(True)
        return True

if __name__ == "__main__":
    app = ProjectrolApp(0)
    app.MainLoop()

I'm not really shure what are you trying to do BUT here is an ideea
put the toggle buttons AND the Panels in a BoxSizer(wx.VERTICAL) in the following order
Button, Panel, Button, Panel, etc. Add the components with proportion=0 for buttons and proportion=1 for panels then all you have to do is toogle the Panel's visibility via sizer.Show(somepanel)

Also... I think there might be something wrong with the whitespaces in the code you inserted in the email (might be a good idea to attach the .py file)

The size of your email is a little bit large, on the future try to create a minimum piece of code demonstrating the problem you have. This attempt to minimize the code might solve the problem :wink: It happen to me more than once :wink:

···

On Mon, 24 May 2004 00:33:48 +0530, Rajeev J Sebastian <rajeev_jsv@stendekrnd.com> wrote:

Hello friends,

I am trying to implement the equivalent of Dock windows in my application, but I got stuck right at the beginning:

I tried to make a derivative of wxSashWindow (SashSubPanel) for use as Dock panes, but unfortunately the children that I associate with it arent getting rendered to screen. I tried to add a Sizer to the wxSashWindow, but again no luck I also tried additionally deriving from wxPyPanel, but that too does no good.

I am including the source for my program along with this email. In advance, I apologize if this email bothers someone due to its size.

I would also like some information regarding how best to handle the resizes caused by pressing the SubPanel show/hide button. How can I make this class behave better with the other controls on the frame ? Is it necessary to make changes for this if SubPanels always exist within Dock windows (Dock yet to be coded) ?

--
Peter Damoc
Hacker Wannabe