1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "ImageListBox.h" 21 22 #include "View/ViewConstants.h" 23 24 #include <wx/control.h> 25 #include <wx/dc.h> 26 #include <wx/dcmemory.h> 27 #include <wx/settings.h> 28 29 #include <cassert> 30 31 namespace TrenchBroom { 32 namespace View { ImageListBox(wxWindow * parent,const wxSize & imageSize,const wxString & emptyText,const long style)33 ImageListBox::ImageListBox(wxWindow* parent, const wxSize& imageSize, const wxString& emptyText, const long style) : 34 wxVListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLB_SINGLE | style), 35 m_imageSize(imageSize), 36 m_empty(true), 37 m_emptyText(emptyText), 38 m_border(2, 4) {} 39 itemWidth(const wxString & subtitle) const40 wxCoord ImageListBox::itemWidth(const wxString& subtitle) const { 41 wxMemoryDC dc; 42 dc.SetFont(*wxNORMAL_FONT); 43 return dc.GetTextExtent(subtitle).x + 2 * m_border.x + m_imageSize.x + 8; 44 } 45 itemHeight() const46 wxCoord ImageListBox::itemHeight() const { 47 const int imageHeight = m_imageSize.y + 2 * m_border.y; 48 int textHeight = 2 * m_border.y + 4; 49 50 wxMemoryDC dc; 51 dc.SetFont(wxNORMAL_FONT->Bold()); 52 textHeight += dc.GetTextExtent("Wgy").y; 53 54 dc.SetFont(*wxNORMAL_FONT); 55 textHeight += dc.GetTextExtent("Wgy").y; 56 57 return std::max(imageHeight, textHeight); 58 } 59 SetItemCount(size_t itemCount)60 void ImageListBox::SetItemCount(size_t itemCount) { 61 if (itemCount == 0) { 62 m_empty = true; 63 wxVListBox::SetItemCount(1); 64 } else { 65 m_empty = false; 66 wxVListBox::SetItemCount(itemCount); 67 } 68 } 69 OnDrawItem(wxDC & dc,const wxRect & rect,size_t n) const70 void ImageListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const { 71 if (m_empty) 72 drawEmptyItem(dc, rect); 73 else 74 drawItem(dc, rect, n); 75 } 76 drawItem(wxDC & dc,const wxRect & rect,size_t n) const77 void ImageListBox::drawItem(wxDC& dc, const wxRect& rect, size_t n) const { 78 const wxBitmap& img = image(n); 79 const wxString ttl = title(n); 80 const wxString sub = subtitle(n); 81 82 dc.DrawBitmap(img, rect.GetLeft() + m_border.x, rect.GetTop() + m_border.y, true); 83 84 int yOff = rect.GetTop() + m_border.y; 85 86 if (IsSelected(n)) 87 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT)); 88 else 89 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT)); 90 91 dc.SetFont(wxNORMAL_FONT->Bold()); 92 const wxString shortTtl = wxControl::Ellipsize(ttl, dc, wxELLIPSIZE_MIDDLE, rect.GetWidth() - (rect.GetLeft() + m_imageSize.x + 8 + 6)); 93 dc.DrawText(shortTtl, rect.GetLeft() + m_imageSize.x + 8, yOff); 94 95 yOff += dc.GetTextExtent("Wgy").y + 4; 96 97 dc.SetFont(*wxSMALL_FONT); 98 const wxString shortSub = wxControl::Ellipsize(sub, dc, wxELLIPSIZE_MIDDLE, rect.GetWidth() - (rect.GetLeft() + m_imageSize.x + 8 + 6)); 99 dc.DrawText(shortSub, rect.GetLeft() + m_imageSize.x + 8, yOff); 100 } 101 drawEmptyItem(wxDC & dc,const wxRect & rect) const102 void ImageListBox::drawEmptyItem(wxDC& dc, const wxRect& rect) const { 103 dc.SetFont(wxNORMAL_FONT->Larger().Larger().Bold()); 104 const wxSize textSize = dc.GetTextExtent(m_emptyText); 105 106 const int x = (rect.GetWidth() - textSize.x) / 2; 107 const int y = (rect.GetHeight() - textSize.y) / 2; 108 dc.SetTextForeground(*wxLIGHT_GREY); 109 dc.DrawText(m_emptyText, x, y); 110 } 111 OnDrawBackground(wxDC & dc,const wxRect & rect,size_t n) const112 void ImageListBox::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const { 113 assert(n < GetItemCount()); 114 dc.SetPen(*wxTRANSPARENT_PEN); 115 if (IsSelected(n)) 116 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))); 117 else 118 dc.SetBrush(*wxWHITE_BRUSH); 119 dc.DrawRectangle(rect); 120 } 121 OnDrawSeparator(wxDC & dc,wxRect & rect,size_t n) const122 void ImageListBox::OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const { 123 if (m_empty) 124 return; 125 126 assert(n < GetItemCount()); 127 dc.SetPen(Colors::borderColor()); 128 dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight(), rect.GetBottom()); 129 rect.Deflate(0, 1); 130 } 131 OnMeasureItem(size_t n) const132 wxCoord ImageListBox::OnMeasureItem(size_t n) const { 133 return itemHeight(); 134 } 135 } 136 } 137