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