BUG: PointAndZone.cpp -> Zone::rotate()
In the calculation of inv_x and inv_y, TFT_WIDTH and TFT_HEIGHT must be interchanged according to the rotation of the screen. Otherwise, the resulting coordinates of the Zone :: rotate () function are wrong and do not correspond to the physical locations of buttons A, B, and C.
Demonstration:
M5.Lcd.setRotation(2);
...
BtnA(10,240,110,40..);
Inside Zone :: rotate ():
inv_x = TFT_WIDTH - 1 - x - w (= 240 - 1 - 10 - 110 = 119 -> Wrong!!)
...
switch (m) {
...
case 2:
x = normal_y;
y = inv_x;
break;
...
The zone corresponding to button A would have the coordinates (240,119,280,229), overlapping with the real button B (240,130,280,200).
Correct value:
When the rotation is 2, the screen has a resolution of 240(280)x320 in the rotated x and y directions, so:
inv_x = TFT_WIDTH - 1 - x - w (= 320 - 1 - 10 - 110 = 199 - > Correct !!)
Fixed function:
void Zone::rotate(uint8_t m) {
if (m == 1) return;
int16_t tftW = TFT_WIDTH;
int16_t tftH = TFT_HEIGHT;
switch (m) {
case 0:
tftW = TFT_HEIGHT;
tftH = TFT_WIDTH;
break;
case 2:
tftW = TFT_HEIGHT;
tftH = TFT_WIDTH;
break;
case 3:
tftW = TFT_WIDTH;
tftH = TFT_HEIGHT;
break;
// rotations 4-7 are mirrored
case 4:
tftW = TFT_HEIGHT;
tftH = TFT_WIDTH;
break;
case 5:
tftW = TFT_WIDTH;
tftH = TFT_HEIGHT;
break;
case 6:
tftW = TFT_HEIGHT;
tftH = TFT_WIDTH;
break;
case 7:
tftW = TFT_WIDTH;
tftH = TFT_HEIGHT;
break;
}
int16_t normal_x = x;
int16_t normal_y = y;
int16_t inv_x = tftW - 1 - x - w;
int16_t inv_y = tftH - 1 - y - h;
...
There are no changes from this line to the end of the function.
Thx a lot for this issue. It helped me to find out, why my M5Stack Core2 didn't work properly with rotation. But in the section "case 3" is still a mistake.
The right variables are the following:
case 3:
tftW = TFT_HEIGHT;
tftH = TFT_WIDTH;
break;
Then it works as expected: The buttons (aka the small red circles) are on the top and they react now.