diff --git a/README.md b/README.md index 19372a4..592bd0a 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Supported features: - Containers - Object Pointers - Input numbers +- Input Boolean - Output numbers - Output rectangles - Output ellipse @@ -46,7 +47,6 @@ Unimplemented features (for now) - Output Lists - Output arched bar graph - Logging -- Input Boolean - Graphics contexts - Pointing events - TAN diff --git a/include/WorkingSetSelectorComponent.hpp b/include/WorkingSetSelectorComponent.hpp index e1ce4a6..77773e5 100644 --- a/include/WorkingSetSelectorComponent.hpp +++ b/include/WorkingSetSelectorComponent.hpp @@ -27,6 +27,8 @@ class WorkingSetSelectorComponent : public Component void paint(Graphics &g) override; void resized() override; + void redraw(); + private: struct SELECTOR_CHILD_OBJECTS_STRUCT { diff --git a/src/AlarmMaskComponent.cpp b/src/AlarmMaskComponent.cpp index 6b9094e..46417ef 100644 --- a/src/AlarmMaskComponent.cpp +++ b/src/AlarmMaskComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file AlarmMaskComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "AlarmMaskComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" diff --git a/src/ButtonComponent.cpp b/src/ButtonComponent.cpp index 07894fd..9fc2bde 100644 --- a/src/ButtonComponent.cpp +++ b/src/ButtonComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file ButtonComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "ButtonComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" diff --git a/src/ContainerComponent.cpp b/src/ContainerComponent.cpp index c47cda4..066af1e 100644 --- a/src/ContainerComponent.cpp +++ b/src/ContainerComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file ContainerComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "ContainerComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" @@ -44,6 +49,7 @@ void ContainerComponent::paint(Graphics &) child->setVisible(false); } } + this->setVisible(false); } else { @@ -54,5 +60,6 @@ void ContainerComponent::paint(Graphics &) child->setVisible(true); } } + this->setVisible(true); } } diff --git a/src/DataMaskComponent.cpp b/src/DataMaskComponent.cpp index 999e5ab..a1e840d 100644 --- a/src/DataMaskComponent.cpp +++ b/src/DataMaskComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file DataMaskComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "DataMaskComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" diff --git a/src/DataMaskRenderAreaComponent.cpp b/src/DataMaskRenderAreaComponent.cpp index 956dd40..7b2225f 100644 --- a/src/DataMaskRenderAreaComponent.cpp +++ b/src/DataMaskRenderAreaComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file DataMaskRenderAreaComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "DataMaskRenderAreaComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" #include "ServerMainComponent.hpp" @@ -5,7 +10,6 @@ DataMaskRenderAreaComponent::DataMaskRenderAreaComponent(ServerMainComponent &parentServer) : ownerServer(parentServer) { - addMouseListener(this, true); } void DataMaskRenderAreaComponent::on_change_active_mask(std::shared_ptr workingSet) @@ -114,13 +118,15 @@ void DataMaskRenderAreaComponent::mouseUp(const MouseEvent &event) { auto clickedList = std::static_pointer_cast(clickedObject); - if ((clickedList->get_option(isobus::InputList::Options::Enabled)) && (clickedList->get_number_children() > 1)) + if ((clickedList->get_option(isobus::InputList::Options::Enabled)) && + (clickedList->get_number_children() > 0) && + clickedList->get_option(isobus::InputList::Options::Enabled)) { // Need to display a modal combo selection inputListModal.reset(new AlertWindow("Input List Selection", "Select a List Item, then press OK.", MessageBoxIconType::QuestionIcon)); inputListModal->addComboBox("Input List Combo", StringArray()); currentModalComponentCache.clear(); - currentModalComponentCache.reserve(clickedList->get_number_children() - 1); + currentModalComponentCache.reserve(clickedList->get_number_children()); // In order to handle things that are not strings being allowed in an input list, grab the popup menu itself and shove custom components in there auto combo = inputListModal->getComboBoxComponent("Input List Combo"); @@ -130,16 +136,60 @@ void DataMaskRenderAreaComponent::mouseUp(const MouseEvent &event) { auto child = clickedList->get_object_by_id(clickedList->get_child_id(static_cast(i))); - if (0 != i) + if (nullptr != child) { currentModalComponentCache.push_back(JuceManagedWorkingSetCache::create_component(parentWorkingSet, child)); - comboPopup->addCustomItem(i, *currentModalComponentCache.back().get(), currentModalComponentCache.back()->getWidth(), currentModalComponentCache.back()->getHeight(), true, nullptr, "Object " + std::to_string(clickedList->get_child_id(static_cast(i)))); + comboPopup->addCustomItem(i + 1, *currentModalComponentCache.back().get(), currentModalComponentCache.back()->getWidth(), currentModalComponentCache.back()->getHeight(), true, nullptr, "Object " + std::to_string(clickedList->get_child_id(static_cast(i)))); } } inputListModal->addButton("OK", 0); - auto resultCallback = [this](int /*result*/) { + auto resultCallback = [this, clickedList](int result) { + auto combo = inputListModal->getComboBoxComponent("Input List Combo"); + result = combo->getSelectedItemIndex(); + + // Remap the visible index to the actual index + std::uint16_t numberOfNonNullsSeen = 0; + for (std::uint16_t i = 0; i < clickedList->get_number_children(); i++) + { + if (isobus::NULL_OBJECT_ID != clickedList->get_child_id(i)) + { + numberOfNonNullsSeen++; + } + + if (numberOfNonNullsSeen == result + 1) + { + result = i; + break; + } + } + + if (isobus::NULL_OBJECT_ID != clickedList->get_variable_reference()) + { + auto child = clickedList->get_object_by_id(clickedList->get_variable_reference()); + + if (nullptr != child) + { + if (isobus::VirtualTerminalObjectType::NumberVariable == child->get_object_type()) + { + if (std::static_pointer_cast(child)->get_value() != static_cast(result)) + { + ownerServer.send_change_numeric_value_message(child->get_id(), result, ownerServer.get_client_control_function_for_working_set(parentWorkingSet)); + } + std::static_pointer_cast(child)->set_value(result); + } + } + } + else + { + if (clickedList->get_value() != result) + { + ownerServer.send_change_numeric_value_message(clickedList->get_id(), result, ownerServer.get_client_control_function_for_working_set(parentWorkingSet)); + } + clickedList->set_value(static_cast(result)); + } this->inputListModal->exitModalState(); inputListModal.reset(); + repaint(); }; inputListModal->enterModalState(true, ModalCallbackFunction::create(std::move(resultCallback)), false); } @@ -231,6 +281,40 @@ void DataMaskRenderAreaComponent::mouseUp(const MouseEvent &event) } break; + case isobus::VirtualTerminalObjectType::InputBoolean: + { + auto clickedBool = std::static_pointer_cast(clickedObject); + + if (clickedBool->get_enabled()) + { + bool hasNumberVariable = false; + + for (std::uint16_t i = 0; i < clickedBool->get_number_children(); i++) + { + auto child = clickedBool->get_object_by_id(clickedBool->get_child_id(i)); + + if (nullptr != child) + { + if (isobus::VirtualTerminalObjectType::NumberVariable == child->get_object_type()) + { + hasNumberVariable = true; + std::static_pointer_cast(child)->set_value(!(0 != std::static_pointer_cast(child)->get_value())); + ownerServer.send_change_numeric_value_message(child->get_id(), std::static_pointer_cast(child)->get_value(), ownerServer.get_client_control_function_for_working_set(parentWorkingSet)); + break; + } + } + } + + if (!hasNumberVariable) + { + clickedBool->set_value(~clickedBool->get_value()); + ownerServer.send_change_numeric_value_message(clickedBool->get_id(), clickedBool->get_value(), ownerServer.get_client_control_function_for_working_set(parentWorkingSet)); + } + repaint(); + } + } + break; + default: break; } diff --git a/src/InputBooleanComponent.cpp b/src/InputBooleanComponent.cpp index f249185..f17c475 100644 --- a/src/InputBooleanComponent.cpp +++ b/src/InputBooleanComponent.cpp @@ -1 +1,57 @@ +/******************************************************************************* +** @file InputBooleanComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "InputBooleanComponent.hpp" + +InputBooleanComponent::InputBooleanComponent(std::shared_ptr workingSet, isobus::InputBoolean sourceObject) : + isobus::InputBoolean(sourceObject), + parentWorkingSet(workingSet) +{ + setOpaque(false); + setSize(get_width(), get_height()); + + setEnabled(get_enabled()); +} + +void InputBooleanComponent::paint(Graphics &g) +{ + // Draw background + auto vtColour = colourTable.get_colour(get_background_color()); + g.setColour(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0f)); + g.drawRect(0, 0, static_cast(get_width()), static_cast(get_height()), 0); + + g.setColour(Colour::fromFloatRGBA(0.0f, 0.0f, 0.0f, 1.0f)); + // Change colour to foreground colour if present + for (std::uint16_t i = 0; i < get_number_children(); i++) + { + auto child = get_object_by_id(get_child_id(i)); + + if ((nullptr != child) && (isobus::VirtualTerminalObjectType::FontAttributes == child->get_object_type())) + { + vtColour = colourTable.get_colour(std::static_pointer_cast(child)->get_background_color()); + g.setColour(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0f)); + break; + } + } + + bool isChecked = (0 != get_value()); + // Change use number variable if one was provided + for (std::uint16_t i = 0; i < get_number_children(); i++) + { + auto child = get_object_by_id(get_child_id(i)); + + if ((nullptr != child) && (isobus::VirtualTerminalObjectType::NumberVariable == child->get_object_type())) + { + isChecked = std::static_pointer_cast(child)->get_value(); + break; + } + } + + if (isChecked) + { + g.drawLine(0, get_height() / 2, get_width() / 2, get_height()); + g.drawLine(get_width() / 2, get_height(), get_width(), 0); + } +} diff --git a/src/InputListComponent.cpp b/src/InputListComponent.cpp index 14a3690..3733ebd 100644 --- a/src/InputListComponent.cpp +++ b/src/InputListComponent.cpp @@ -1,11 +1,8 @@ -//================================================================================================ -/// @file InputListComponent.cpp -/// -/// @brief This is a class for drawing an input list. -/// @author Adrian Del Grosso -/// -/// @copyright 2023 Adrian Del Grosso -//================================================================================================ +/******************************************************************************* +** @file InputListComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "InputListComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" @@ -26,35 +23,32 @@ void InputListComponent::onChanged(bool initial) { childComponent.reset(); - if (get_number_children() > 1) + std::uint32_t selectedIndex = get_value(); + + if (isobus::NULL_OBJECT_ID != get_variable_reference()) { - std::uint32_t selectedIndex = get_value(); + auto child = get_object_by_id(get_variable_reference()); - for (std::uint16_t i = 0; i < get_number_children(); i++) + if (nullptr != child) { - auto child = get_object_by_id(get_child_id(i)); - - if (nullptr != child) + if (isobus::VirtualTerminalObjectType::NumberVariable == child->get_object_type()) { - if (isobus::VirtualTerminalObjectType::NumberVariable == child->get_object_type()) - { - selectedIndex = std::static_pointer_cast(child)->get_value(); - break; - } + selectedIndex = std::static_pointer_cast(child)->get_value(); } } + } - if (selectedIndex < static_cast(get_number_children() - 1)) - { - // The number variable will always be the first one - auto listItem = get_object_by_id(get_child_id(static_cast(selectedIndex + 1))); - childComponent = JuceManagedWorkingSetCache::create_component(parentWorkingSet, listItem); + if ((get_number_children() > 0) && + (selectedIndex < static_cast(get_number_children()))) + { + // The number variable will always be the first one + auto listItem = get_object_by_id(get_child_id(static_cast(selectedIndex))); + childComponent = JuceManagedWorkingSetCache::create_component(parentWorkingSet, listItem); - if (nullptr != childComponent) - { - addAndMakeVisible(*childComponent); - childComponent->setTopLeftPosition(0, 0); - } + if (nullptr != childComponent) + { + addAndMakeVisible(*childComponent); + childComponent->setTopLeftPosition(0, 0); } } diff --git a/src/InputNumberComponent.cpp b/src/InputNumberComponent.cpp index 96f913d..10b4723 100644 --- a/src/InputNumberComponent.cpp +++ b/src/InputNumberComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file InputNumberComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "InputNumberComponent.hpp" #include diff --git a/src/JuceManagedWorkingSetCache.cpp b/src/JuceManagedWorkingSetCache.cpp index 238e560..4163bbd 100644 --- a/src/JuceManagedWorkingSetCache.cpp +++ b/src/JuceManagedWorkingSetCache.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file JuceManagedWorkingSetCache.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "JuceManagedWorkingSetCache.hpp" #include "AlarmMaskComponent.hpp" @@ -98,8 +103,13 @@ std::shared_ptr JuceManagedWorkingSetCache::create_component(std::sha } break; - case isobus::VirtualTerminalObjectType::KeyGroup: case isobus::VirtualTerminalObjectType::InputBoolean: + { + retVal = std::make_shared(workingSet, *std::static_pointer_cast(sourceObject)); + } + break; + + case isobus::VirtualTerminalObjectType::KeyGroup: case isobus::VirtualTerminalObjectType::InputString: { } @@ -217,5 +227,10 @@ std::shared_ptr JuceManagedWorkingSetCache::create_component(std::sha break; } } + + if (nullptr != retVal) + { + retVal->setInterceptsMouseClicks(false, false); + } return retVal; } diff --git a/src/KeyComponent.cpp b/src/KeyComponent.cpp index c8c8b4a..7a72b11 100644 --- a/src/KeyComponent.cpp +++ b/src/KeyComponent.cpp @@ -1,4 +1,10 @@ +/******************************************************************************* +** @file KeyComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "KeyComponent.hpp" + #include "JuceManagedWorkingSetCache.hpp" KeyComponent::KeyComponent(std::shared_ptr workingSet, isobus::Key sourceObject) : diff --git a/src/Main.cpp b/src/Main.cpp index 80e3348..e06c180 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -1,11 +1,8 @@ -/* - ============================================================================== - - This file contains the basic startup code for a JUCE application. - - ============================================================================== -*/ - +/******************************************************************************* +** @file Main.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include #include "ServerMainComponent.hpp" #include "isobus/hardware_integration/available_can_drivers.hpp" @@ -97,7 +94,7 @@ class AgISOUniversalTerminalApplication : public juce::JUCEApplication serverNAME.set_arbitrary_address_capable(true); serverNAME.set_function_code(static_cast(isobus::NAME::Function::VirtualTerminal)); serverNAME.set_industry_group(2); - serverNAME.set_manufacturer_code(64); + serverNAME.set_manufacturer_code(1407); serverInternalControlFunction = isobus::InternalControlFunction::create(serverNAME, 0x26, 0); setUsingNativeTitleBar(true); setContentOwned(new ServerMainComponent(serverInternalControlFunction), true); @@ -117,6 +114,7 @@ class AgISOUniversalTerminalApplication : public juce::JUCEApplication // This is called when the user tries to close this window. Here, we'll just // ask the app to quit when this happens, but you can change this to do // whatever you need. + isobus::CANHardwareInterface::stop(); JUCEApplication::getInstance()->systemRequestedQuit(); } diff --git a/src/ObjectPointerComponent.cpp b/src/ObjectPointerComponent.cpp index c81d0e8..15d8c61 100644 --- a/src/ObjectPointerComponent.cpp +++ b/src/ObjectPointerComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file ObjectPointerComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "ObjectPointerComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" diff --git a/src/OutputEllipseComponent.cpp b/src/OutputEllipseComponent.cpp index 0981eef..24e541d 100644 --- a/src/OutputEllipseComponent.cpp +++ b/src/OutputEllipseComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputEllipseComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputEllipseComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" diff --git a/src/OutputLineComponent.cpp b/src/OutputLineComponent.cpp index 8d1e14f..9fd122b 100644 --- a/src/OutputLineComponent.cpp +++ b/src/OutputLineComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputLineComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputLineComponent.hpp" OutputLineComponent::OutputLineComponent(std::shared_ptr workingSet, isobus::OutputLine sourceObject) : diff --git a/src/OutputLinearBarGraphComponent.cpp b/src/OutputLinearBarGraphComponent.cpp index 6f402b0..65a30ab 100644 --- a/src/OutputLinearBarGraphComponent.cpp +++ b/src/OutputLinearBarGraphComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputLinearBarGraphComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputLinearBarGraphComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" diff --git a/src/OutputMeterComponent.cpp b/src/OutputMeterComponent.cpp index 2ff7a1d..9bd2272 100644 --- a/src/OutputMeterComponent.cpp +++ b/src/OutputMeterComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputMeterComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputMeterComponent.hpp" #include diff --git a/src/OutputNumberComponent.cpp b/src/OutputNumberComponent.cpp index f2efa0f..ad35de0 100644 --- a/src/OutputNumberComponent.cpp +++ b/src/OutputNumberComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputNumberComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputNumberComponent.hpp" #include diff --git a/src/OutputPolygonComponent.cpp b/src/OutputPolygonComponent.cpp index ecf8383..641faa0 100644 --- a/src/OutputPolygonComponent.cpp +++ b/src/OutputPolygonComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputPolygonComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputPolygonComponent.hpp" OutputPolygonComponent::OutputPolygonComponent(std::shared_ptr workingSet, isobus::OutputPolygon sourceObject) : @@ -62,11 +67,11 @@ void OutputPolygonComponent::paint(Graphics &g) auto vtColour = colourTable.get_colour(fill->get_background_color()); g.setFillType(FillType(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0f))); + g.fillPath(polygonPath); break; } } - g.fillPath(polygonPath); g.resetToDefaultState(); g.setColour(lineColour); g.strokePath(polygonPath, PathStrokeType(lineWidth)); diff --git a/src/OutputRectangleComponent.cpp b/src/OutputRectangleComponent.cpp index 57fad19..7558fd0 100644 --- a/src/OutputRectangleComponent.cpp +++ b/src/OutputRectangleComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputRectangleComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputRectangleComponent.hpp" OutputRectangleComponent::OutputRectangleComponent(std::shared_ptr workingSet, isobus::OutputRectangle sourceObject) : @@ -21,7 +26,44 @@ void OutputRectangleComponent::paint(Graphics &g) auto fill = std::static_pointer_cast(child); vtColour = colourTable.get_colour(fill->get_background_color()); - g.fillAll(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0f)); + switch (std::static_pointer_cast(child)->get_type()) + { + case isobus::FillAttributes::FillType::FillWithPatternGivenByFillPatternAttribute: + { + // @todo + } + break; + + case isobus::FillAttributes::FillType::FillWithLineColor: + { + for (std::uint16_t i = 0; i < get_number_children(); i++) + { + auto childLineAttributes = get_object_by_id(get_child_id(i)); + + if ((nullptr != childLineAttributes) && (isobus::VirtualTerminalObjectType::LineAttributes == childLineAttributes->get_object_type())) + { + auto line = std::static_pointer_cast(childLineAttributes); + vtColour = colourTable.get_colour(line->get_background_color()); + g.setColour(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0)); + g.fillAll(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0f)); + break; + } + } + } + break; + + case isobus::FillAttributes::FillType::FillWithSpecifiedColorInFillColorAttribute: + { + g.fillAll(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0f)); + } + break; + + default: + { + // No fill + } + break; + } isOpaque = true; break; } @@ -40,7 +82,8 @@ void OutputRectangleComponent::paint(Graphics &g) if (0 != line->get_width()) { bool anyLineSuppressed = (0 != get_line_suppression_bitfield()); - g.setColour(Colour::fromFloatRGBA(0.0f, 0.0f, 0.0f, 1.0)); + vtColour = colourTable.get_colour(line->get_background_color()); + g.setColour(Colour::fromFloatRGBA(vtColour.r, vtColour.g, vtColour.b, 1.0)); if (!anyLineSuppressed) { diff --git a/src/OutputStringComponent.cpp b/src/OutputStringComponent.cpp index c3e7d03..0c19ab0 100644 --- a/src/OutputStringComponent.cpp +++ b/src/OutputStringComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file OutputStringComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "OutputStringComponent.hpp" OutputStringComponent::OutputStringComponent(std::shared_ptr workingSet, isobus::OutputString sourceObject) : diff --git a/src/PictureGraphicComponent.cpp b/src/PictureGraphicComponent.cpp index 4232699..63bd912 100644 --- a/src/PictureGraphicComponent.cpp +++ b/src/PictureGraphicComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file PictureGraphicComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "PictureGraphicComponent.hpp" PictureGraphicComponent::PictureGraphicComponent(std::shared_ptr workingSet, isobus::PictureGraphic sourceObject) : diff --git a/src/ServerMainComponent.cpp b/src/ServerMainComponent.cpp index d684df9..4094ab6 100644 --- a/src/ServerMainComponent.cpp +++ b/src/ServerMainComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file ServerMainComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "ServerMainComponent.hpp" #include "AlarmMaskAudio.h" @@ -215,6 +220,8 @@ void ServerMainComponent::timerCallback() dataMaskRenderer.on_change_active_mask(ws); softKeyMaskRenderer.on_change_active_mask(ws); activeWorkingSet = ws; + ws->save_callback_handle(get_on_repaint_event_dispatcher().add_listener([this](std::shared_ptr) {const MessageManagerLock mmLock; this->dataMaskRenderer.on_change_active_mask(activeWorkingSet); + softKeyMaskRenderer.on_change_active_mask(activeWorkingSet); })); // Todo only repaint if active WS is the one that changed ws->save_callback_handle(get_on_change_active_mask_event_dispatcher().add_listener([this](std::shared_ptr affectedWorkingSet, std::uint16_t workingSet, std::uint16_t newMask) { this->on_change_active_mask_callback(affectedWorkingSet, workingSet, newMask); })); ws->save_callback_handle(get_on_change_numeric_value_event_dispatcher().add_listener([this](std::shared_ptr affectedWorkingSet, std::uint16_t objectID, std::uint32_t value) { this->on_change_numeric_value_callback(affectedWorkingSet, objectID, value); })); ws->save_callback_handle(get_on_change_string_value_event_dispatcher().add_listener([this](std::shared_ptr affectedWorkingSet, std::uint16_t objectID, std::string value) { this->on_change_string_value_callback(affectedWorkingSet, objectID, value); })); @@ -230,12 +237,13 @@ void ServerMainComponent::timerCallback() else if ((isobus::VirtualTerminalServerManagedWorkingSet::ObjectPoolProcessingThreadState::Joined == ws->get_object_pool_processing_state()) && (isobus::SystemTiming::time_expired_ms(ws->get_working_set_maintenance_message_timestamp_ms(), 3000))) { - //workingSetSelector.remove_working_set(std::static_pointer_cast(ws->get_working_set_object())); + workingSetSelector.remove_working_set(ws); } else if (isobus::VirtualTerminalServerManagedWorkingSet::ObjectPoolProcessingThreadState::Joined == ws->get_object_pool_processing_state()) { if (dataMaskRenderer.needsRepaint()) { + repaint_data_and_soft_key_mask(); dataMaskRenderer.on_change_active_mask(ws); } } @@ -262,6 +270,8 @@ std::shared_ptr ServerMainComponent::get_client_control { std::shared_ptr retVal = nullptr; + uint64_t test = 0; + for (const auto &ws : managedWorkingSetList) { if (workingSet == ws) @@ -292,177 +302,87 @@ void ServerMainComponent::on_change_active_mask_callback(std::shared_ptrget_object_pool_processing_state()) { const MessageManagerLock mmLock; + dataMaskRenderer.on_change_active_mask(activeWorkingSet); softKeyMaskRenderer.on_change_active_mask(activeWorkingSet); auto activeMask = affectedWorkingSet->get_object_by_id(newMask); - - if ((nullptr != activeMask) && (isobus::VirtualTerminalObjectType::AlarmMask == activeMask->get_object_type())) + + if (activeWorkingSetDataMaskObjectID != newMask) { - auto alarmMask = std::static_pointer_cast(activeMask); - - switch (alarmMask->get_signal_priority()) + activeWorkingSetDataMaskObjectID = newMask; + + if (send_status_message()) { - case isobus::AlarmMask::AcousticSignal::Highest: - { - mSoundPlayer.play(AlarmMaskAudio::alarmMaskHigh_mp3, AlarmMaskAudio::alarmMaskHigh_mp3Size); - } - break; - - case isobus::AlarmMask::AcousticSignal::Medium: - { - mSoundPlayer.play(AlarmMaskAudio::alarmMaskMedium_mp3, AlarmMaskAudio::alarmMaskMedium_mp3Size); - } - break; - - case isobus::AlarmMask::AcousticSignal::Lowest: - { - mSoundPlayer.play(AlarmMaskAudio::alarmMaskLow_mp3, AlarmMaskAudio::alarmMaskLow_mp3Size); - } - break; - - default: - break; + statusMessageTimestamp_ms = isobus::SystemTiming::get_timestamp_ms(); } - } - } -} - -void ServerMainComponent::on_change_numeric_value_callback(std::shared_ptr affectedWorkingSet, std::uint16_t objectID, std::uint32_t value) -{ - if (isobus::VirtualTerminalServerManagedWorkingSet::ObjectPoolProcessingThreadState::Joined == affectedWorkingSet->get_object_pool_processing_state()) - { - const MessageManagerLock mmLock; - auto affectedObject = affectedWorkingSet->get_object_by_id(objectID); - - switch (affectedObject->get_object_type()) - { - case isobus::VirtualTerminalObjectType::InputBoolean: + else { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); + statusMessageTimestamp_ms = 0; } - break; - - case isobus::VirtualTerminalObjectType::InputNumber: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; - - case isobus::VirtualTerminalObjectType::InputList: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; - - case isobus::VirtualTerminalObjectType::OutputNumber: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; - - case isobus::VirtualTerminalObjectType::OutputList: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; + } - case isobus::VirtualTerminalObjectType::OutputMeter: + if (nullptr != activeMask) + { + for (std::uint16_t i = 0; i < activeMask->get_number_children(); i++) { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; + auto child = activeMask->get_object_by_id(activeMask->get_child_id(i)); - case isobus::VirtualTerminalObjectType::OutputLinearBarGraph: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); + if ((nullptr != child) && (isobus::VirtualTerminalObjectType::SoftKeyMask == child->get_object_type())) + { + activeWorkingSetSoftkeyMaskObjectID = child->get_id(); + break; + } } - break; - case isobus::VirtualTerminalObjectType::OutputArchedBarGraph: + if (isobus::VirtualTerminalObjectType::AlarmMask == activeMask->get_object_type()) { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; + auto alarmMask = std::static_pointer_cast(activeMask); - case isobus::VirtualTerminalObjectType::NumberVariable: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; + switch (alarmMask->get_signal_priority()) + { + case isobus::AlarmMask::AcousticSignal::Highest: + { + mSoundPlayer.play(AlarmMaskAudio::alarmMaskHigh_mp3, AlarmMaskAudio::alarmMaskHigh_mp3Size); + } + break; - case isobus::VirtualTerminalObjectType::ObjectPointer: - { - std::static_pointer_cast(affectedObject)->pop_child(); - std::static_pointer_cast(affectedObject)->add_child(value, 0, 0); - repaint_data_and_soft_key_mask(); - } - break; + case isobus::AlarmMask::AcousticSignal::Medium: + { + mSoundPlayer.play(AlarmMaskAudio::alarmMaskMedium_mp3, AlarmMaskAudio::alarmMaskMedium_mp3Size); + } + break; - case isobus::VirtualTerminalObjectType::ExternalObjectPointer: - { - // TODO - } - break; + case isobus::AlarmMask::AcousticSignal::Lowest: + { + mSoundPlayer.play(AlarmMaskAudio::alarmMaskLow_mp3, AlarmMaskAudio::alarmMaskLow_mp3Size); + } + break; - case isobus::VirtualTerminalObjectType::Animation: - { - //Todo std::static_pointer_cast(lTargetObject)->set_value(value); + default: + break; + } } - break; - - default: - break; } } } -void ServerMainComponent::on_change_string_value_callback(std::shared_ptr affectedWorkingSet, std::uint16_t objectID, std::string value) +void ServerMainComponent::on_change_numeric_value_callback(std::shared_ptr affectedWorkingSet, std::uint16_t objectID, std::uint32_t value) { if (isobus::VirtualTerminalServerManagedWorkingSet::ObjectPoolProcessingThreadState::Joined == affectedWorkingSet->get_object_pool_processing_state()) { const MessageManagerLock mmLock; - auto affectedObject = affectedWorkingSet->get_object_by_id(objectID); - - switch (affectedObject->get_object_type()) - { - case isobus::VirtualTerminalObjectType::StringVariable: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; - - case isobus::VirtualTerminalObjectType::InputString: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; - - case isobus::VirtualTerminalObjectType::OutputString: - { - std::static_pointer_cast(affectedObject)->set_value(value); - repaint_data_and_soft_key_mask(); - } - break; - - default: - break; - } + repaint_data_and_soft_key_mask(); } } -void ServerMainComponent::on_change_child_position_callback(std::shared_ptr, std::uint16_t, std::uint16_t, std::uint16_t, std::uint16_t) +void ServerMainComponent::on_change_string_value_callback(std::shared_ptr affectedWorkingSet, std::uint16_t objectID, std::string value) +{ + const MessageManagerLock mmLock; + repaint_data_and_soft_key_mask(); +} + +void ServerMainComponent::on_change_child_position_callback(std::shared_ptr, std::uint16_t, std::uint16_t objectID, std::uint16_t, std::uint16_t) { const MessageManagerLock mmLock; repaint_data_and_soft_key_mask(); @@ -472,4 +392,5 @@ void ServerMainComponent::repaint_data_and_soft_key_mask() { dataMaskRenderer.on_change_active_mask(activeWorkingSet); softKeyMaskRenderer.on_change_active_mask(activeWorkingSet); + workingSetSelector.redraw(); } diff --git a/src/SoftKeyMaskComponent.cpp b/src/SoftKeyMaskComponent.cpp index 04a735e..f0580c7 100644 --- a/src/SoftKeyMaskComponent.cpp +++ b/src/SoftKeyMaskComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file SoftKeyMaskComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "SoftKeyMaskComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" @@ -24,8 +29,6 @@ void SoftKeyMaskComponent::on_content_changed(bool initial) { addAndMakeVisible(*childComponents.back()); childComponents.back()->setTopLeftPosition(10, 10 + (60 * i) + (10 * i)); - - // Add space between the keys } } } diff --git a/src/SoftkeyMaskRenderArea.cpp b/src/SoftkeyMaskRenderArea.cpp index 8b7acc9..28a7a04 100644 --- a/src/SoftkeyMaskRenderArea.cpp +++ b/src/SoftkeyMaskRenderArea.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file SoftKeyMaskRenderAreaComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "JuceManagedWorkingSetCache.hpp" #include "ServerMainComponent.hpp" #include "SoftKeyMaskRenderAreaComponent.hpp" diff --git a/src/WorkingSetComponent.cpp b/src/WorkingSetComponent.cpp index 7dc53b5..c3a0024 100644 --- a/src/WorkingSetComponent.cpp +++ b/src/WorkingSetComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file WorkingSetComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "WorkingSetComponent.hpp" WorkingSetComponent::WorkingSetComponent(std::shared_ptr workingSet, isobus::WorkingSet sourceObject) : diff --git a/src/WorkingSetSelectorComponent.cpp b/src/WorkingSetSelectorComponent.cpp index 38e5255..40af6ba 100644 --- a/src/WorkingSetSelectorComponent.cpp +++ b/src/WorkingSetSelectorComponent.cpp @@ -1,3 +1,8 @@ +/******************************************************************************* +** @file WorkingSetSelectorComponent.cpp +** @author Adrian Del Grosso +** @copyright The Open-Agriculture Developers +*******************************************************************************/ #include "WorkingSetSelectorComponent.hpp" #include "JuceManagedWorkingSetCache.hpp" @@ -17,7 +22,7 @@ void WorkingSetSelectorComponent::add_working_set_to_draw(std::shared_ptrget_object_by_id(workingSetObject->get_child_id(i))); children.back().childComponents.push_back(childObject); - childObject->setTopLeftPosition(8 + 15, 8 + 7); + childObject->setTopLeftPosition(4 + 15, 10 + 7); addAndMakeVisible(*childObject); } repaint(); @@ -30,6 +35,7 @@ void WorkingSetSelectorComponent::remove_working_set(std::shared_ptrworkingSet) { children.erase(child); + break; } } repaint(); @@ -40,7 +46,7 @@ void WorkingSetSelectorComponent::paint(Graphics &g) g.setColour(getLookAndFeel().findColour(ResizableWindow::backgroundColourId)); g.fillAll(); - for (auto &ws : children) + for (const auto &ws : children) { g.setColour(getLookAndFeel().findColour(ResizableWindow::backgroundColourId).brighter()); g.drawRoundedRectangle(8.0, 8.0, 80, 80, 6, 1); @@ -52,3 +58,21 @@ void WorkingSetSelectorComponent::resized() auto parentBounds = getLocalBounds(); setBounds(0, 0, 100, parentBounds.getHeight()); } + +void WorkingSetSelectorComponent::redraw() +{ + for (auto& workingSet : children) + { + workingSet.childComponents.clear(); + auto workingSetObject = workingSet.workingSet->get_working_set_object(); + + for (std::uint16_t i = 0; i < workingSetObject->get_number_children(); i++) + { + auto childObject = JuceManagedWorkingSetCache::create_component(workingSet.workingSet, workingSetObject->get_object_by_id(workingSetObject->get_child_id(i))); + children.back().childComponents.push_back(childObject); + childObject->setTopLeftPosition(4 + 15 + workingSetObject->get_child_x(i), 10 + 7 + workingSetObject->get_child_y(i)); + addAndMakeVisible(*childObject); + } + } + repaint(); +}