]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/widgets/bmpcombobox.cpp
Support using GetTextExtent() with empty string to get descent in wxOSX.
[wxWidgets.git] / samples / widgets / bmpcombobox.cpp
index 4495fc598a24702878f3e36f60a4347e181d928c..74b14b493cad638c77fb08bbc211d606c0c7fb42 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     Sep-01-2006
 // Id:          $Id$
 // Copyright:   (c) 2006 Jaakko Salli
 // Created:     Sep-01-2006
 // Id:          $Id$
 // Copyright:   (c) 2006 Jaakko Salli
-// License:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
@@ -139,8 +139,6 @@ protected:
     void OnTextButtonAll(wxCommandEvent& event);
 
     void OnUpdateUIInsert(wxUpdateUIEvent& event);
     void OnTextButtonAll(wxCommandEvent& event);
 
     void OnUpdateUIInsert(wxUpdateUIEvent& event);
-    void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
-    void OnUpdateUIAddSeveralWithImages(wxUpdateUIEvent& event);
     void OnUpdateUIClearButton(wxUpdateUIEvent& event);
     void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
     void OnUpdateUIItemManipulator(wxUpdateUIEvent& event);
     void OnUpdateUIClearButton(wxUpdateUIEvent& event);
     void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
     void OnUpdateUIItemManipulator(wxUpdateUIEvent& event);
@@ -218,8 +216,6 @@ BEGIN_EVENT_TABLE(BitmapComboBoxWidgetsPage, WidgetsPage)
     EVT_UPDATE_UI(BitmapComboBoxPage_Reset, BitmapComboBoxWidgetsPage::OnUpdateUIResetButton)
     EVT_UPDATE_UI(BitmapComboBoxPage_Insert, BitmapComboBoxWidgetsPage::OnUpdateUIInsert)
     EVT_UPDATE_UI(BitmapComboBoxPage_LoadFromFile, BitmapComboBoxWidgetsPage::OnUpdateUIInsert)
     EVT_UPDATE_UI(BitmapComboBoxPage_Reset, BitmapComboBoxWidgetsPage::OnUpdateUIResetButton)
     EVT_UPDATE_UI(BitmapComboBoxPage_Insert, BitmapComboBoxWidgetsPage::OnUpdateUIInsert)
     EVT_UPDATE_UI(BitmapComboBoxPage_LoadFromFile, BitmapComboBoxWidgetsPage::OnUpdateUIInsert)
