Commit 9d81025e authored by dickelbeck's avatar dickelbeck

more layer widget work

parent 6601495c
...@@ -49,6 +49,9 @@ ...@@ -49,6 +49,9 @@
*/ */
#define LAYER_COLUMN_COUNT 4
/* XPM */ /* XPM */
static const char * clear_xpm[] = { static const char * clear_xpm[] = {
"28 14 1 1", "28 14 1 1",
...@@ -92,6 +95,43 @@ static const char * rightarrow_xpm[] = { ...@@ -92,6 +95,43 @@ static const char * rightarrow_xpm[] = {
" oO "}; " oO "};
/**
* Function layerId
* is here to allow saving a layer index within a control as its wxControl id,
* but to do so in a way that all child wxControl ids within a wxWindow are unique,
* since this is required by Windows.
* @see getLayerId()
*/
static int layerId( int aColumn, int aLayer )
{
int id = aLayer * LAYER_COLUMN_COUNT + aColumn;
return id;
}
/**
* Function getLayerId
* decodes \a aControlId to return a layer.
*/
static int getLayerId( int aControlId )
{
int layer = aControlId / LAYER_COLUMN_COUNT; // rounding is OK.
return layer;
}
/**
* Function makeColorTxt
* returns a string containing the numeric value of the color.
* in a form like 0x00000000. (Color is currently an index, not RGB).
*/
static wxString makeColorTxt( int aColor )
{
char colorValue[64];
sprintf( colorValue, "0x%08x", aColor );
return wxString( CONV_FROM_UTF8(colorValue) );
}
/** /**
* Struct LAYER_SPEC * Struct LAYER_SPEC
...@@ -123,28 +163,31 @@ struct LAYER_SPEC ...@@ -123,28 +163,31 @@ struct LAYER_SPEC
* it has no knowledge of a BOARD or anything. To use it you must derive from * it has no knowledge of a BOARD or anything. To use it you must derive from
* this class and implement the abstract functions: * this class and implement the abstract functions:
* <p> * <p>
* void ColorChange( int aLayer, int aColor ); * void OnColorChange( int aLayer, int aColor );
* <p> * <p>
* bool LayerChange( int aLayer ); * bool OnLayerSelect( int aLayer );
* <p>
* void OnLayerVisible( int aLayer, bool isVisible );
*/ */
class LAYER_WIDGET : public LAYER_PANEL_BASE class LAYER_WIDGET : public LAYER_PANEL_BASE
{ {
#define MAX_LAYER_ROWS 64 #define MAX_LAYER_ROWS 64
#define LAYER_COLUMN_COUNT 4
#define BUTT_SIZE_X 32 #define BUTT_SIZE_X 32
#define BUTT_SIZE_Y 22 #define BUTT_SIZE_Y 22
#define BUTT_VOID 6
protected: protected:
wxBitmap* m_BlankBitmap; wxBitmap* m_BlankBitmap;
wxBitmap* m_RightArrowBitmap; wxBitmap* m_RightArrowBitmap;
wxSize m_BitmapSize; wxSize m_BitmapSize;
wxStaticBitmap* m_Bitmaps[MAX_LAYER_ROWS];
int m_CurrentRow; ///< selected row of layer list int m_CurrentRow; ///< selected row of layer list
wxBitmap makeBitmap( int aColor ) static wxBitmap makeBitmap( int aColor )
{ {
wxBitmap bitmap( BUTT_SIZE_X, BUTT_SIZE_Y ); // the bitmap will be 8 pixels smaller than the button, leaving a
// border of 4 pixels on each side.
wxBitmap bitmap( BUTT_SIZE_X - 2 * BUTT_VOID, BUTT_SIZE_Y - 2 * BUTT_VOID );
wxBrush brush; wxBrush brush;
wxMemoryDC iconDC; wxMemoryDC iconDC;
...@@ -154,7 +197,7 @@ protected: ...@@ -154,7 +197,7 @@ protected:
brush.SetStyle( wxSOLID ); brush.SetStyle( wxSOLID );
iconDC.SetBrush( brush ); iconDC.SetBrush( brush );
iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y ); iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X - 2 * BUTT_VOID, BUTT_SIZE_Y - 2 * BUTT_VOID );
return bitmap; return bitmap;
} }
...@@ -175,14 +218,6 @@ protected: ...@@ -175,14 +218,6 @@ protected:
// save the color value in the name, no where else to put it. // save the color value in the name, no where else to put it.
ret->SetName( makeColorTxt( aColor ) ); ret->SetName( makeColorTxt( aColor ) );
ret->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
ret->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnRightDownLayers ), NULL, this );
/* cannot get this event without also the wxEVT_LEFT_DOWN firing first
ret->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( LAYER_WIDGET::OnLeftDClickLayers ), NULL, this );
*/
return ret; return ret;
} }
...@@ -191,11 +226,11 @@ protected: ...@@ -191,11 +226,11 @@ protected:
{ {
int row; int row;
wxObject* eventSource = event.GetEventObject(); wxWindow* eventSource = (wxWindow*) event.GetEventObject();
// if mouse event is coming from the m_LayerScrolledWindow and not one // if mouse event is coming from the m_LayerScrolledWindow and not one
// of its children, we have to find the row manually based on y coord. // of its children, we have to find the row manually based on y coord.
if( eventSource == (wxObject*) m_LayerScrolledWindow ) if( eventSource == m_LayerScrolledWindow )
{ {
int y = event.GetY(); int y = event.GetY();
...@@ -216,41 +251,29 @@ protected: ...@@ -216,41 +251,29 @@ protected:
row = rowCount - 1; row = rowCount - 1;
} }
// all nested controls on a given row will have the layer index as their ID
else else
{ {
int layer = ((wxWindow*)eventSource)->GetId(); // all nested controls on a given row will have their ID encoded with
// makeLayerId(), and the corresponding decoding is getLayerId()
int layer = getLayerId( eventSource ->GetId() );
row = findLayerRow( layer ); row = findLayerRow( layer );
} }
if( LayerChange( row ) ) // if owner allows this change. if( OnLayerSelect( row ) ) // if client allows this change.
SelectLayerRow( row ); SelectLayerRow( row );
} }
/** /**
* Function makeColorTxt * Function OnMiddleDownLayerColor
* returns a string containing the numeric value of the color. * is called only from a color button when user right clicks.
* in a form like 0x00000000. (Color is currently an index, not RGB).
*/
wxString makeColorTxt( int aColor )
{
char colorValue[64];
sprintf( colorValue, "0x%08x", aColor );
return wxString( CONV_FROM_UTF8(colorValue) );
}
/**
* Function OnRightDownLayers
* is called only from the color button when user right clicks.
*/ */
void OnRightDownLayers( wxMouseEvent& event ) void OnMiddleDownLayerColor( wxMouseEvent& event )
{ {
wxBitmapButton* eventSource = (wxBitmapButton*) event.GetEventObject(); wxBitmapButton* eventSource = (wxBitmapButton*) event.GetEventObject();
wxString colorTxt = eventSource->GetName(); wxString colorTxt = eventSource->GetName();
int oldColor = strtoul( CONV_TO_UTF8(colorTxt), NULL, 0 ); int oldColor = strtoul( CONV_TO_UTF8(colorTxt), NULL, 0 );
int newColor = DisplayColorFrame( this, oldColor ); int newColor = DisplayColorFrame( this, oldColor );
if( newColor >= 0 ) if( newColor >= 0 )
...@@ -258,11 +281,42 @@ protected: ...@@ -258,11 +281,42 @@ protected:
eventSource->SetName( makeColorTxt( newColor ) ); eventSource->SetName( makeColorTxt( newColor ) );
wxBitmap bm = makeBitmap( newColor ); wxBitmap bm = makeBitmap( newColor );
eventSource->SetBitmapLabel( bm ); eventSource->SetBitmapLabel( bm );
int layer = getLayerId( eventSource->GetId() );
// tell the client code.
OnColorChange( layer, newColor );
} }
} }
/**
* Function OnRightDownLayers
* puts up a popup menu for the layer panel.
*/
void OnRightDownLayers( wxMouseEvent& event )
{
// popup menu
printf( "OnRightDownLayers\n" );
}
/**
* Function OnLayerCheckBox
* handles the "is layer visible" checkbox and propogates the
* event to the client's notification function.
*/
void OnLayerCheckBox( wxCommandEvent& event )
{
wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
int layer = getLayerId( eventSource->GetId() );
OnLayerVisible( layer, eventSource->IsChecked() );
}
/** /**
* Function getLayerComp * Function getLayerComp
* returns the component within the m_LayersFlexGridSizer at aSizerNdx. * returns the component within the m_LayersFlexGridSizer at aSizerNdx.
...@@ -287,7 +341,7 @@ protected: ...@@ -287,7 +341,7 @@ protected:
// column 0 in the layer scroll window has a wxStaticBitmap, get its ID. // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row * LAYER_COLUMN_COUNT + 0 ); wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row * LAYER_COLUMN_COUNT + 0 );
if( aLayer == bm->GetId() ) if( aLayer == getLayerId( bm->GetId() ))
return row; return row;
} }
...@@ -309,31 +363,38 @@ protected: ...@@ -309,31 +363,38 @@ protected:
flags.Align(wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL); flags.Align(wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
// column 0 // column 0
m_Bitmaps[aRow] = new wxStaticBitmap( m_LayerScrolledWindow, aSpec.layer, *m_BlankBitmap, wxStaticBitmap* sbm = new wxStaticBitmap( m_LayerScrolledWindow, layerId( 0, aSpec.layer ),
wxDefaultPosition, m_BitmapSize ); *m_BlankBitmap, wxDefaultPosition, m_BitmapSize );
m_Bitmaps[aRow]->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this ); sbm->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
sbm->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnRightDownLayers ), NULL, this );
m_LayersFlexGridSizer->Insert( index+0, m_LayersFlexGridSizer->Insert( index+0,
new wxSizerItem( m_Bitmaps[aRow], wxSizerFlags().Align( wxALIGN_CENTER_VERTICAL ) ) ); new wxSizerItem( sbm, wxSizerFlags().Align( wxALIGN_CENTER_VERTICAL ) ) );
// column 1 // column 1
wxBitmapButton* bmb = makeColorButton( aSpec.color, aSpec.layer ); wxBitmapButton* bmb = makeColorButton( aSpec.color, layerId( 1, aSpec.layer ) );
bmb->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
bmb->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownLayerColor ), NULL, this );
bmb->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnRightDownLayers ), NULL, this );
bmb->SetToolTip( _("Right click to change layer color, left click to select layer" ) ); bmb->SetToolTip( _("Right click to change layer color, left click to select layer" ) );
m_LayersFlexGridSizer->Insert( index+1, m_LayersFlexGridSizer->Insert( index+1,
new wxSizerItem( bmb, flags ) ); new wxSizerItem( bmb, flags ) );
// column 2 // column 2
wxStaticText* st = new wxStaticText( m_LayerScrolledWindow, aSpec.layer, aSpec.layerName ); wxStaticText* st = new wxStaticText( m_LayerScrolledWindow, layerId( 2, aSpec.layer ), aSpec.layerName );
st->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this ); st->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
st->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnRightDownLayers ), NULL, this );
st->SetToolTip( _( "Click here to select this layer" ) ); st->SetToolTip( _( "Click here to select this layer" ) );
m_LayersFlexGridSizer->Insert( index+2, m_LayersFlexGridSizer->Insert( index+2,
new wxSizerItem( st, wxSizerFlags().Align( wxALIGN_CENTER_VERTICAL )) ); new wxSizerItem( st, wxSizerFlags().Align( wxALIGN_CENTER_VERTICAL )) );
// column 3 // column 3
wxCheckBox* cb = new wxCheckBox( m_LayerScrolledWindow, aSpec.layer, wxEmptyString ); wxCheckBox* cb = new wxCheckBox( m_LayerScrolledWindow, layerId( 3, aSpec.layer ), wxEmptyString );
cb->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( LAYER_WIDGET::OnLayerCheckBox ), NULL, this );
cb->SetToolTip( _( "Enable this for visibility" ) ); cb->SetToolTip( _( "Enable this for visibility" ) );
m_LayersFlexGridSizer->Insert( index+3, new wxSizerItem( cb, flags ) ); m_LayersFlexGridSizer->Insert( index+3, new wxSizerItem( cb, flags ) );
} }
public: public:
/** Constructor */ /** Constructor */
...@@ -342,13 +403,14 @@ public: ...@@ -342,13 +403,14 @@ public:
{ {
m_CurrentRow = 0; m_CurrentRow = 0;
memset( m_Bitmaps, 0, sizeof(m_Bitmaps) );
m_RightArrowBitmap = new wxBitmap( rightarrow_xpm ); m_RightArrowBitmap = new wxBitmap( rightarrow_xpm );
m_BlankBitmap = new wxBitmap( clear_xpm ); // translucent m_BlankBitmap = new wxBitmap( clear_xpm ); // translucent
m_BitmapSize = wxSize(m_BlankBitmap->GetWidth(), m_BlankBitmap->GetHeight()); m_BitmapSize = wxSize(m_BlankBitmap->GetWidth(), m_BlankBitmap->GetHeight());
m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnRightDownLayers ), NULL, this );
AppendLayerRow( LAYER_SPEC( wxT("layer 1"), 0, RED ) ); AppendLayerRow( LAYER_SPEC( wxT("layer 1"), 0, RED ) );
AppendLayerRow( LAYER_SPEC( wxT("layer 2"), 1, GREEN ) ); AppendLayerRow( LAYER_SPEC( wxT("layer 2"), 1, GREEN ) );
AppendLayerRow( LAYER_SPEC( wxT("brown_layer"), 2, BROWN ) ); AppendLayerRow( LAYER_SPEC( wxT("brown_layer"), 2, BROWN ) );
...@@ -356,9 +418,41 @@ public: ...@@ -356,9 +418,41 @@ public:
SelectLayerRow( 1 ); SelectLayerRow( 1 );
FitInside(); SetMinSize( GetPreferredSize() );
}
SetMinSize( GetSize() ); /**
* Function GetPreferredSize
* returns the preferred minimum size, taking into consideration the
* dynamic content. Nothing in wxWidgets was reliable enough.
*/
wxSize GetPreferredSize()
{
m_LayersFlexGridSizer->Layout();
wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
int totWidth = 0;
for( int i=0; i<LAYER_COLUMN_COUNT; ++i )
{
totWidth += widths[i] + m_LayersFlexGridSizer->GetHGap();
printf("widths[%d]:%d\n", i, widths[i] );
}
wxArrayInt heights = m_LayersFlexGridSizer->GetRowHeights();
int totHeight = 0;
int rowCount = GetLayerRowCount();
for( int i=0; i<rowCount; ++i )
{
totHeight += heights[i] + m_LayersFlexGridSizer->GetVGap();
printf("heights[%d]:%d\n", i, heights[i] );
}
wxSize layerPanelSize( totWidth, totHeight );
// this aint done yet, just a place holder for more work.
return layerPanelSize;
} }
...@@ -366,13 +460,12 @@ public: ...@@ -366,13 +460,12 @@ public:
* Function GetLayerRowCount * Function GetLayerRowCount
* returns the number of rows in the layer tab. * returns the number of rows in the layer tab.
*/ */
int GetLayerRowCount() int GetLayerRowCount() const
{ {
int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount(); int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount();
return controlCount / LAYER_COLUMN_COUNT; return controlCount / LAYER_COLUMN_COUNT;
} }
/** /**
* Function AppendLayerRow * Function AppendLayerRow
* appends a new row in the layer portion of the widget. * appends a new row in the layer portion of the widget.
...@@ -383,6 +476,15 @@ public: ...@@ -383,6 +476,15 @@ public:
insertLayerRow( nextRow, aSpec ); insertLayerRow( nextRow, aSpec );
} }
/**
* Function ClearLayerRows
* empties out the layer rows.
*/
void ClearLayerRows()
{
m_LayerScrolledWindow->DestroyChildren();
}
/** /**
* Function SelectLayerRow * Function SelectLayerRow
...@@ -390,6 +492,9 @@ public: ...@@ -390,6 +492,9 @@ public:
*/ */
bool SelectLayerRow( int aRow ) bool SelectLayerRow( int aRow )
{ {
// enable the layer tab at index 0
m_notebook->ChangeSelection( 0 );
if( (unsigned) aRow < (unsigned) GetLayerRowCount() ) if( (unsigned) aRow < (unsigned) GetLayerRowCount() )
{ {
int newNdx = LAYER_COLUMN_COUNT * aRow; int newNdx = LAYER_COLUMN_COUNT * aRow;
...@@ -403,6 +508,18 @@ public: ...@@ -403,6 +508,18 @@ public:
m_CurrentRow = aRow; m_CurrentRow = aRow;
// Change the focus to the wxBitmapButton in column 1 for this row.
// We really do not need or want the focus, but because we get focus
// and it changes the appearance of these wxBitmapButtons, if any focused
// button is going to look different, we want it to be the current
// row.
getLayerComp( newNdx + 1 /* 1 is column */ )->SetFocus();
// Make sure the desired layer row is visible.
// It seems that as of 2.8.2, setting the focus
// does this and generally I don't expect the scrolling to be needed at all because
// the minimum window size may end up being established by the number of layers.
return true; return true;
} }
return false; return false;
...@@ -410,7 +527,7 @@ public: ...@@ -410,7 +527,7 @@ public:
/** /**
* Function SelectLayer * Function SelectLayer
* changes the row selection in the layer list to the given layer. * changes the row selection in the layer list to \a aLayer provided.
*/ */
bool SelectLayer( int aLayer ) bool SelectLayer( int aLayer )
{ {
...@@ -418,21 +535,29 @@ public: ...@@ -418,21 +535,29 @@ public:
return SelectLayerRow( row ); return SelectLayerRow( row );
} }
//-----<abstract functions>------------------------------------------- //-----<abstract functions>-------------------------------------------
/** /**
* Function ColorChange * Function OnColorChange
* is called whenever the user changes the color of a layer. Derived * is called to notify client code about a layer color change. Derived
* classes will handle this accordingly. * classes will handle this accordingly.
*/ */
virtual void ColorChange( int aLayer, int aColor ) = 0; virtual void OnColorChange( int aLayer, int aColor ) = 0;
/**
* Function OnLayerSelect
* is called to notify client code whenever the user selects a different
* layer. Derived classes will handle this accordingly, and can deny
* the change by returning false.
*/
virtual bool OnLayerSelect( int aLayer ) = 0;
/** /**
* Function LayerChange * Function OnLayerVisible
* is called whenever the user selects a different layer. Derived classes * is called to notify client code about a layer visibility change.
* will handle this accordingly, and can deny the change by returning false.
*/ */
virtual bool LayerChange( int aLayer ) = 0; virtual void OnLayerVisible( int aLayer, bool isVisible ) = 0;
//-----</abstract functions>------------------------------------------ //-----</abstract functions>------------------------------------------
...@@ -449,7 +574,6 @@ public: ...@@ -449,7 +574,6 @@ public:
*/ */
class MYFRAME : public wxFrame class MYFRAME : public wxFrame
{ {
// example of how to derive from LAYER_WIDGET in order to provide the // example of how to derive from LAYER_WIDGET in order to provide the
// abstract methods. // abstract methods.
class MYLAYERS : public LAYER_WIDGET class MYLAYERS : public LAYER_WIDGET
...@@ -466,16 +590,28 @@ class MYFRAME : public wxFrame ...@@ -466,16 +590,28 @@ class MYFRAME : public wxFrame
{ {
} }
void ColorChange( int aLayer, int aColor ) void OnColorChange( int aLayer, int aColor )
{ {
printf("ColorChange( aLayer:%d, aColor:%d )\n", aLayer, aColor ); printf( "OnColorChange( aLayer:%d, aColor:%d )\n", aLayer, aColor );
// a test trigger only
if( aLayer == 2 )
{
ClearLayerRows();
printf(" GetLayerRowCount(): %d\n", GetLayerRowCount() );
}
} }
bool LayerChange( int aLayer ) bool OnLayerSelect( int aLayer )
{ {
printf( "LayerChange( aLayer:%d )\n", aLayer ); printf( "OnLayerSelect( aLayer:%d )\n", aLayer );
return true; return true;
} }
void OnLayerVisible( int aLayer, bool isVisible )
{
printf( "OnLayerVisible( aLayer:%d, isVisible:%d )\n", aLayer, isVisible );
}
}; };
...@@ -487,7 +623,7 @@ public: ...@@ -487,7 +623,7 @@ public:
// notify wxAUI which frame to use // notify wxAUI which frame to use
m_mgr.SetManagedWindow( this ); m_mgr.SetManagedWindow( this );
wxPanel* layerWidget = new MYLAYERS( this, this ); MYLAYERS* layerWidget = new MYLAYERS( this, this );
wxTextCtrl* text2 = new wxTextCtrl( this, -1, _( "Pane 2 - sample text" ), wxTextCtrl* text2 = new wxTextCtrl( this, -1, _( "Pane 2 - sample text" ),
wxDefaultPosition, wxSize( 200, 150 ), wxDefaultPosition, wxSize( 200, 150 ),
...@@ -499,11 +635,11 @@ public: ...@@ -499,11 +635,11 @@ public:
// add the panes to the manager // add the panes to the manager
wxAuiPaneInfo li; wxAuiPaneInfo li;
li.MinSize( layerWidget->GetSize() ); // ignored on linux li.MinSize( layerWidget->GetPreferredSize() ); // ignored on linux
li.BestSize( layerWidget->GetSize() ); li.BestSize( layerWidget->GetPreferredSize() );
li.Left(); li.Left();
li.MaximizeButton( false ); li.MaximizeButton( true );
li.MinimizeButton( false ); li.MinimizeButton( true );
li.CloseButton( false ); li.CloseButton( false );
li.Caption( wxT( "Layers" ) ); li.Caption( wxT( "Layers" ) );
m_mgr.AddPane( layerWidget, li ); m_mgr.AddPane( layerWidget, li );
...@@ -544,4 +680,4 @@ public: ...@@ -544,4 +680,4 @@ public:
DECLARE_APP( MyApp ); DECLARE_APP( MyApp );
IMPLEMENT_APP( MyApp ); IMPLEMENT_APP( MyApp );
#endif #endif // STAND_ALONE
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment