Skip to content

Commit

Permalink
Send button/key release on mask change and stop sending held messages…
Browse files Browse the repository at this point in the history
… if softkeymask changed
  • Loading branch information
martonmiklos committed Jan 11, 2025
1 parent 41a2e7f commit 328a4ca
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 31 deletions.
5 changes: 5 additions & 0 deletions include/KeyComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ class KeyComponent : public isobus::Key
KeyComponent(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, isobus::Key sourceObject, int keyWidth, int keyHeight);

void paint(Graphics &g) override;
void setKeyPosition(uint8_t pos);
std::uint8_t getKeyPosition() const;

static const std::uint8_t InvalidSoftKeyPos = 255;

private:
std::uint8_t keyPosition = InvalidSoftKeyPos;
std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> parentWorkingSet;
std::vector<std::shared_ptr<Component>> childComponents;

Expand Down
2 changes: 2 additions & 0 deletions include/ObjectPointerComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class ObjectPointerComponent : public isobus::ObjectPointer

void paint(Graphics &g) override;

std::shared_ptr<Component> getChildComponent() const;

private:
std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> parentWorkingSet;
std::shared_ptr<Component> childComponent;
Expand Down
13 changes: 9 additions & 4 deletions include/ServerMainComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ class ServerMainComponent : public juce::Component

void change_selected_working_set(std::uint8_t index);

void set_button_held(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey);
void set_button_released(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey);
void set_button_held(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey, std::uint8_t pos);
void set_button_released(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey, std::uint8_t pos);

bool is_key_position_released_by_mask_change(std::uint8_t pos) const;

void repaint_on_next_update();

Expand Down Expand Up @@ -144,13 +146,14 @@ class ServerMainComponent : public juce::Component

struct HeldButtonData
{
HeldButtonData(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey);
HeldButtonData(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey, std::uint8_t position);
bool operator==(const HeldButtonData &other);
std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> associatedWorkingSet;
std::uint32_t timestamp_ms;
std::uint16_t buttonObjectID;
std::uint16_t activeMaskObjectID;
std::uint16_t softKeyMaskObjectID;
std::uint8_t buttonKeyCode;
std::uint8_t keyPosition; // applicable only for softkeys
bool isSoftKey;
};

Expand All @@ -159,6 +162,7 @@ class ServerMainComponent : public juce::Component
std::size_t number_of_iop_files_in_directory(std::filesystem::path path);

void on_change_active_mask_callback(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> affectedWorkingSet, std::uint16_t workingSet, std::uint16_t newMask);
void handle_softkey_release_if_mask_changed();
void repaint_data_and_soft_key_mask();
void check_load_settings();
void remove_working_set(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSetToRemove);
Expand All @@ -182,6 +186,7 @@ class ServerMainComponent : public juce::Component
std::vector<HeldButtonData> heldButtons;
std::uint32_t alarmAckKeyMaskId = isobus::NULL_OBJECT_ID;
int alarmAckKeyCode = juce::KeyPress::escapeKey;
std::uint8_t softKeyPositionReleasedByMaskChange;
std::uint8_t numberOfPoolsToRender = 0;
VTVersion versionToReport = VTVersion::Version5;
bool needToRepaint = false;
Expand Down
17 changes: 12 additions & 5 deletions src/DataMaskRenderAreaComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "DataMaskRenderAreaComponent.hpp"
#include "AppImages.h"
#include "JuceManagedWorkingSetCache.hpp"
#include "KeyComponent.hpp"
#include "ServerMainComponent.hpp"

DataMaskRenderAreaComponent::DataMaskRenderAreaComponent(ServerMainComponent &parentServer) :
Expand Down Expand Up @@ -79,10 +80,11 @@ void DataMaskRenderAreaComponent::mouseDown(const MouseEvent &event)
auto relativeEvent = event.getEventRelativeTo(this);
auto clickedObject = getClickedChildRecursive(activeMask, relativeEvent.getMouseDownX(), relativeEvent.getMouseDownY());

