mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 06:53:43 +00:00
Finish scroll bars
This commit is contained in:
@@ -248,6 +248,9 @@ void RedrawMapContents (void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
surface->SetForeColor(StdColors::White());
|
||||||
|
surface->FillRect(aRoom);
|
||||||
|
|
||||||
if (i >= groundLevel)
|
if (i >= groundLevel)
|
||||||
surface->SetForeColor(StdColors::Green());
|
surface->SetForeColor(StdColors::Green());
|
||||||
else
|
else
|
||||||
@@ -464,50 +467,50 @@ void ToggleMapWindow (void)
|
|||||||
//-------------------------------------------------------------- LiveHScrollAction
|
//-------------------------------------------------------------- LiveHScrollAction
|
||||||
#ifndef COMPILEDEMO
|
#ifndef COMPILEDEMO
|
||||||
|
|
||||||
void LiveHScrollAction (ControlHandle theControl, short thePart)
|
void LiveHScrollAction (PortabilityLayer::Widget *theControl, int thePart)
|
||||||
{
|
{
|
||||||
short wasValue, newValue;
|
short wasValue, newValue;
|
||||||
|
|
||||||
switch (thePart)
|
switch (thePart)
|
||||||
{
|
{
|
||||||
case kControlUpButtonPart:
|
case kControlUpButtonPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
SetControlValue(theControl, wasValue - 1);
|
theControl->SetState(wasValue - 1);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapLeftRoom = GetControlValue(theControl);
|
mapLeftRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlDownButtonPart:
|
case kControlDownButtonPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
SetControlValue(theControl, wasValue + 1);
|
theControl->SetState(wasValue + 1);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapLeftRoom = GetControlValue(theControl);
|
mapLeftRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlPageUpPart:
|
case kControlPageUpPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
newValue = wasValue - (mapRoomsWide / 2);
|
newValue = wasValue - (mapRoomsWide / 2);
|
||||||
SetControlValue(theControl, newValue);
|
theControl->SetState(newValue);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapLeftRoom = GetControlValue(theControl);
|
mapLeftRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlPageDownPart:
|
case kControlPageDownPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
newValue = wasValue + (mapRoomsWide / 2);
|
newValue = wasValue + (mapRoomsWide / 2);
|
||||||
SetControlValue(theControl, newValue);
|
theControl->SetState(newValue);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapLeftRoom = GetControlValue(theControl);
|
mapLeftRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -521,50 +524,50 @@ void LiveHScrollAction (ControlHandle theControl, short thePart)
|
|||||||
//-------------------------------------------------------------- LiveVScrollAction
|
//-------------------------------------------------------------- LiveVScrollAction
|
||||||
#ifndef COMPILEDEMO
|
#ifndef COMPILEDEMO
|
||||||
|
|
||||||
void LiveVScrollAction (ControlHandle theControl, short thePart)
|
void LiveVScrollAction (PortabilityLayer::Widget *theControl, int thePart)
|
||||||
{
|
{
|
||||||
short wasValue, newValue;
|
short wasValue, newValue;
|
||||||
|
|
||||||
switch (thePart)
|
switch (thePart)
|
||||||
{
|
{
|
||||||
case kControlUpButtonPart:
|
case kControlUpButtonPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
SetControlValue(theControl, wasValue - 1);
|
theControl->SetState(wasValue - 1);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapTopRoom = GetControlValue(theControl);
|
mapTopRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlDownButtonPart:
|
case kControlDownButtonPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
SetControlValue(theControl, wasValue + 1);
|
theControl->SetState(wasValue + 1);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapTopRoom = GetControlValue(theControl);
|
mapTopRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlPageUpPart:
|
case kControlPageUpPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
newValue = wasValue - (mapRoomsHigh / 2);
|
newValue = wasValue - (mapRoomsHigh / 2);
|
||||||
SetControlValue(theControl, newValue);
|
theControl->SetState(newValue);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapTopRoom = GetControlValue(theControl);
|
mapTopRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlPageDownPart:
|
case kControlPageDownPart:
|
||||||
wasValue = GetControlValue(theControl);
|
wasValue = theControl->GetState();
|
||||||
newValue = wasValue + (mapRoomsHigh / 2);
|
newValue = wasValue + (mapRoomsHigh / 2);
|
||||||
SetControlValue(theControl, newValue);
|
theControl->SetState(newValue);
|
||||||
if (GetControlValue(theControl) != wasValue)
|
if (theControl->GetState() != wasValue)
|
||||||
{
|
{
|
||||||
mapTopRoom = GetControlValue(theControl);
|
mapTopRoom = theControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -586,13 +589,9 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
|
|||||||
long controlRef;
|
long controlRef;
|
||||||
short whichPart, localH, localV;
|
short whichPart, localH, localV;
|
||||||
short roomH, roomV, itsNumber;
|
short roomH, roomV, itsNumber;
|
||||||
ControlActionUPP scrollHActionUPP, scrollVActionUPP;
|
|
||||||
|
|
||||||
wherePt = Point::Create(theEvent.m_x, theEvent.m_y);
|
wherePt = Point::Create(theEvent.m_x, theEvent.m_y);
|
||||||
|
|
||||||
scrollHActionUPP = NewControlActionUPP(LiveHScrollAction);
|
|
||||||
scrollVActionUPP = NewControlActionUPP(LiveVScrollAction);
|
|
||||||
|
|
||||||
if (mapWindow == nil)
|
if (mapWindow == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -676,14 +675,11 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
|
|||||||
case kControlDownButtonPart:
|
case kControlDownButtonPart:
|
||||||
case kControlPageUpPart:
|
case kControlPageUpPart:
|
||||||
case kControlPageDownPart:
|
case kControlPageDownPart:
|
||||||
if (TrackControl(whichControl, wherePt, scrollHActionUPP))
|
whichControl->Capture(wherePt, LiveHScrollAction);
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlIndicatorPart:
|
case kControlIndicatorPart:
|
||||||
if (TrackControl(whichControl, wherePt, nil))
|
if (whichControl->Capture(wherePt, nil))
|
||||||
{
|
{
|
||||||
mapLeftRoom = whichControl->GetState();
|
mapLeftRoom = whichControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
@@ -699,14 +695,11 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
|
|||||||
case kControlDownButtonPart:
|
case kControlDownButtonPart:
|
||||||
case kControlPageUpPart:
|
case kControlPageUpPart:
|
||||||
case kControlPageDownPart:
|
case kControlPageDownPart:
|
||||||
if (TrackControl(whichControl, wherePt, scrollVActionUPP))
|
whichControl->Capture(wherePt, LiveVScrollAction);
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kControlIndicatorPart:
|
case kControlIndicatorPart:
|
||||||
if (TrackControl(whichControl, wherePt, nil))
|
if (whichControl->Capture(wherePt, nil))
|
||||||
{
|
{
|
||||||
mapTopRoom = whichControl->GetState();
|
mapTopRoom = whichControl->GetState();
|
||||||
RedrawMapContents();
|
RedrawMapContents();
|
||||||
@@ -715,9 +708,6 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisposeControlActionUPP(scrollHActionUPP);
|
|
||||||
DisposeControlActionUPP(scrollVActionUPP);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#include "PLScrollBarWidget.h"
|
#include "PLScrollBarWidget.h"
|
||||||
#include "PLControlDefinitions.h"
|
#include "PLControlDefinitions.h"
|
||||||
#include "PLStandardColors.h"
|
#include "PLStandardColors.h"
|
||||||
|
#include "PLTimeTaggedVOSEvent.h"
|
||||||
|
|
||||||
namespace PortabilityLayer
|
namespace PortabilityLayer
|
||||||
{
|
{
|
||||||
@@ -196,12 +197,161 @@ namespace PortabilityLayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScrollBarWidget::SetState(int16_t state)
|
||||||
|
{
|
||||||
|
if (state < m_min)
|
||||||
|
WidgetSpec<ScrollBarWidget>::SetState(m_min);
|
||||||
|
else if (state > m_max)
|
||||||
|
WidgetSpec<ScrollBarWidget>::SetState(m_max);
|
||||||
|
else
|
||||||
|
WidgetSpec<ScrollBarWidget>::SetState(state);
|
||||||
|
}
|
||||||
|
|
||||||
void ScrollBarWidget::OnStateChanged()
|
void ScrollBarWidget::OnStateChanged()
|
||||||
{
|
{
|
||||||
RefreshGrip();
|
RefreshGrip();
|
||||||
DrawControl(m_window->GetDrawSurface());
|
DrawControl(m_window->GetDrawSurface());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t ScrollBarWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
|
||||||
|
{
|
||||||
|
int part = ResolvePart(pos);
|
||||||
|
if (!part)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (part == kControlIndicatorPart)
|
||||||
|
return CaptureIndicator(pos, callback);
|
||||||
|
else
|
||||||
|
return CaptureScrollSegment(pos, part, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t ScrollBarWidget::CaptureScrollSegment(const Point &pos, int part, WidgetUpdateCallback_t callback)
|
||||||
|
{
|
||||||
|
int tickDelay = 15;
|
||||||
|
|
||||||
|
Point currentPos = pos;
|
||||||
|
bool wasInBounds = false;
|
||||||
|
bool isInBounds = (ResolvePart(pos) == part);
|
||||||
|
|
||||||
|
int ticksUntilIterate = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (ticksUntilIterate == 0)
|
||||||
|
{
|
||||||
|
if (isInBounds)
|
||||||
|
{
|
||||||
|
IterateScrollSegment(part, callback);
|
||||||
|
isInBounds = (ResolvePart(currentPos) == part); // Update in-bounds since the scroll may invalidate it
|
||||||
|
}
|
||||||
|
|
||||||
|
ticksUntilIterate = tickDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeTaggedVOSEvent evt;
|
||||||
|
if (WaitForEvent(&evt, 1))
|
||||||
|
{
|
||||||
|
if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
|
||||||
|
{
|
||||||
|
const GpMouseInputEvent &mouseEvt = evt.m_vosEvent.m_event.m_mouseInputEvent;
|
||||||
|
if (mouseEvt.m_button == GpMouseButtons::kLeft && mouseEvt.m_eventType == GpMouseEventTypes::kUp)
|
||||||
|
return part;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPos = m_window->MouseToLocal(mouseEvt);
|
||||||
|
isInBounds = (ResolvePart(currentPos) == part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ticksUntilIterate--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t ScrollBarWidget::CaptureIndicator(const Point &pos, WidgetUpdateCallback_t callback)
|
||||||
|
{
|
||||||
|
const bool isHorizontal = IsHorizontal();
|
||||||
|
|
||||||
|
const int32_t startCoordinate = isHorizontal ? pos.h : pos.v;
|
||||||
|
int32_t currentGripPos = m_gripPos;
|
||||||
|
|
||||||
|
Rect currentHandle;
|
||||||
|
if (isHorizontal)
|
||||||
|
currentHandle = Rect::Create(m_rect.top, m_rect.left + 16 + m_gripPos, m_rect.bottom, m_rect.left + 16 + m_gripPos + m_gripSize);
|
||||||
|
else
|
||||||
|
currentHandle = Rect::Create(m_rect.top + 16 + m_gripPos, m_rect.left, m_rect.top + 16 + m_gripPos + m_gripSize, m_rect.right);
|
||||||
|
|
||||||
|
DrawSurface *surface = this->m_window->GetDrawSurface();
|
||||||
|
|
||||||
|
uint8_t solidPattern[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
surface->InvertFillRect(currentHandle, solidPattern);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
TimeTaggedVOSEvent evt;
|
||||||
|
if (WaitForEvent(&evt, 1))
|
||||||
|
{
|
||||||
|
if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
|
||||||
|
{
|
||||||
|
const GpMouseInputEvent &mouseEvt = evt.m_vosEvent.m_event.m_mouseInputEvent;
|
||||||
|
if (mouseEvt.m_eventType == GpMouseEventTypes::kUp || mouseEvt.m_eventType == GpMouseEventTypes::kMove)
|
||||||
|
{
|
||||||
|
const Point localPoint = m_window->MouseToLocal(mouseEvt);
|
||||||
|
int32_t desiredCoordinate = isHorizontal ? localPoint.h : localPoint.v;
|
||||||
|
int32_t desiredGripPos = m_gripPos + (desiredCoordinate - startCoordinate);
|
||||||
|
|
||||||
|
if (desiredGripPos < 0)
|
||||||
|
desiredGripPos = 0;
|
||||||
|
else if (desiredGripPos > m_laneCapacity)
|
||||||
|
desiredGripPos = m_laneCapacity;
|
||||||
|
|
||||||
|
if (desiredGripPos != currentGripPos)
|
||||||
|
{
|
||||||
|
surface->InvertFillRect(currentHandle, solidPattern);
|
||||||
|
|
||||||
|
if (isHorizontal)
|
||||||
|
currentHandle = Rect::Create(m_rect.top, m_rect.left + 16 + desiredGripPos, m_rect.bottom, m_rect.left + 16 + desiredGripPos + m_gripSize);
|
||||||
|
else
|
||||||
|
currentHandle = Rect::Create(m_rect.top + 16 + desiredGripPos, m_rect.left, m_rect.top + 16 + desiredGripPos + m_gripSize, m_rect.right);
|
||||||
|
|
||||||
|
surface->InvertFillRect(currentHandle, solidPattern);
|
||||||
|
|
||||||
|
currentGripPos = desiredGripPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouseEvt.m_eventType == GpMouseEventTypes::kUp && mouseEvt.m_button == GpMouseButtons::kLeft)
|
||||||
|
{
|
||||||
|
surface->InvertFillRect(currentHandle, solidPattern);
|
||||||
|
|
||||||
|
//int32_t desiredState = (currentGripPos / m_laneCapacity) * (m_max - m_min);
|
||||||
|
int32_t desiredState = m_min;
|
||||||
|
|
||||||
|
if (m_laneCapacity > 0)
|
||||||
|
{
|
||||||
|
desiredState = ((currentGripPos * (m_max - m_min)) * 2 + m_laneCapacity) / (m_laneCapacity * 2);
|
||||||
|
|
||||||
|
// This shouldn't happen unless something weird happens like an int overflow
|
||||||
|
if (desiredState < m_min)
|
||||||
|
desiredState = m_min;
|
||||||
|
else if (desiredState > m_max)
|
||||||
|
desiredState = m_max;
|
||||||
|
|
||||||
|
SetState(desiredState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return kControlIndicatorPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollBarWidget::IterateScrollSegment(int part, WidgetUpdateCallback_t callback)
|
||||||
|
{
|
||||||
|
if (callback != nullptr)
|
||||||
|
callback(this, part);
|
||||||
|
}
|
||||||
|
|
||||||
int ScrollBarWidget::ResolvePart(const Point &point) const
|
int ScrollBarWidget::ResolvePart(const Point &point) const
|
||||||
{
|
{
|
||||||
if (!m_rect.Contains(point))
|
if (!m_rect.Contains(point))
|
||||||
@@ -222,17 +372,17 @@ namespace PortabilityLayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (coord < 16)
|
if (coord < 16)
|
||||||
return isHorizontal ? kControlDownButtonPart : kControlUpButtonPart;
|
return kControlUpButtonPart;
|
||||||
|
|
||||||
if (coord < m_gripPos)
|
if (coord - 16 < m_gripPos)
|
||||||
return isHorizontal ? kControlPageDownPart : kControlPageUpPart;
|
return kControlPageUpPart;
|
||||||
|
|
||||||
if (coord - m_gripPos < m_gripSize)
|
if (coord - 16 - m_gripPos < m_gripSize)
|
||||||
return kControlIndicatorPart;
|
return kControlIndicatorPart;
|
||||||
|
|
||||||
if (coord < span - 16)
|
if (coord < span - 16)
|
||||||
return isHorizontal ? kControlPageUpPart : kControlPageDownPart;
|
return kControlPageDownPart;
|
||||||
|
|
||||||
return isHorizontal ? kControlUpButtonPart : kControlDownButtonPart;
|
return kControlDownButtonPart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,8 +18,11 @@ namespace PortabilityLayer
|
|||||||
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
|
WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override;
|
||||||
void DrawControl(DrawSurface *surface) override;
|
void DrawControl(DrawSurface *surface) override;
|
||||||
|
|
||||||
|
void SetState(int16_t state) override;
|
||||||
void OnStateChanged() override;
|
void OnStateChanged() override;
|
||||||
|
|
||||||
|
int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback) override;
|
||||||
|
|
||||||
int ResolvePart(const Point &point) const override;
|
int ResolvePart(const Point &point) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -33,6 +36,10 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
static void DrawBeveledBox(DrawSurface *surface, const Rect &rect);
|
static void DrawBeveledBox(DrawSurface *surface, const Rect &rect);
|
||||||
|
|
||||||
|
int16_t CaptureScrollSegment(const Point &pos, int part, WidgetUpdateCallback_t callback);
|
||||||
|
int16_t CaptureIndicator(const Point &pos, WidgetUpdateCallback_t callback);
|
||||||
|
void IterateScrollSegment(int part, WidgetUpdateCallback_t callback);
|
||||||
|
|
||||||
int32_t m_min;
|
int32_t m_min;
|
||||||
int32_t m_max;
|
int32_t m_max;
|
||||||
int32_t m_gripSize;
|
int32_t m_gripSize;
|
||||||
|
@@ -58,7 +58,7 @@ namespace PortabilityLayer
|
|||||||
void Resize(uint16_t width, uint16_t height);
|
void Resize(uint16_t width, uint16_t height);
|
||||||
|
|
||||||
void SetEnabled(bool enabled);
|
void SetEnabled(bool enabled);
|
||||||
void SetState(int16_t state);
|
virtual void SetState(int16_t state);
|
||||||
int16_t GetState() const;
|
int16_t GetState() const;
|
||||||
|
|
||||||
void SetVisible(bool visible);
|
void SetVisible(bool visible);
|
||||||
|
Reference in New Issue
Block a user