7#include "xfa/fwl/cfwl_scrollbar.h"
13#include "xfa/fwl/cfwl_app.h"
14#include "xfa/fwl/cfwl_messagemouse.h"
15#include "xfa/fwl/cfwl_messagemousewheel.h"
16#include "xfa/fwl/cfwl_notedriver.h"
17#include "xfa/fwl/cfwl_themebackground.h"
18#include "xfa/fwl/cfwl_themepart.h"
19#include "xfa/fwl/ifwl_themeprovider.h"
23constexpr int kScrollbarElapsedMsecs = 500;
24constexpr float kMinThumbSize = 5.0f;
28CFWL_ScrollBar::CFWL_ScrollBar(CFWL_App* app,
54 DrawLowerTrack(pGraphics, matrix);
55 DrawUpperTrack(pGraphics, matrix);
56 DrawMinArrowBtn(pGraphics, matrix);
57 DrawMaxArrowBtn(pGraphics, matrix);
58 DrawThumb(pGraphics, matrix);
62 m_fTrackPos = fTrackPos;
63 m_ThumbRect
= CalcThumbButtonRect(m_ThumbRect);
64 m_MinTrackRect
= CalcMinTrackRect(m_MinTrackRect);
65 m_MaxTrackRect
= CalcMaxTrackRect(m_MaxTrackRect);
68bool CFWL_ScrollBar::DoScroll(CFWL_EventScroll::
Code dwCode,
float fPos) {
71 return OnScroll(dwCode, fPos);
127 : m_iThumbButtonState;
133void CFWL_ScrollBar::Layout() {
137 m_MinBtnRect
= CalcMinButtonRect();
138 m_MaxBtnRect
= CalcMaxButtonRect();
139 m_ThumbRect
= CalcThumbButtonRect(m_ThumbRect);
140 m_MinTrackRect
= CalcMinTrackRect(m_MinTrackRect);
141 m_MaxTrackRect
= CalcMaxTrackRect(m_MaxTrackRect);
144void CFWL_ScrollBar::CalcButtonLen() {
145 m_fButtonLen = IsVertical() ? m_ClientRect
.width : m_ClientRect
.height;
146 float fLength = IsVertical() ? m_ClientRect
.height : m_ClientRect
.width;
147 if (fLength < m_fButtonLen * 2) {
148 m_fButtonLen = fLength / 2;
155CFX_RectF CFWL_ScrollBar::CalcMinButtonRect() {
157 return CFX_RectF(m_ClientRect.TopLeft(), m_ClientRect
.width, m_fButtonLen);
158 return CFX_RectF(m_ClientRect.TopLeft(), m_fButtonLen, m_ClientRect
.height);
161CFX_RectF CFWL_ScrollBar::CalcMaxButtonRect() {
181 float fRange = m_fRangeMax - m_fRangeMin;
192 float fLength = IsVertical() ? rtClient
.height : rtClient
.width;
193 float fSize = m_fButtonLen;
194 fLength -= fSize * 2.0f;
198 float fThumbSize = fLength * fLength / (fRange + fLength);
199 fThumbSize =
std::max(fThumbSize, kMinThumbSize);
201 float fDiff =
std::max(fLength - fThumbSize, 0.0f);
202 float fTrackPos =
std::clamp(m_fTrackPos, m_fRangeMin, m_fRangeMax);
206 float iPos = fSize + fDiff * (fTrackPos - m_fRangeMin) / fRange;
243 return CFX_RectF(rtMaxRect.TopLeft(), 0, 0);
256float CFWL_ScrollBar::GetTrackPointPos(
const CFX_PointF& point) {
257 CFX_PointF diff = point - m_cpTrackPoint;
258 float fRange = m_fRangeMax - m_fRangeMin;
262 fPos = fRange * diff.y /
265 fPos = fRange * diff.x /
269 fPos += m_fLastTrackPos;
270 return std::clamp(fPos, m_fRangeMin, m_fRangeMax);
273bool CFWL_ScrollBar::SendEvent() {
284 return m_ThumbRect.Contains(m_cpTrackPoint);
288 return m_ThumbRect.Contains(m_cpTrackPoint);
291 CFWL_EventScroll::
Code dwCode = m_iMouseWheel < 0
294 DoScroll(dwCode, m_fTrackPos);
299bool CFWL_ScrollBar::OnScroll(CFWL_EventScroll::
Code dwCode,
float fPos) {
300 CFWL_EventScroll ev(
this, dwCode, fPos);
308 CFWL_MessageMouse* pMsg =
static_cast<CFWL_MessageMouse*>(pMessage);
311 OnLButtonDown(pMsg->m_pos);
314 OnLButtonUp(pMsg->m_pos);
317 OnMouseMove(pMsg->m_pos);
326 auto* pMsg =
static_cast<CFWL_MessageMouseWheel*>(pMessage);
336void CFWL_ScrollBar::OnLButtonDown(
const CFX_PointF& point) {
343 m_cpTrackPoint = point;
344 m_fLastTrackPos = m_fTrackPos;
346 DoMouseDown(0, m_MinBtnRect, &m_iMinButtonState, point);
348 DoMouseDown(1, m_ThumbRect, &m_iThumbButtonState, point);
350 DoMouseDown(2, m_MaxBtnRect, &m_iMaxButtonState, point);
352 DoMouseDown(3, m_MinTrackRect, &m_iMinTrackState, point);
354 DoMouseDown(4, m_MaxTrackRect, &m_iMaxTrackState, point);
357 m_pTimer = std::make_unique<CFX_Timer>(GetFWLApp()->GetTimerHandler(),
this,
358 kScrollbarElapsedMsecs);
362void CFWL_ScrollBar::OnLButtonUp(
const CFX_PointF& point) {
364 m_bMouseDown =
false;
365 DoMouseUp(0, m_MinBtnRect, &m_iMinButtonState, point);
366 DoMouseUp(1, m_ThumbRect, &m_iThumbButtonState, point);
367 DoMouseUp(2, m_MaxBtnRect, &m_iMaxButtonState, point);
368 DoMouseUp(3, m_MinTrackRect, &m_iMinTrackState, point);
369 DoMouseUp(4, m_MaxTrackRect, &m_iMaxTrackState, point);
373void CFWL_ScrollBar::OnMouseMove(
const CFX_PointF& point) {
374 DoMouseMove(0, m_MinBtnRect, &m_iMinButtonState, point);
375 DoMouseMove(1, m_ThumbRect, &m_iThumbButtonState, point);
376 DoMouseMove(2, m_MaxBtnRect, &m_iMaxButtonState, point);
377 DoMouseMove(3, m_MinTrackRect, &m_iMinTrackState, point);
378 DoMouseMove(4, m_MaxTrackRect, &m_iMaxTrackState, point);
381void CFWL_ScrollBar::OnMouseLeave() {
382 DoMouseLeave(0, m_MinBtnRect, &m_iMinButtonState);
383 DoMouseLeave(1, m_ThumbRect, &m_iThumbButtonState);
384 DoMouseLeave(2, m_MaxBtnRect, &m_iMaxButtonState);
385 DoMouseLeave(3, m_MinTrackRect, &m_iMinTrackState);
386 DoMouseLeave(4, m_MaxTrackRect, &m_iMaxTrackState);
389void CFWL_ScrollBar::OnMouseWheel(
const CFX_Vector& delta) {
390 m_iMouseWheel = delta.y;
395void CFWL_ScrollBar::DoMouseDown(int32_t iItem,
398 const CFX_PointF& point) {
408void CFWL_ScrollBar::DoMouseUp(int32_t iItem,
411 const CFX_PointF& point) {
414 if (*pState == iNewState)
422void CFWL_ScrollBar::DoMouseMove(int32_t iItem,
425 const CFX_PointF& point) {
429 if (*pState == iNewState)
434 }
else if ((2 == iItem) &&
436 m_fTrackPos = GetTrackPointPos(point);
441void CFWL_ScrollBar::DoMouseLeave(int32_t iItem,
451void CFWL_ScrollBar::DoMouseHover(int32_t iItem,
465 std::make_unique<CFX_Timer>(GetFWLApp()->GetTimerHandler(),
this, 0);
const CFX_Vector & delta() const
const MouseCommand m_dwCmd
CFX_Matrix & operator=(const CFX_Matrix &other)=default
CFX_RectF & operator=(const CFX_RectF &other)=default
bool Contains(const PointType &p) const
constexpr CFX_RectF(float dst_left, float dst_top, float dst_width, float dst_height)