/src/libreoffice/vcl/source/treelist/SvLBoxButton.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <SvLBoxButton.hxx> |
21 | | |
22 | | #include <vcl/decoview.hxx> |
23 | | #include <vcl/salnativewidgets.hxx> |
24 | | #include <vcl/toolkit/button.hxx> |
25 | | |
26 | | SvLBoxButtonData::SvLBoxButtonData(const Control& rControlForSettings, bool _bRadioBtn) |
27 | 0 | : m_pEntry(nullptr) |
28 | 0 | , m_pBox(nullptr) |
29 | 0 | , m_bShowRadioButton(false) |
30 | 0 | { |
31 | 0 | m_bShowRadioButton = _bRadioBtn; |
32 | |
|
33 | 0 | SetDefaultImages(rControlForSettings); |
34 | 0 | } |
35 | | |
36 | 0 | SvLBoxButtonData::~SvLBoxButtonData() {} |
37 | | |
38 | | void SvLBoxButtonData::CallLink(SvTreeListEntry* pActEntry, SvLBoxButton* pActBox) |
39 | 0 | { |
40 | 0 | m_pEntry = pActEntry; |
41 | 0 | m_pBox = pActBox; |
42 | 0 | m_aLink.Call(this); |
43 | 0 | } |
44 | | |
45 | | SvBmp SvLBoxButtonData::GetIndex(SvItemStateFlags nItemState) |
46 | 0 | { |
47 | 0 | SvBmp nIdx; |
48 | 0 | if (nItemState == SvItemStateFlags::UNCHECKED) |
49 | 0 | nIdx = SvBmp::UNCHECKED; |
50 | 0 | else if (nItemState == SvItemStateFlags::CHECKED) |
51 | 0 | nIdx = SvBmp::CHECKED; |
52 | 0 | else if (nItemState == SvItemStateFlags::TRISTATE) |
53 | 0 | nIdx = SvBmp::TRISTATE; |
54 | 0 | else if (nItemState == (SvItemStateFlags::UNCHECKED | SvItemStateFlags::HIGHLIGHTED)) |
55 | 0 | nIdx = SvBmp::HIUNCHECKED; |
56 | 0 | else if (nItemState == (SvItemStateFlags::CHECKED | SvItemStateFlags::HIGHLIGHTED)) |
57 | 0 | nIdx = SvBmp::HICHECKED; |
58 | 0 | else if (nItemState == (SvItemStateFlags::TRISTATE | SvItemStateFlags::HIGHLIGHTED)) |
59 | 0 | nIdx = SvBmp::HITRISTATE; |
60 | 0 | else |
61 | 0 | nIdx = SvBmp::UNCHECKED; |
62 | 0 | return nIdx; |
63 | 0 | } |
64 | | |
65 | 0 | const Size& SvLBoxButtonData::GetSize() { return m_aSize; } |
66 | | |
67 | | SvButtonState SvLBoxButtonData::ConvertToButtonState(SvItemStateFlags nItemFlags) |
68 | 0 | { |
69 | 0 | nItemFlags |
70 | 0 | &= SvItemStateFlags::UNCHECKED | SvItemStateFlags::CHECKED | SvItemStateFlags::TRISTATE; |
71 | 0 | switch (nItemFlags) |
72 | 0 | { |
73 | 0 | case SvItemStateFlags::UNCHECKED: |
74 | 0 | return SvButtonState::Unchecked; |
75 | 0 | case SvItemStateFlags::CHECKED: |
76 | 0 | return SvButtonState::Checked; |
77 | 0 | case SvItemStateFlags::TRISTATE: |
78 | 0 | return SvButtonState::Tristate; |
79 | 0 | default: |
80 | 0 | return SvButtonState::Unchecked; |
81 | 0 | } |
82 | 0 | } |
83 | | |
84 | 0 | SvTreeListEntry* SvLBoxButtonData::GetActEntry() const { return m_pEntry; } |
85 | | |
86 | 0 | SvLBoxButton* SvLBoxButtonData::GetActBox() const { return m_pBox; } |
87 | | |
88 | | void SvLBoxButtonData::SetDefaultImages(const Control& rCtrl) |
89 | 0 | { |
90 | 0 | const AllSettings& rSettings = rCtrl.GetSettings(); |
91 | |
|
92 | 0 | if (m_bShowRadioButton) |
93 | 0 | { |
94 | 0 | m_aBmps[SvBmp::UNCHECKED] = RadioButton::GetRadioImage(rSettings, DrawButtonFlags::Default); |
95 | 0 | m_aBmps[SvBmp::CHECKED] = RadioButton::GetRadioImage(rSettings, DrawButtonFlags::Checked); |
96 | 0 | m_aBmps[SvBmp::HICHECKED] = RadioButton::GetRadioImage( |
97 | 0 | rSettings, DrawButtonFlags::Checked | DrawButtonFlags::Pressed); |
98 | 0 | m_aBmps[SvBmp::HIUNCHECKED] = RadioButton::GetRadioImage( |
99 | 0 | rSettings, DrawButtonFlags::Default | DrawButtonFlags::Pressed); |
100 | 0 | m_aBmps[SvBmp::TRISTATE] = RadioButton::GetRadioImage(rSettings, DrawButtonFlags::DontKnow); |
101 | 0 | m_aBmps[SvBmp::HITRISTATE] = RadioButton::GetRadioImage( |
102 | 0 | rSettings, DrawButtonFlags::DontKnow | DrawButtonFlags::Pressed); |
103 | 0 | } |
104 | 0 | else |
105 | 0 | { |
106 | 0 | m_aBmps[SvBmp::UNCHECKED] = CheckBox::GetCheckImage(rSettings, DrawButtonFlags::Default); |
107 | 0 | m_aBmps[SvBmp::CHECKED] = CheckBox::GetCheckImage(rSettings, DrawButtonFlags::Checked); |
108 | 0 | m_aBmps[SvBmp::HICHECKED] = CheckBox::GetCheckImage( |
109 | 0 | rSettings, DrawButtonFlags::Checked | DrawButtonFlags::Pressed); |
110 | 0 | m_aBmps[SvBmp::HIUNCHECKED] = CheckBox::GetCheckImage( |
111 | 0 | rSettings, DrawButtonFlags::Default | DrawButtonFlags::Pressed); |
112 | 0 | m_aBmps[SvBmp::TRISTATE] = CheckBox::GetCheckImage(rSettings, DrawButtonFlags::DontKnow); |
113 | 0 | m_aBmps[SvBmp::HITRISTATE] = CheckBox::GetCheckImage( |
114 | 0 | rSettings, DrawButtonFlags::DontKnow | DrawButtonFlags::Pressed); |
115 | 0 | } |
116 | |
|
117 | 0 | m_aSize = m_aBmps.at(SvBmp::UNCHECKED).GetSizePixel(); |
118 | 0 | } |
119 | | |
120 | 0 | bool SvLBoxButtonData::IsRadio() const { return m_bShowRadioButton; } |
121 | | |
122 | | SvLBoxButton::SvLBoxButton(SvLBoxButtonData& rBData, bool bIsVis) |
123 | 0 | : m_bIsVis(bIsVis) |
124 | 0 | , m_rData(rBData) |
125 | 0 | , m_nItemFlags(SvItemStateFlags::NONE) |
126 | 0 | { |
127 | 0 | SetStateUnchecked(); |
128 | 0 | } |
129 | | |
130 | 0 | SvLBoxButton::~SvLBoxButton() {} |
131 | | |
132 | 0 | SvLBoxItemType SvLBoxButton::GetType() const { return SvLBoxItemType::Button; } |
133 | | |
134 | | void SvLBoxButton::ClickHdl(SvTreeListEntry* pEntry) |
135 | 0 | { |
136 | 0 | if (IsStateChecked()) |
137 | 0 | SetStateUnchecked(); |
138 | 0 | else |
139 | 0 | SetStateChecked(); |
140 | |
|
141 | 0 | m_rData.CallLink(pEntry, this); |
142 | 0 | } |
143 | | |
144 | | void SvLBoxButton::Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext, |
145 | | const SvViewDataEntry* /*pView*/, const SvTreeListEntry& /*rEntry*/) |
146 | 0 | { |
147 | 0 | SvBmp nIndex = SvLBoxButtonData::GetIndex(m_nItemFlags); |
148 | 0 | DrawImageFlags nStyle |
149 | 0 | = (rDev.IsEnabled() && !mbDisabled) ? DrawImageFlags::NONE : DrawImageFlags::Disable; |
150 | | |
151 | | //Native drawing |
152 | 0 | bool bNativeOK = false; |
153 | 0 | ControlType eCtrlType = (m_rData.IsRadio()) ? ControlType::Radiobutton : ControlType::Checkbox; |
154 | 0 | if (rRenderContext.IsNativeControlSupported(eCtrlType, ControlPart::Entire)) |
155 | 0 | { |
156 | 0 | Size aSize = m_rData.GetSize(); |
157 | 0 | ImplAdjustBoxSize(aSize, eCtrlType, rRenderContext); |
158 | 0 | ImplControlValue aControlValue; |
159 | 0 | tools::Rectangle aCtrlRegion(rPos, aSize); |
160 | 0 | ControlState nState = ControlState::NONE; |
161 | | |
162 | | //states ControlState::DEFAULT, ControlState::PRESSED and ControlState::ROLLOVER are not implemented |
163 | 0 | if (IsStateHilighted()) |
164 | 0 | nState |= ControlState::FOCUSED; |
165 | 0 | if (nStyle != DrawImageFlags::Disable) |
166 | 0 | nState |= ControlState::ENABLED; |
167 | 0 | if (IsStateChecked()) |
168 | 0 | aControlValue.setTristateVal(ButtonValue::On); |
169 | 0 | else if (IsStateUnchecked()) |
170 | 0 | aControlValue.setTristateVal(ButtonValue::Off); |
171 | 0 | else if (IsStateTristate()) |
172 | 0 | aControlValue.setTristateVal(ButtonValue::Mixed); |
173 | |
|
174 | 0 | if (m_bIsVis) |
175 | 0 | bNativeOK = rRenderContext.DrawNativeControl( |
176 | 0 | eCtrlType, ControlPart::Entire, aCtrlRegion, nState, aControlValue, OUString()); |
177 | 0 | } |
178 | |
|
179 | 0 | if (!bNativeOK && m_bIsVis) |
180 | 0 | rRenderContext.DrawImage(rPos, m_rData.GetImage(nIndex), nStyle); |
181 | 0 | } |
182 | | |
183 | | std::unique_ptr<SvLBoxItem> SvLBoxButton::Clone(SvLBoxItem const* pSource) const |
184 | 0 | { |
185 | 0 | return std::make_unique<SvLBoxButton>(static_cast<SvLBoxButton const*>(pSource)->m_rData, |
186 | 0 | false); |
187 | 0 | } |
188 | | |
189 | | void SvLBoxButton::ImplAdjustBoxSize(Size& io_rSize, ControlType i_eType, |
190 | | vcl::RenderContext const& rRenderContext) |
191 | 0 | { |
192 | 0 | if (!rRenderContext.IsNativeControlSupported(i_eType, ControlPart::Entire)) |
193 | 0 | return; |
194 | | |
195 | 0 | ImplControlValue aControlValue; |
196 | 0 | tools::Rectangle aCtrlRegion(Point(0, 0), io_rSize); |
197 | |
|
198 | 0 | aControlValue.setTristateVal(ButtonValue::On); |
199 | |
|
200 | 0 | tools::Rectangle aNativeBounds, aNativeContent; |
201 | 0 | bool bNativeOK = rRenderContext.GetNativeControlRegion( |
202 | 0 | i_eType, ControlPart::Entire, aCtrlRegion, ControlState::ENABLED, aControlValue, |
203 | 0 | aNativeBounds, aNativeContent); |
204 | 0 | if (bNativeOK) |
205 | 0 | { |
206 | 0 | Size aContentSize(aNativeContent.GetSize()); |
207 | | // leave a little space around the box image (looks better) |
208 | 0 | if (aContentSize.Height() + 2 > io_rSize.Height()) |
209 | 0 | io_rSize.setHeight(aContentSize.Height() + 2); |
210 | 0 | if (aContentSize.Width() + 2 > io_rSize.Width()) |
211 | 0 | io_rSize.setWidth(aContentSize.Width() + 2); |
212 | 0 | } |
213 | 0 | } |
214 | | |
215 | | void SvLBoxButton::InitViewData(SvTreeListBox& rView, SvTreeListEntry& rEntry, |
216 | | SvViewDataItem* pViewData) |
217 | 0 | { |
218 | 0 | if (!pViewData) |
219 | 0 | pViewData = &rView.GetViewDataItem(rEntry, *this); |
220 | 0 | Size aSize = m_rData.GetSize(); |
221 | |
|
222 | 0 | ControlType eCtrlType = (m_rData.IsRadio()) ? ControlType::Radiobutton : ControlType::Checkbox; |
223 | 0 | ImplAdjustBoxSize(aSize, eCtrlType, *rView.GetOutDev()); |
224 | 0 | pViewData->mnWidth = aSize.Width(); |
225 | 0 | pViewData->mnHeight = aSize.Height(); |
226 | 0 | } |
227 | | |
228 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |