Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues with button press on softkey change #71

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ juce_add_gui_app(
DESCRIPTION
"An ISO11783-6 Server")

set_target_properties(AgISOVirtualTerminal PROPERTIES CXX_STANDARD 17)
set_target_properties(AgISOVirtualTerminal PROPERTIES CXX_STANDARD 20)

target_compile_definitions(AgISOVirtualTerminal PRIVATE JUCE_USE_CURL=0
JUCE_WEB_BROWSER=0)
Expand Down
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
15 changes: 10 additions & 5 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);
bool operator==(const HeldButtonData &other);
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) const;
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;
}
60 changes: 47 additions & 13 deletions src/ServerMainComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "AlarmMaskAudio.h"
#include "JuceManagedWorkingSetCache.hpp"
#include "KeyComponent.hpp"
#include "ShortcutsWindow.hpp"
#include "isobus/utility/system_timing.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);
ServerMainComponent::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,44 @@ 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.
std::erase_if(heldButtons,
[this](const HeldButtonData button) {
if ((button.softKeyMaskObjectID != activeWorkingSetSoftkeyMaskObjectID) && 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;
return true;
}
return false;
});
}

void ServerMainComponent::repaint_on_next_update()
{
needToRepaint = true;
Expand Down Expand Up @@ -1263,22 +1293,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)
bool ServerMainComponent::HeldButtonData::operator==(const HeldButtonData &other) const
{
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 +1370,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 +1438,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(dimensionInfo.keyHeight, dimensionInfo.keyWidth);
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
Loading