std::uint8_t keyCode = 1;

if (nullptr != clickedObject)
{
std::uint8_t keyCode = 1;
std::uint8_t keyPos = KeyComponent::InvalidSoftKeyPos;

if (isobus::VirtualTerminalObjectType::Button == clickedObject->get_object_type())
{
keyCode = std::static_pointer_cast<isobus::Button>(clickedObject)->get_key_code();
Expand All @@ -91,6 +93,7 @@ void DataMaskRenderAreaComponent::mouseDown(const MouseEvent &event)
else if (isobus::VirtualTerminalObjectType::Key == clickedObject->get_object_type())
{
keyCode = std::static_pointer_cast<isobus::Key>(clickedObject)->get_key_code();
keyPos = std::static_pointer_cast<KeyComponent>(clickedObject)->getKeyPosition();
ownerServer.process_macro(clickedObject, isobus::EventID::OnKeyPress, isobus::VirtualTerminalObjectType::Key, parentWorkingSet);
}

Expand All @@ -106,7 +109,8 @@ void DataMaskRenderAreaComponent::mouseDown(const MouseEvent &event)
clickedObject->get_id(),
activeMask->get_id(),
keyCode,
(isobus::VirtualTerminalObjectType::Key == clickedObject->get_object_type()));
(isobus::VirtualTerminalObjectType::Key == clickedObject->get_object_type()),
keyPos);
}
}
}
Expand Down Expand Up @@ -149,14 +153,16 @@ void DataMaskRenderAreaComponent::mouseUp(const MouseEvent &event)
clickedObject->get_id(),
activeMask->get_id(),
keyCode,
true);
true,
KeyComponent::InvalidSoftKeyPos);
}
}
break;

case isobus::VirtualTerminalObjectType::Key:
{
keyCode = std::static_pointer_cast<isobus::Key>(clickedObject)->get_key_code();
std::uint8_t keyPos = std::static_pointer_cast<KeyComponent>(clickedObject)->getKeyPosition();
ownerServer.send_button_activation_message(isobus::VirtualTerminalBase::KeyActivationCode::ButtonUnlatchedOrReleased,
clickedObject->get_id(),
activeMask->get_id(),
Expand All @@ -167,7 +173,8 @@ void DataMaskRenderAreaComponent::mouseUp(const MouseEvent &event)
clickedObject->get_id(),
activeMask->get_id(),
keyCode,
true);
true,
keyPos);
}
break;

Expand Down
10 changes: 10 additions & 0 deletions src/KeyComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ void KeyComponent::paint(Graphics &g)

g.fillAll(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0f));
}

uint8_t KeyComponent::getKeyPosition() const
{
return keyPosition;
}

void KeyComponent::setKeyPosition(std::uint8_t pos)
{
keyPosition = pos;
}
5 changes: 5 additions & 0 deletions src/ObjectPointerComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ void ObjectPointerComponent::on_content_changed(bool initial)
void ObjectPointerComponent::paint(Graphics &)
{
}

std::shared_ptr<Component> ObjectPointerComponent::getChildComponent() const
{
return childComponent;
}
65 changes: 53 additions & 12 deletions src/ServerMainComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "AlarmMaskAudio.h"
#include "JuceManagedWorkingSetCache.hpp"
#include "ShortcutsWindow.hpp"
#include "KeyComponent.hpp"
#include "isobus/utility/system_timing.hpp"

#include "SoftKeyMaskRenderAreaComponent.hpp"
Expand Down Expand Up @@ -598,11 +599,11 @@ void ServerMainComponent::timerCallback()