-    EVT_UPDATE_UI(BitmapComboBoxPage_AddSeveral, BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveral)
-    EVT_UPDATE_UI(BitmapComboBoxPage_AddSeveralWithImages, BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveralWithImages)
     EVT_UPDATE_UI(BitmapComboBoxPage_Clear, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
     EVT_UPDATE_UI(BitmapComboBoxPage_DeleteText, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
     EVT_UPDATE_UI(BitmapComboBoxPage_Delete, BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton)
     EVT_UPDATE_UI(BitmapComboBoxPage_Clear, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
     EVT_UPDATE_UI(BitmapComboBoxPage_DeleteText, BitmapComboBoxWidgetsPage::OnUpdateUIClearButton)
     EVT_UPDATE_UI(BitmapComboBoxPage_Delete, BitmapComboBoxWidgetsPage::OnUpdateUIDeleteButton)
@@ -247,7 +243,7 @@ END_EVENT_TABLE()
     #define NATIVE_OR_GENERIC_CTRLS     GENERIC_CTRLS
 #endif
 
     #define NATIVE_OR_GENERIC_CTRLS     GENERIC_CTRLS
 #endif
 
-IMPLEMENT_WIDGETS_PAGE(BitmapComboBoxWidgetsPage, _T("BitmapCombobox"),
+IMPLEMENT_WIDGETS_PAGE(BitmapComboBoxWidgetsPage, wxT("BitmapCombobox"),
                        NATIVE_OR_GENERIC_CTRLS | WITH_ITEMS_CTRLS | COMBO_CTRLS
                        );
 
                        NATIVE_OR_GENERIC_CTRLS | WITH_ITEMS_CTRLS | COMBO_CTRLS
                        );
 
@@ -303,39 +299,39 @@ void BitmapComboBoxWidgetsPage::CreateContent()
     wxSizer *sizerLeft = new wxBoxSizer(wxVERTICAL);
 
     // left pane - style box
     wxSizer *sizerLeft = new wxBoxSizer(wxVERTICAL);
 
     // left pane - style box
-    wxStaticBox *box = new wxStaticBox(this, wxID_ANY, _T("&Set style"));
+    wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("&Set style"));
 
 
     // should be in sync with ComboKind_XXX values
     static const wxString kinds[] =
     {
 
 
     // should be in sync with ComboKind_XXX values
     static const wxString kinds[] =
     {
-        _T("default"),
-        _T("simple"),
-        _T("drop down"),
+        wxT("default"),
+        wxT("simple"),
+        wxT("drop down"),
     };
 
     };
 
-    m_radioKind = new wxRadioBox(this, wxID_ANY, _T("Combobox &kind:"),
+    m_radioKind = new wxRadioBox(this, wxID_ANY, wxT("Combobox &kind:"),
                                  wxDefaultPosition, wxDefaultSize,
                                  WXSIZEOF(kinds), kinds,
                                  1, wxRA_SPECIFY_COLS);
 
     wxSizer *sizerStyle = new wxStaticBoxSizer(box, wxVERTICAL);
 
                                  wxDefaultPosition, wxDefaultSize,
                                  WXSIZEOF(kinds), kinds,
                                  1, wxRA_SPECIFY_COLS);
 
     wxSizer *sizerStyle = new wxStaticBoxSizer(box, wxVERTICAL);
 
-    m_chkSort = CreateCheckBoxAndAddToSizer(sizerStyle, _T("&Sort items"));
-    m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerStyle, _T("&Read only"));
+    m_chkSort = CreateCheckBoxAndAddToSizer(sizerStyle, wxT("&Sort items"));
+    m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerStyle, wxT("&Read only"));
 
 
-    wxButton *btn = new wxButton(this, BitmapComboBoxPage_Reset, _T("&Reset"));
+    wxButton *btn = new wxButton(this, BitmapComboBoxPage_Reset, wxT("&Reset"));
     sizerStyle->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 3);
 
     sizerLeft->Add(sizerStyle, 0, wxGROW | wxALIGN_CENTRE_HORIZONTAL);
     sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
 
     // left pane - other options box
     sizerStyle->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 3);
 
     sizerLeft->Add(sizerStyle, 0, wxGROW | wxALIGN_CENTRE_HORIZONTAL);
     sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
 
     // left pane - other options box
-    box = new wxStaticBox(this, wxID_ANY, _T("Demo options"));
+    box = new wxStaticBox(this, wxID_ANY, wxT("Demo options"));
 
     wxSizer *sizerOptions = new wxStaticBoxSizer(box, wxVERTICAL);
 
 
     wxSizer *sizerOptions = new wxStaticBoxSizer(box, wxVERTICAL);
 
-    sizerRow = CreateSizerWithSmallTextAndLabel(_T("Control &height:"),
+    sizerRow = CreateSizerWithSmallTextAndLabel(wxT("Control &height:"),
                                                 BitmapComboBoxPage_ChangeHeight,
                                                 &m_textChangeHeight);
     m_textChangeHeight->SetSize(20, wxDefaultCoord);
                                                 BitmapComboBoxPage_ChangeHeight,
                                                 &m_textChangeHeight);
     m_textChangeHeight->SetSize(20, wxDefaultCoord);
@@ -345,42 +341,42 @@ void BitmapComboBoxWidgetsPage::CreateContent()
 
     // middle pane
     wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
 
     // middle pane
     wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
-        _T("&Change wxBitmapComboBox contents"));
+        wxT("&Change wxBitmapComboBox contents"));
     wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
 
     wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
 
