5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
23 #define RECT_OFFSET 80
26 #define COLUMN_SIZE 200
31 #define LEG_COLORBOX 15
33 #define VIEW_CHANNELS_LIMIT_PCT (g_model.extendedLimits ? LIMIT_EXT_PERCENT : 100)
35 bool menuChannelsMonitor(event_t event
, uint8_t page
);
36 bool menuLogicalSwitches(event_t
);
39 bool menuChannelsMonitor(event_t event
)
41 lastMonitorPage
= e_MonChannelsFirst
+ index
;
42 MENU(STR_MONITOR_CHANNELS
[index
], MONITOR_ICONS
, menuTabMonitors
, lastMonitorPage
, 0, { 0 });
43 return menuChannelsMonitor(event
, index
);
46 const MenuHandlerFunc menuTabMonitors
[] PROGMEM
= {
47 menuChannelsMonitor
<0>,
48 menuChannelsMonitor
<1>,
49 menuChannelsMonitor
<2>,
50 menuChannelsMonitor
<3>,
54 uint8_t lastMonitorPage
= 0;
56 uint16_t posOnBar(int16_t value_to100
)
58 return divRoundClosest((value_to100
+ VIEW_CHANNELS_LIMIT_PCT
) * COLUMN_SIZE
, VIEW_CHANNELS_LIMIT_PCT
* 2);
61 void drawOutputBarLimits(coord_t left
, coord_t right
, coord_t y
)
63 lcd
->drawSolidVerticalLine(left
, y
, BAR_HEIGHT
, TEXT_COLOR
);
64 lcd
->drawSolidHorizontalLine(left
, y
, 3, TEXT_COLOR
);
65 lcd
->drawSolidHorizontalLine(left
, y
+ BAR_HEIGHT
- 1, 3, TEXT_COLOR
);
67 lcd
->drawSolidVerticalLine(--right
, y
, BAR_HEIGHT
, TEXT_COLOR
);
68 lcd
->drawSolidHorizontalLine(right
- 3, y
, 3, TEXT_COLOR
);
69 lcd
->drawSolidHorizontalLine(right
- 3, y
+ BAR_HEIGHT
- 1, 3, TEXT_COLOR
);
72 void drawSingleMixerBar(coord_t x
, coord_t y
, coord_t w
, coord_t h
, uint8_t channel
)
74 int16_t chanVal
= calcRESXto100(ex_chans
[channel
]);
75 const int16_t displayVal
= chanVal
;
77 // this could be handled nicer, but slower, by checking actual range for this mixer
78 chanVal
= limit
<int16_t>(-VIEW_CHANNELS_LIMIT_PCT
, chanVal
, VIEW_CHANNELS_LIMIT_PCT
);
80 lcdDrawSolidFilledRect(x
, y
, w
, h
, BARGRAPH_BGCOLOR
);
82 lcdDrawSolidFilledRect(x
+ w
/ 2, y
, divRoundClosest(chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2), h
, BARGRAPH2_COLOR
);
83 lcdDrawNumber(x
- 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, "%");
85 else if (chanVal
< 0) {
86 const uint16_t endpoint
= x
+ w
/ 2;
87 const uint16_t size
= divRoundClosest(-chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2);
88 lcdDrawSolidFilledRect(endpoint
- size
, y
, size
, h
, BARGRAPH2_COLOR
);
89 lcdDrawNumber(x
+ 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
, 0, NULL
, "%");
92 lcd
->drawSolidVerticalLine(x
+ w
/ 2, y
, h
, TEXT_COLOR
);
95 void drawSingleOutputBar(coord_t x
, coord_t y
, coord_t w
, coord_t h
, uint8_t channel
)
97 int16_t chanVal
= calcRESXto100(channelOutputs
[channel
]);
98 int16_t displayVal
= chanVal
;
100 chanVal
= limit
<int16_t>(-VIEW_CHANNELS_LIMIT_PCT
, chanVal
, VIEW_CHANNELS_LIMIT_PCT
);
102 lcdDrawSolidFilledRect(x
, y
, w
, h
, BARGRAPH_BGCOLOR
);
104 lcdDrawSolidFilledRect(x
+ w
/ 2, y
, divRoundClosest(chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2), h
, BARGRAPH1_COLOR
);
105 lcdDrawNumber(x
- 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, "%");
107 else if (chanVal
< 0) {
108 uint16_t endpoint
= x
+ w
/ 2;
109 uint16_t size
= divRoundClosest(-chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2);
110 lcdDrawSolidFilledRect(endpoint
- size
, y
, size
, h
, BARGRAPH1_COLOR
);
111 lcdDrawNumber(x
+ 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
, 0, NULL
, "%");
114 lcd
->drawSolidVerticalLine(x
+ w
/ 2, y
, h
, TEXT_COLOR
);
117 void drawComboOutputBar(coord_t x
, coord_t y
, coord_t w
, coord_t h
, uint8_t channel
)
119 char chanString
[] = "Ch32 ";
120 int16_t chanVal
= calcRESXto100(channelOutputs
[channel
]);
121 LimitData
* ld
= limitAddress(channel
);
122 int usValue
= PPM_CH_CENTER(channel
) + channelOutputs
[channel
] / 2;
123 const uint16_t limPos
= ld
? posOnBar(calcRESXto100((ld
&& ld
->revert
) ? -ld
->offset
: ld
->offset
)) : 0;
126 strAppendSigned(&chanString
[2], channel
+ 1, 2);
127 lcdDrawText(x
, y
, chanString
, SMLSIZE
| TEXT_COLOR
| LEFT
);
129 lcdDrawSizedText(x
+ 45, y
, g_model
.limitData
[channel
].name
, sizeof(g_model
.limitData
[channel
].name
), SMLSIZE
| TEXT_COLOR
| LEFT
| ZCHAR
);
130 lcdDrawNumber(x
+ w
, y
, usValue
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, STR_US
);
132 lcdDrawSolidFilledRect(x
, y
+ Y_OUTBAR
, w
, h
, BARGRAPH_BGCOLOR
);
133 lcd
->drawSolidVerticalLine(x
+ limPos
, y
+ Y_OUTBAR
, h
, MAINVIEW_GRAPHICS_COLOR
);
135 chanVal
= limit
<int16_t>(-VIEW_CHANNELS_LIMIT_PCT
, chanVal
, VIEW_CHANNELS_LIMIT_PCT
);
136 valPos
= posOnBar(chanVal
);
138 if (valPos
> limPos
) {
139 lcdDrawSolidFilledRect(x
+ limPos
, y
+ Y_OUTBAR
, valPos
- limPos
, h
, BARGRAPH1_COLOR
);
141 else if (valPos
< limPos
) {
142 uint16_t endpoint
= x
+ limPos
;
143 uint16_t size
= limPos
- valPos
;
144 lcdDrawSolidFilledRect(endpoint
- size
, y
+ Y_OUTBAR
, size
, h
, BARGRAPH1_COLOR
);
147 if (ld
&& ld
->revert
) {
148 drawOutputBarLimits(x
+ posOnBar(-100 - ld
->max
/ 10), x
+ posOnBar(100 - ld
->min
/ 10), y
+ Y_OUTBAR
);
149 lcd
->drawBitmap(x
- X_OFFSET
+ 7, y
+ 25, chanMonInvertedBitmap
);
152 drawOutputBarLimits(x
+ posOnBar(-100 + ld
->min
/ 10), x
+ posOnBar(100 + ld
->max
/ 10), y
+ Y_OUTBAR
);
154 #if defined(OVERRIDE_CHANNEL_FUNCTION)
155 if (safetyCh
[channel
] != OVERRIDE_CHANNEL_UNDEFINED
)
156 lcd
->drawBitmap(x
- X_OFFSET
+ 7, y
+ 7, chanMonLockedBitmap
);
158 lcd
->drawSolidVerticalLine(x
+ w
/ 2, y
+ Y_OUTBAR
, h
, TEXT_COLOR
);
159 if (chanVal
> calcRESXto100((ld
&& ld
->revert
) ? -ld
->offset
: ld
->offset
))
160 lcdDrawNumber(x
+ limPos
, y
+ h
, chanVal
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, "%");
162 lcdDrawNumber(x
+ limPos
, y
+ h
, chanVal
, SMLSIZE
| TEXT_COLOR
, 0, NULL
, "%");
165 coord_t
drawChannelsMonitorLegend(coord_t x
, const pm_char
* s
, int color
)
167 lcdDrawSolidFilledRect(x
, MENU_FOOTER_TOP
+ 2, LEG_COLORBOX
+ 2, LEG_COLORBOX
+ 2, BARGRAPH_BGCOLOR
);
168 lcdDrawSolidFilledRect(x
+ 1, MENU_FOOTER_TOP
+ 3, LEG_COLORBOX
, LEG_COLORBOX
, color
);
169 lcdDrawText(x
+ 20, MENU_FOOTER_TOP
, s
, TEXT_STATUSBAR_COLOR
);
170 return x
+ 25 + getTextWidth(s
);
173 bool menuChannelsMonitor(event_t event
, uint8_t page
)
175 uint8_t channel
= 8 * page
;
176 coord_t x
, y
= Y_OFFSET
;
178 x
= drawChannelsMonitorLegend(MENUS_MARGIN_LEFT
, STR_MONITOR_OUTPUT_DESC
, BARGRAPH1_COLOR
);
179 drawChannelsMonitorLegend(x
, STR_MONITOR_MIXER_DESC
, BARGRAPH2_COLOR
);
182 for (uint8_t i
= 0; i
< 8; i
++, channel
++, y
+= ROW_HEIGHT
) {
184 x
= 1 + LCD_W
/ 2 + X_OFFSET
;
187 drawComboOutputBar(x
, y
, COLUMN_SIZE
, BAR_HEIGHT
, channel
);
188 drawSingleMixerBar(x
, y
+ Y_MIXBAR
+ 1, COLUMN_SIZE
, BAR_HEIGHT
, channel
);