if (heldButton.isSoftKey)
{
sentMessage = send_soft_key_activation_message(KeyActivationCode::ButtonStillHeld, heldButton.buttonObjectID, heldButton.activeMaskObjectID, heldButton.buttonKeyCode, heldButton.associatedWorkingSet->get_control_function());
sentMessage = send_soft_key_activation_message(KeyActivationCode::ButtonStillHeld, heldButton.buttonObjectID, heldButton.softKeyMaskObjectID, heldButton.buttonKeyCode, heldButton.associatedWorkingSet->get_control_function());
}
else
{
sentMessage = send_button_activation_message(KeyActivationCode::ButtonStillHeld, heldButton.buttonObjectID, heldButton.activeMaskObjectID, heldButton.buttonKeyCode, heldButton.associatedWorkingSet->get_control_function());
sentMessage = send_button_activation_message(KeyActivationCode::ButtonStillHeld, heldButton.buttonObjectID, heldButton.softKeyMaskObjectID, heldButton.buttonKeyCode, heldButton.associatedWorkingSet->get_control_function());
}

if (sentMessage)
Expand Down Expand Up @@ -1107,6 +1108,7 @@ void ServerMainComponent::change_selected_working_set(std::uint8_t index)

dataMaskRenderer.on_change_active_mask(ws);
softKeyMaskRenderer.on_change_active_mask(ws);
handle_softkey_release_if_mask_changed();
activeWorkingSet = ws;
process_macro(activeWorkingSet->get_working_set_object(), isobus::EventID::OnActivate, isobus::VirtualTerminalObjectType::WorkingSet, activeWorkingSet);
ws->save_callback_handle(get_on_repaint_event_dispatcher().add_listener([this](std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet>) { this->repaint_on_next_update(); }));
Expand All @@ -1131,11 +1133,13 @@ void ServerMainComponent::change_selected_working_set(std::uint8_t index)
}
}