-    btn = new wxButton(this, BitmapComboBoxPage_ContainerTests, _T("Run &tests"));
+    btn = new wxButton(this, BitmapComboBoxPage_ContainerTests, wxT("Run &tests"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
 #if wxUSE_IMAGE
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
 #if wxUSE_IMAGE
-    btn = new wxButton(this, BitmapComboBoxPage_AddWidgetIcons, _T("Add &widget icons"));
+    btn = new wxButton(this, BitmapComboBoxPage_AddWidgetIcons, wxT("Add &widget icons"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
-    btn = new wxButton(this, BitmapComboBoxPage_LoadFromFile, _T("Insert image from &file"));
+    btn = new wxButton(this, BitmapComboBoxPage_LoadFromFile, wxT("Insert image from &file"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
-    btn = new wxButton(this, BitmapComboBoxPage_SetFromFile, _T("&Set image from file"));
+    btn = new wxButton(this, BitmapComboBoxPage_SetFromFile, wxT("&Set image from file"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 #endif
 
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 #endif
 
-    btn = new wxButton(this, BitmapComboBoxPage_AddSeveralWithImages, _T("A&ppend a few strings with images"));
+    btn = new wxButton(this, BitmapComboBoxPage_AddSeveralWithImages, wxT("A&ppend a few strings with images"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
-    btn = new wxButton(this, BitmapComboBoxPage_AddSeveral, _T("Append a &few strings"));
+    btn = new wxButton(this, BitmapComboBoxPage_AddSeveral, wxT("Append a &few strings"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
-    btn = new wxButton(this, BitmapComboBoxPage_AddMany, _T("Append &many strings"));
+    btn = new wxButton(this, BitmapComboBoxPage_AddMany, wxT("Append &many strings"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
     sizerRow = CreateSizerWithTextAndButton(BitmapComboBoxPage_Delete,
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
     sizerRow = CreateSizerWithTextAndButton(BitmapComboBoxPage_Delete,
-                                            _T("&Delete this item"),
+                                            wxT("&Delete this item"),
                                             BitmapComboBoxPage_DeleteText,
                                             &m_textDelete);
     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
 
                                             BitmapComboBoxPage_DeleteText,
                                             &m_textDelete);
     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
 
-    btn = new wxButton(this, BitmapComboBoxPage_DeleteSel, _T("Delete &selection"));
+    btn = new wxButton(this, BitmapComboBoxPage_DeleteSel, wxT("Delete &selection"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
-    btn = new wxButton(this, BitmapComboBoxPage_Clear, _T("&Clear"));
+    btn = new wxButton(this, BitmapComboBoxPage_Clear, wxT("&Clear"));
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
 #if wxUSE_IMAGE
     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
 
 #if wxUSE_IMAGE
@@ -437,7 +433,7 @@ void BitmapComboBoxWidgetsPage::CreateCombo()
     switch ( m_radioKind->GetSelection() )
     {
         default:
     switch ( m_radioKind->GetSelection() )
     {
         default:
-            wxFAIL_MSG( _T("unknown combo kind") );
+            wxFAIL_MSG( wxT("unknown combo kind") );
             // fall through
 
         case ComboKind_Default:
             // fall through
 
         case ComboKind_Default:
@@ -460,7 +456,8 @@ void BitmapComboBoxWidgetsPage::CreateCombo()
         for ( unsigned int n = 0; n < count; n++ )
         {
             items.Add(m_combobox->GetString(n));
         for ( unsigned int n = 0; n < count; n++ )
         {
             items.Add(m_combobox->GetString(n));
-            bitmaps.Add(new wxBitmap(m_combobox->GetItemBitmap(n)));
+            wxBitmap bmp = m_combobox->GetItemBitmap(n);
+            bitmaps.Add(new wxBitmap(bmp));
         }
 
         m_sizerCombo->Detach( m_combobox );
         }
 
         m_sizerCombo->Detach( m_combobox );
@@ -489,7 +486,7 @@ void BitmapComboBoxWidgetsPage::CreateCombo()
     m_sizerCombo->Add(m_combobox, 0, wxGROW | wxALL, 5);
     m_sizerCombo->Layout();
 
     m_sizerCombo->Add(m_combobox, 0, wxGROW | wxALL, 5);
     m_sizerCombo->Layout();
 
-    // Allow changing height inorder to demonstrate flexible
+    // Allow changing height in order to demonstrate flexible
     // size of image "thumbnail" painted in the control itself.
     long h = 0;
     m_textChangeHeight->GetValue().ToLong(&h);
     // size of image "thumbnail" painted in the control itself.
     long h = 0;
     m_textChangeHeight->GetValue().ToLong(&h);
@@ -516,7 +513,7 @@ void BitmapComboBoxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
 #ifndef __WXGTK__
         m_combobox->SetString(sel, m_textChange->GetValue());
 #else
 #ifndef __WXGTK__
         m_combobox->SetString(sel, m_textChange->GetValue());
 #else
-        wxLogMessage(_T("Not implemented in wxGTK"));
+        wxLogMessage(wxT("Not implemented in wxGTK"));
 #endif
     }
 }
 #endif
     }
 }
@@ -555,7 +552,7 @@ void BitmapComboBoxWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
     if ( !m_textInsert->IsModified() )
     {
         // update the default string
     if ( !m_textInsert->IsModified() )
     {
         // update the default string
-        m_textInsert->SetValue(wxString::Format(_T("test item %u"), ++s_item));
+        m_textInsert->SetValue(wxString::Format(wxT("test item %u"), ++s_item));
     }
 
     int sel = m_combobox->GetSelection();
     }
 
     int sel = m_combobox->GetSelection();
@@ -599,15 +596,15 @@ void BitmapComboBoxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
     // "many" means 1000 here
     for ( unsigned int n = 0; n < 1000; n++ )
     {
     // "many" means 1000 here
     for ( unsigned int n = 0; n < 1000; n++ )
     {
-        m_combobox->Append(wxString::Format(_T("item #%u"), n));
+        m_combobox->Append(wxString::Format(wxT("item #%u"), n));
     }
 }
 
 void BitmapComboBoxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
 {
     }
 }
 
 void BitmapComboBoxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
 {
-    m_combobox->Append(_T("First"));
-    m_combobox->Append(_T("another one"));
-    m_combobox->Append(_T("and the last (very very very very very very very very very very long) one"));
+    m_combobox->Append(wxT("First"));
+    m_combobox->Append(wxT("another one"));
+    m_combobox->Append(wxT("and the last (very very very very very very very very very very long) one"));
 }
 
 void BitmapComboBoxWidgetsPage::OnButtonAddSeveralWithImages(wxCommandEvent& WXUNUSED(event))
 }
 
 void BitmapComboBoxWidgetsPage::OnButtonAddSeveralWithImages(wxCommandEvent& WXUNUSED(event))
@@ -715,10 +712,10 @@ void BitmapComboBoxWidgetsPage::LoadWidgetImages( wxArrayString* strings, wxImag
 #if wxUSE_IMAGE
             wxASSERT(fn.FileExists());
             wxImage image(fn.GetFullPath());
 #if wxUSE_IMAGE
             wxASSERT(fn.FileExists());
             wxImage image(fn.GetFullPath());
-            wxASSERT(image.Ok());
+            wxASSERT(image.IsOk());
             RescaleImage(image, foundSize.x, foundSize.y);
             wxBitmap bmp(image);
             RescaleImage(image, foundSize.x, foundSize.y);
             wxBitmap bmp(image);
-            wxASSERT( bmp.Ok() );
+            wxASSERT( bmp.IsOk() );
 #else
             wxBitmap bmp(wxNullBitmap);
 #endif
 #else
             wxBitmap bmp(wxNullBitmap);
 #endif
@@ -796,18 +793,6 @@ void BitmapComboBoxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
         event.Enable(m_combobox->GetCount() != 0);
 }
 
         event.Enable(m_combobox->GetCount() != 0);
 }
 
-void BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
-{
-    if (m_combobox)
-        event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
-}
-
-void BitmapComboBoxWidgetsPage::OnUpdateUIAddSeveralWithImages(wxUpdateUIEvent& event)
-{
-    if (m_combobox)
-        event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
-}
-
 void BitmapComboBoxWidgetsPage::OnComboText(wxCommandEvent& event)
 {
     if (!m_combobox)
 void BitmapComboBoxWidgetsPage::OnComboText(wxCommandEvent& event)
 {
     if (!m_combobox)
@@ -816,22 +801,26 @@ void BitmapComboBoxWidgetsPage::OnComboText(wxCommandEvent& event)
     wxString s = event.GetString();
 
     wxASSERT_MSG( s == m_combobox->GetValue(),
     wxString s = event.GetString();
 
     wxASSERT_MSG( s == m_combobox->GetValue(),
-                  _T("event and combobox values should be the same") );
+                  wxT("event and combobox values should be the same") );
 
 
-    if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
-        wxLogMessage(_T("BitmapCombobox enter pressed (now '%s')"), s.c_str());
+    if (event.GetEventType() == wxEVT_TEXT_ENTER)
+    {
+        wxLogMessage(wxT("BitmapCombobox enter pressed (now '%s')"), s.c_str());
+    }
     else
     else
-        wxLogMessage(_T("BitmapCombobox text changed (now '%s')"), s.c_str());
+    {
+        wxLogMessage(wxT("BitmapCombobox text changed (now '%s')"), s.c_str());
+    }
 }
 
 void BitmapComboBoxWidgetsPage::OnComboBox(wxCommandEvent& event)
 {
     long sel = event.GetInt();
 }
 
 void BitmapComboBoxWidgetsPage::OnComboBox(wxCommandEvent& event)
 {
     long sel = event.GetInt();
-    m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
+    m_textDelete->SetValue(wxString::Format(wxT("%ld"), sel));
 
 
-    wxLogMessage(_T("BitmapCombobox item %ld selected"), sel);
+    wxLogMessage(wxT("BitmapCombobox item %ld selected"), sel);
 
 
-    wxLogMessage(_T("BitmapCombobox GetValue(): %s"), m_combobox->GetValue().c_str() );
+    wxLogMessage(wxT("BitmapCombobox GetValue(): %s"), m_combobox->GetValue().c_str() );
 }
 
 void BitmapComboBoxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
 }
 
 void BitmapComboBoxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
@@ -853,7 +842,7 @@ wxBitmap BitmapComboBoxWidgetsPage::LoadBitmap(const wxString& filepath)
     }
 
     wxImage image(filepath);
     }
 
     wxImage image(filepath);
-    if ( image.Ok() )
+    if ( image.IsOk() )
     {
         // Rescale very large images
         int ow = image.GetWidth();
     {
         // Rescale very large images
         int ow = image.GetWidth();
@@ -895,7 +884,7 @@ wxBitmap BitmapComboBoxWidgetsPage::QueryBitmap(wxString* pStr)
 
     ::wxSetCursor( *wxHOURGLASS_CURSOR );
 
 
     ::wxSetCursor( *wxHOURGLASS_CURSOR );
 
-    if ( filepath.length() )
+    if ( !filepath.empty() )
     {
         if ( pStr )
         {
     {
         if ( pStr )
         {
@@ -906,7 +895,9 @@ wxBitmap BitmapComboBoxWidgetsPage::QueryBitmap(wxString* pStr)
     }
 
     if (bitmap.IsOk())
     }
 
     if (bitmap.IsOk())
+    {
         wxLogDebug(wxT("%i, %i"),bitmap.GetWidth(), bitmap.GetHeight());
         wxLogDebug(wxT("%i, %i"),bitmap.GetWidth(), bitmap.GetHeight());
+    }
 
     ::wxSetCursor( *wxSTANDARD_CURSOR );
 
 
     ::wxSetCursor( *wxSTANDARD_CURSOR );
 
@@ -942,14 +933,14 @@ wxBitmap BitmapComboBoxWidgetsPage::CreateBitmap(const wxColour& colour)
     return bmp;
 }
 
     return bmp;
 }
 
-void BitmapComboBoxWidgetsPage::OnDropDown(wxCommandEvent& event)
+void BitmapComboBoxWidgetsPage::OnDropDown(wxCommandEvent& WXUNUSED(event))
 {
 {
-    wxLogMessage(_T("Combobox dropped down"));
+    wxLogMessage(wxT("Combobox dropped down"));
 }
 
 }
 
-void BitmapComboBoxWidgetsPage::OnCloseUp(wxCommandEvent& event)
+void BitmapComboBoxWidgetsPage::OnCloseUp(wxCommandEvent& WXUNUSED(event))
 {
 {
-    wxLogMessage(_T("Combobox closed up"));
+    wxLogMessage(wxT("Combobox closed up"));
 }
 
 #endif // wxUSE_BITMAPCOMBOBOX
 }
 
 #endif // wxUSE_BITMAPCOMBOBOX