From 032b6c6300e441a1ec6f515112f2f0666ea25cb9 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sat, 13 Jan 2024 02:30:11 +0000 Subject: [PATCH] Resizable Effects-Only Zones --- .../RGBController_MSIMysticLight185.cpp | 52 ++++++++++++++----- RGBController/RGBController.cpp | 48 ++++++++++++++--- RGBController/RGBController.h | 27 ++++++++-- qt/DeviceView.cpp | 6 +-- qt/OpenRGBDevicePage/OpenRGBDevicePage.cpp | 15 +++--- 5 files changed, 117 insertions(+), 31 deletions(-) diff --git a/Controllers/MSIMysticLightController/MSIMysticLight185Controller/RGBController_MSIMysticLight185.cpp b/Controllers/MSIMysticLightController/MSIMysticLight185Controller/RGBController_MSIMysticLight185.cpp index 4429931f..91084a92 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLight185Controller/RGBController_MSIMysticLight185.cpp +++ b/Controllers/MSIMysticLightController/MSIMysticLight185Controller/RGBController_MSIMysticLight185.cpp @@ -147,23 +147,37 @@ void RGBController_MSIMysticLight185::SetupZones() zone new_zone; new_zone.name = zd->name; + new_zone.flags = 0; int maxLeds = (int)controller->GetMaxDirectLeds(zd->zone_type); /*-------------------------------------------------*\ | This is a fixed size zone | - | Either this is a board which only supports zone | - | control or this is not an ARGB header zone | \*-------------------------------------------------*/ - if((controller->GetSupportedDirectMode() == MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED) - || ((zd->zone_type != MSI_ZONE_J_RAINBOW_1) && (zd->zone_type != MSI_ZONE_J_RAINBOW_2) && (zd->zone_type != MSI_ZONE_J_RAINBOW_3) && (zd->zone_type != MSI_ZONE_J_CORSAIR))) + if(((zd->zone_type != MSI_ZONE_J_RAINBOW_1) + && (zd->zone_type != MSI_ZONE_J_RAINBOW_2) + && (zd->zone_type != MSI_ZONE_J_RAINBOW_3) + && (zd->zone_type != MSI_ZONE_J_CORSAIR))) { new_zone.leds_min = maxLeds; new_zone.leds_max = maxLeds; new_zone.leds_count = maxLeds; } /*--------------------------------------------------\ - | This is a resizable zone on a per-LED board | + | This is a resizable zone on a board that does not | + | support per-LED direct mode | + \*-------------------------------------------------*/ + else if(controller->GetSupportedDirectMode() == MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED) + { + new_zone.leds_min = 0; + new_zone.leds_max = 30;//maxLeds; + new_zone.leds_count = 0; + last_resizable_zone = zd->zone_type; + new_zone.flags |= ZONE_FLAG_RESIZE_EFFECTS_ONLY; + } + /*--------------------------------------------------\ + | This is a resizable zone on a board that does | + | support per-LED direct mode | \*-------------------------------------------------*/ else { @@ -176,7 +190,7 @@ void RGBController_MSIMysticLight185::SetupZones() /*-------------------------------------------------*\ | Determine zone type based on max number of LEDs | \*-------------------------------------------------*/ - if(new_zone.leds_max == 1) + if((new_zone.leds_max == 1) || (new_zone.flags & ZONE_FLAG_RESIZE_EFFECTS_ONLY)) { new_zone.type = ZONE_TYPE_SINGLE; } @@ -199,16 +213,28 @@ void RGBController_MSIMysticLight185::SetupZones() { controller->SetCycleCount(zone_description[zone_idx]->zone_type, zones[zone_idx].leds_count); - for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; ++led_idx) + if((zones[zone_idx].flags & ZONE_FLAG_RESIZE_EFFECTS_ONLY) == 0) + { + for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; ++led_idx) + { + led new_led; + + new_led.name = zones[zone_idx].name; + + if(zones[zone_idx].leds_count > 1) + { + new_led.name.append(" LED " + std::to_string(led_idx + 1)); + } + + new_led.value = zone_description[zone_idx]->zone_type; + leds.push_back(new_led); + } + } + else if(zones[zone_idx].leds_count > 0) { led new_led; - new_led.name = zones[zone_idx].name + " LED "; - - if(zones[zone_idx].leds_count > 1) - { - new_led.name.append(std::to_string(led_idx + 1)); - } + new_led.name = zones[zone_idx].name; new_led.value = zone_description[zone_idx]->zone_type; leds.push_back(new_led); diff --git a/RGBController/RGBController.cpp b/RGBController/RGBController.cpp index 36d61654..745dcca9 100644 --- a/RGBController/RGBController.cpp +++ b/RGBController/RGBController.cpp @@ -37,6 +37,25 @@ mode::~mode() colors.clear(); } +zone::zone() +{ + name = ""; + type = 0; + leds = NULL; + colors = NULL; + start_idx = 0; + leds_count = 0; + leds_min = 0; + leds_max = 0; + matrix_map = NULL; + flags = 0; +} + +zone::~zone() +{ + +} + RGBController::RGBController() { DeviceThreadRunning = true; @@ -1515,6 +1534,7 @@ void RGBController::SetSingleLEDColorDescription(unsigned char* data_buf) void RGBController::SetupColors() { unsigned int total_led_count; + unsigned int zone_led_count; /*---------------------------------------------------------*\ | Determine total number of LEDs on the device | @@ -1523,7 +1543,7 @@ void RGBController::SetupColors() for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) { - total_led_count += zones[zone_idx].leds_count; + total_led_count += GetLEDsInZone(zone_idx); } /*---------------------------------------------------------*\ @@ -1538,9 +1558,10 @@ void RGBController::SetupColors() for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) { - zones[zone_idx].start_idx=total_led_count; + zones[zone_idx].start_idx = total_led_count; + zone_led_count = GetLEDsInZone(zone_idx); - if((colors.size() > 0) && (zones[zone_idx].leds_count > 0)) + if((colors.size() > 0) && (zone_led_count > 0)) { zones[zone_idx].colors = &colors[total_led_count]; } @@ -1549,7 +1570,7 @@ void RGBController::SetupColors() zones[zone_idx].colors = NULL; } - if((leds.size() > 0) && (zones[zone_idx].leds_count > 0)) + if((leds.size() > 0) && (zone_led_count > 0)) { zones[zone_idx].leds = &leds[total_led_count]; } @@ -1559,10 +1580,25 @@ void RGBController::SetupColors() } - total_led_count += zones[zone_idx].leds_count; + total_led_count += zone_led_count; } } +unsigned int RGBController::GetLEDsInZone(unsigned int zone) +{ + unsigned int leds_count = zones[zone].leds_count; + + if(zones[zone].flags & ZONE_FLAG_RESIZE_EFFECTS_ONLY) + { + if(leds_count > 1) + { + leds_count = 1; + } + } + + return(leds_count); +} + RGBColor RGBController::GetLED(unsigned int led) { if(led < colors.size()) @@ -1593,7 +1629,7 @@ void RGBController::SetAllLEDs(RGBColor color) void RGBController::SetAllZoneLEDs(int zone, RGBColor color) { - for (std::size_t color_idx = 0; color_idx < zones[zone].leds_count; color_idx++) + for (std::size_t color_idx = 0; color_idx < GetLEDsInZone(zone); color_idx++) { zones[zone].colors[color_idx] = color; } diff --git a/RGBController/RGBController.h b/RGBController/RGBController.h index e2765f2c..208bdf3f 100644 --- a/RGBController/RGBController.h +++ b/RGBController/RGBController.h @@ -116,6 +116,15 @@ typedef struct unsigned int value; /* Device-specific LED value */ } led; +/*------------------------------------------------------------------*\ +| Zone Flags | +\*------------------------------------------------------------------*/ +enum +{ + ZONE_FLAG_RESIZE_EFFECTS_ONLY = (1 << 0), /* Zone is resizable, but only for */ + /* effects - treat as single LED */ +}; + /*------------------------------------------------------------------*\ | Zone Types | \*------------------------------------------------------------------*/ @@ -150,10 +159,11 @@ typedef struct } segment; /*------------------------------------------------------------------*\ -| Zone Struct | +| Zone Class | \*------------------------------------------------------------------*/ -typedef struct +class zone { +public: std::string name; /* Zone name */ zone_type type; /* Zone type */ led * leds; /* List of LEDs in zone */ @@ -164,7 +174,14 @@ typedef struct unsigned int leds_max; /* Maximum number of LEDs */ matrix_map_type * matrix_map; /* Matrix map pointer */ std::vector segments; /* Segments in zone */ -} zone; + unsigned int flags; /* Zone flags bitfield */ + + /*--------------------------------------------------------------*\ + | Zone Constructor / Destructor | + \*--------------------------------------------------------------*/ + zone(); + ~zone(); +}; /*------------------------------------------------------------------*\ | Device Types | @@ -210,6 +227,8 @@ class RGBControllerInterface public: virtual void SetupColors() = 0; + virtual unsigned int GetLEDsInZone(unsigned int zone) = 0; + virtual RGBColor GetLED(unsigned int led) = 0; virtual void SetLED(unsigned int led, RGBColor color) = 0; virtual void SetAllLEDs(RGBColor color) = 0; @@ -291,6 +310,8 @@ public: \*---------------------------------------------------------*/ void SetupColors(); + unsigned int GetLEDsInZone(unsigned int zone); + RGBColor GetLED(unsigned int led); void SetLED(unsigned int led, RGBColor color); void SetAllLEDs(RGBColor color); diff --git a/qt/DeviceView.cpp b/qt/DeviceView.cpp index 73d107f1..7d4497f6 100644 --- a/qt/DeviceView.cpp +++ b/qt/DeviceView.cpp @@ -305,7 +305,7 @@ void DeviceView::InitDeviceView() } else { - unsigned int count = controller->zones[zone_idx].leds_count; + unsigned int count = controller->GetLEDsInZone(zone_idx); zone_pos[zone_idx].matrix_w = std::min(count, (unsigned int)MAX_COLS); totalHeight += (count / MAX_COLS) + ((count % MAX_COLS) > 0); } @@ -473,7 +473,7 @@ void DeviceView::InitDeviceView() /*-----------------------------------------------------*\ | Calculate LED box positions for single/linear zones | \*-----------------------------------------------------*/ - unsigned int leds_count = controller->zones[zone_idx].leds_count; + unsigned int leds_count = controller->GetLEDsInZone(zone_idx); for(unsigned int led_idx = 0; led_idx < leds_count; led_idx++) { @@ -1033,7 +1033,7 @@ bool DeviceView::selectZone(int zone, bool add) int zoneStart = controller->zones[zone].start_idx; - for(int led_idx = 0; led_idx < (int)controller->zones[zone].leds_count; led_idx++) + for(int led_idx = 0; led_idx < controller->GetLEDsInZone(zone); led_idx++) { if(!selectionFlags[zoneStart + led_idx]) { diff --git a/qt/OpenRGBDevicePage/OpenRGBDevicePage.cpp b/qt/OpenRGBDevicePage/OpenRGBDevicePage.cpp index 63d33c99..f932478b 100644 --- a/qt/OpenRGBDevicePage/OpenRGBDevicePage.cpp +++ b/qt/OpenRGBDevicePage/OpenRGBDevicePage.cpp @@ -307,13 +307,15 @@ void Ui::OpenRGBDevicePage::on_ZoneBox_currentIndexChanged(int index) \*-----------------------------------------*/ else if(selected_zone != -1 && selected_segment == -1) { + unsigned int leds_in_zone = device->GetLEDsInZone(selected_zone); + /*-------------------------------------*\ | If there are multiple LEDs, add the | | "Entire Zone" option to the LED box | | and enable it, otherwise there is | | only one LED so disable it | \*-------------------------------------*/ - if(device->zones[selected_zone].leds_count > 1) + if(leds_in_zone > 1) { ui->LEDBox->addItem(tr("Entire Zone")); ui->LEDBox->setEnabled(1); @@ -327,7 +329,7 @@ void Ui::OpenRGBDevicePage::on_ZoneBox_currentIndexChanged(int index) | Fill in the LED list with all LEDs in | | the zone | \*-------------------------------------*/ - for(std::size_t led_idx = 0; led_idx < device->zones[selected_zone].leds_count; led_idx++) + for(std::size_t led_idx = 0; led_idx < leds_in_zone; led_idx++) { ui->LEDBox->addItem(device->zones[selected_zone].leds[led_idx].name.c_str()); } @@ -591,9 +593,9 @@ void Ui::OpenRGBDevicePage::on_LEDBox_currentIndexChanged(int index) /*-------------------------------------*\ | Handle single selected LED | \*-------------------------------------*/ - if(device->zones[selected_zone].leds_count == 1 || selected_led != -1) + if(device->GetLEDsInZone(selected_zone) == 1 || selected_led != -1) { - if((unsigned int)selected_led < device->zones[selected_zone].leds_count) + if((unsigned int)selected_led < device->GetLEDsInZone(selected_zone)) { /*-----------------------------*\ | Get selected LED's current | @@ -1624,9 +1626,10 @@ void Ui::OpenRGBDevicePage::on_EditZoneButton_clicked() } /*-----------------------------------------*\ - | Only allow resizing linear zones | + | Only allow resizing linear zones or | + | effects-only resizable zones | \*-----------------------------------------*/ - if(device->zones[selected_zone].type == ZONE_TYPE_LINEAR) + if((device->zones[selected_zone].type == ZONE_TYPE_LINEAR) || (device->zones[selected_zone].flags & ZONE_FLAG_RESIZE_EFFECTS_ONLY)) { OpenRGBZoneResizeDialog dlg(device, selected_zone);