void ServerMainComponent::set_button_held(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey)
void ServerMainComponent::set_button_held(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey, uint8_t pos)
{
HeldButtonData buttonData(workingSet, objectID, maskObjectID, keyCode, isSoftKey);
HeldButtonData buttonData(workingSet, objectID, maskObjectID, keyCode, isSoftKey, pos);
bool alreadyHeld = false;

softKeyPositionReleasedByMaskChange = KeyComponent::InvalidSoftKeyPos;

for (auto &button : heldButtons)
{
if (buttonData == button)
Expand All @@ -1151,18 +1155,51 @@ void ServerMainComponent::set_button_held(std::shared_ptr<isobus::VirtualTermina
}
}

void ServerMainComponent::set_button_released(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey)
bool ServerMainComponent::is_key_position_released_by_mask_change(std::uint8_t pos) const
{
HeldButtonData buttonData(workingSet, objectID, maskObjectID, keyCode, isSoftKey);
bool alreadyHeld = false;
return softKeyPositionReleasedByMaskChange == pos;
}

void ServerMainComponent::set_button_released(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey, uint8_t pos)
{
HeldButtonData buttonData(workingSet, objectID, maskObjectID, keyCode, isSoftKey, pos);
auto found = std::find(heldButtons.begin(), heldButtons.end(), buttonData);
if (heldButtons.end() != found)
{
heldButtons.erase(found);
}
}

void ServerMainComponent::handle_softkey_release_if_mask_changed()
{
// If a Key object .... is erased from the screen ... while it is activated, the VT shall send a Soft Key Activation message
// ... indicating released to the erased object on its parent Data Mask.

for (auto button = heldButtons.begin(); button != heldButtons.end();)
{
if (button->softKeyMaskObjectID != activeWorkingSetSoftkeyMaskObjectID)
{
if (button->isSoftKey)
{
send_soft_key_activation_message(isobus::VirtualTerminalBase::KeyActivationCode::ButtonUnlatchedOrReleased,
button->buttonObjectID,
button->softKeyMaskObjectID,
button->buttonKeyCode,
get_active_working_set()->get_control_function());
// In the case if a currently pressed softkey is being replaced with a new one during a softkey mask change
// the mouseUp event on the newly added key will not be called, however the mouseRelease will.
// To prevent sending the unneeded mouse release events in this scenario we cache the softkey positions of the pressed and replaced keys.
softKeyPositionReleasedByMaskChange = button->keyPosition;
button = heldButtons.erase(button);
}
}
else
{
button++;
}
}
}

void ServerMainComponent::repaint_on_next_update()
{
needToRepaint = true;
Expand Down Expand Up @@ -1263,22 +1300,24 @@ void ServerMainComponent::LanguageCommandConfigClosed::operator()(int result) co
mParent.popupMenu.reset();
}

ServerMainComponent::HeldButtonData::HeldButtonData(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey) :
ServerMainComponent::HeldButtonData::HeldButtonData(std::shared_ptr<isobus::VirtualTerminalServerManagedWorkingSet> workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey, uint8_t position) :
isSoftKey(isSoftKey),
associatedWorkingSet(workingSet),
timestamp_ms(isobus::SystemTiming::get_timestamp_ms()),
buttonObjectID(objectID),
activeMaskObjectID(maskObjectID),
buttonKeyCode(keyCode)
softKeyMaskObjectID(maskObjectID),
buttonKeyCode(keyCode),
keyPosition(position)
{
}

bool ServerMainComponent::HeldButtonData::operator==(const HeldButtonData &other)
{
return ((other.activeMaskObjectID == activeMaskObjectID) &&
return ((other.softKeyMaskObjectID == softKeyMaskObjectID) &&
(other.associatedWorkingSet == associatedWorkingSet) &&
(other.buttonObjectID == buttonObjectID) &&
(other.buttonKeyCode == buttonKeyCode));
(other.buttonKeyCode == buttonKeyCode) &&
(other.keyPosition == keyPosition));
}

ServerMainComponent::VTVersion ServerMainComponent::get_version_from_setting(std::uint8_t aVersion)
Expand Down Expand Up @@ -1338,6 +1377,7 @@ void ServerMainComponent::on_change_active_mask_callback(std::shared_ptr<isobus:
const MessageManagerLock mmLock;

dataMaskRenderer.on_change_active_mask(activeWorkingSet);
handle_softkey_release_if_mask_changed();
softKeyMaskRenderer.on_change_active_mask(activeWorkingSet);

auto activeMask = affectedWorkingSet->get_object_by_id(newMask);
Expand Down Expand Up @@ -1405,6 +1445,7 @@ void ServerMainComponent::on_change_active_mask_callback(std::shared_ptr<isobus:
void ServerMainComponent::repaint_data_and_soft_key_mask()
{
dataMaskRenderer.on_change_active_mask(activeWorkingSet);
handle_softkey_release_if_mask_changed();
softKeyMaskRenderer.on_change_active_mask(activeWorkingSet);
workingSetSelector.redraw();
}
Expand Down
13 changes: 12 additions & 1 deletion src/SoftKeyMaskComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*******************************************************************************/
#include "SoftKeyMaskComponent.hpp"
#include "JuceManagedWorkingSetCache.hpp"
#include "KeyComponent.hpp"
#include "ObjectPointerComponent.hpp"

#include "SoftKeyMaskRenderAreaComponent.hpp"

Expand Down Expand Up @@ -34,7 +36,16 @@ void SoftKeyMaskComponent::on_content_changed(bool initial)

if (isobus::VirtualTerminalObjectType::ObjectPointer == child->get_object_type())
{
childComponents.back()->setSize(dimensionInfo.keyWidth, dimensionInfo.keyHeight);
childComponents.back()->setSize(softKeyWidth, softKeyHeight);
auto keyReference = get_object_by_id(std::static_pointer_cast<ObjectPointerComponent>(childComponents.back())->get_value(), parentWorkingSet->get_object_tree());
if (nullptr != keyReference && isobus::VirtualTerminalObjectType::Key == child->get_object_type())
{
std::static_pointer_cast<KeyComponent>(childComponents.back())->setKeyPosition(i);
}
}
else if (isobus::VirtualTerminalObjectType::Key == child->get_object_type())
{
std::static_pointer_cast<KeyComponent>(childComponents.back())->setKeyPosition(i);
}

if (nullptr != childComponents.back())
Expand Down
Loading

0 comments on commit 328a4ca

Please sign in to comment.