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.
25 #define COLUMN_SIZE 200
30 #define LEG_COLORBOX 15
32 #define VIEW_CHANNELS_LIMIT_PCT (g_model.extendedLimits ? LIMIT_EXT_PERCENT : 100)
34 bool menuChannelsMonitor(event_t event
, uint8_t page
);
35 bool menuLogicalSwitches(event_t
);
38 bool menuChannelsMonitor(event_t event
)
40 lastMonitorPage
= e_MonChannelsFirst
+ index
;
41 MENU(STR_MONITOR_CHANNELS
[index
], MONITOR_ICONS
, menuTabMonitors
, lastMonitorPage
, 0, { 0 });
42 return menuChannelsMonitor(event
, index
);
45 const MenuHandlerFunc menuTabMonitors
[] = {
46 menuChannelsMonitor
<0>,
47 menuChannelsMonitor
<1>,
48 menuChannelsMonitor
<2>,
49 menuChannelsMonitor
<3>,
53 uint8_t lastMonitorPage
= 0;
55 uint16_t posOnBar(int16_t value_to100
)
57 return divRoundClosest((value_to100
+ VIEW_CHANNELS_LIMIT_PCT
) * COLUMN_SIZE
, VIEW_CHANNELS_LIMIT_PCT
* 2);
60 void drawOutputBarLimits(coord_t left
, coord_t right
, coord_t y
)
62 lcd
->drawSolidVerticalLine(left
, y
, BAR_HEIGHT
, TEXT_COLOR
);
63 lcd
->drawSolidHorizontalLine(left
, y
, 3, TEXT_COLOR
);
64 lcd
->drawSolidHorizontalLine(left
, y
+ BAR_HEIGHT
- 1, 3, TEXT_COLOR
);
66 lcd
->drawSolidVerticalLine(--right
, y
, BAR_HEIGHT
, TEXT_COLOR
);
67 lcd
->drawSolidHorizontalLine(right
- 3, y
, 3, TEXT_COLOR
);
68 lcd
->drawSolidHorizontalLine(right
- 3, y
+ BAR_HEIGHT
- 1, 3, TEXT_COLOR
);
71 void drawSingleMixerBar(coord_t x
, coord_t y
, coord_t w
, coord_t h
, uint8_t channel
)
73 int16_t chanVal
= calcRESXto100(ex_chans
[channel
]);
74 const int16_t displayVal
= chanVal
;
76 // this could be handled nicer, but slower, by checking actual range for this mixer
77 chanVal
= limit
<int16_t>(-VIEW_CHANNELS_LIMIT_PCT
, chanVal
, VIEW_CHANNELS_LIMIT_PCT
);
79 lcdDrawSolidFilledRect(x
, y
, w
, h
, BARGRAPH_BGCOLOR
);
81 lcdDrawSolidFilledRect(x
+ w
/ 2, y
, divRoundClosest(chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2), h
, BARGRAPH2_COLOR
);
82 lcdDrawNumber(x
- 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, "%");
84 else if (chanVal
< 0) {
85 const uint16_t endpoint
= x
+ w
/ 2;
86 const uint16_t size
= divRoundClosest(-chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2);
87 lcdDrawSolidFilledRect(endpoint
- size
, y
, size
, h
, BARGRAPH2_COLOR
);
88 lcdDrawNumber(x
+ 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
, 0, NULL
, "%");
91 lcd
->drawSolidVerticalLine(x
+ w
/ 2, y
, h
, TEXT_COLOR
);
94 void drawSingleOutputBar(coord_t x
, coord_t y
, coord_t w
, coord_t h
, uint8_t channel
)
96 int16_t chanVal
= calcRESXto100(channelOutputs
[channel
]);
97 int16_t displayVal
= chanVal
;
99 chanVal
= limit
<int16_t>(-VIEW_CHANNELS_LIMIT_PCT
, chanVal
, VIEW_CHANNELS_LIMIT_PCT
);
101 lcdDrawSolidFilledRect(x
, y
, w
, h
, BARGRAPH_BGCOLOR
);
103 lcdDrawSolidFilledRect(x
+ w
/ 2, y
, divRoundClosest(chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2), h
, BARGRAPH1_COLOR
);
104 lcdDrawNumber(x
- 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, "%");
106 else if (chanVal
< 0) {
107 uint16_t endpoint
= x
+ w
/ 2;
108 uint16_t size
= divRoundClosest(-chanVal
* w
, VIEW_CHANNELS_LIMIT_PCT
* 2);
109 lcdDrawSolidFilledRect(endpoint
- size
, y
, size
, h
, BARGRAPH1_COLOR
);
110 lcdDrawNumber(x
+ 10 + w
/ 2, y
- 2, displayVal
, SMLSIZE
| TEXT_COLOR
, 0, NULL
, "%");
113 lcd
->drawSolidVerticalLine(x
+ w
/ 2, y
, h
, TEXT_COLOR
);
116 void drawComboOutputBar(coord_t x
, coord_t y
, coord_t w
, coord_t h
, uint8_t channel
)
118 char chanString
[] = "Ch32 ";
119 int16_t chanVal
= calcRESXto100(channelOutputs
[channel
]);
120 LimitData
* ld
= limitAddress(channel
);
121 int usValue
= PPM_CH_CENTER(channel
) + channelOutputs
[channel
] / 2;
122 const uint16_t limPos
= ld
? posOnBar(calcRESXto100((ld
&& ld
->revert
) ? -ld
->offset
: ld
->offset
)) : 0;
125 strAppendSigned(&chanString
[2], channel
+ 1, 2);
126 lcdDrawText(x
, y
, chanString
, SMLSIZE
| TEXT_COLOR
| LEFT
);
128 lcdDrawSizedText(x
+ 45, y
, g_model
.limitData
[channel
].name
, sizeof(g_model
.limitData
[channel
].name
), SMLSIZE
| TEXT_COLOR
| LEFT
| ZCHAR
);
129 lcdDrawNumber(x
+ w
, y
, usValue
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, STR_US
);
131 lcdDrawSolidFilledRect(x
, y
+ Y_OUTBAR
, w
, h
, BARGRAPH_BGCOLOR
);
132 lcd
->drawSolidVerticalLine(x
+ limPos
, y
+ Y_OUTBAR
, h
, MAINVIEW_GRAPHICS_COLOR
);
134 chanVal
= limit
<int16_t>(-VIEW_CHANNELS_LIMIT_PCT
, chanVal
, VIEW_CHANNELS_LIMIT_PCT
);
135 valPos
= posOnBar(chanVal
);
137 if (valPos
> limPos
) {
138 lcdDrawSolidFilledRect(x
+ limPos
, y
+ Y_OUTBAR
, valPos
- limPos
, h
, BARGRAPH1_COLOR
);
140 else if (valPos
< limPos
) {
141 uint16_t endpoint
= x
+ limPos
;
142 uint16_t size
= limPos
- valPos
;
143 lcdDrawSolidFilledRect(endpoint
- size
, y
+ Y_OUTBAR
, size
, h
, BARGRAPH1_COLOR
);
146 if (ld
&& ld
->revert
) {
147 drawOutputBarLimits(x
+ posOnBar(-100 - ld
->max
/ 10), x
+ posOnBar(100 - ld
->min
/ 10), y
+ Y_OUTBAR
);
148 lcd
->drawBitmap(x
- X_OFFSET
+ 7, y
+ 25, chanMonInvertedBitmap
);
151 drawOutputBarLimits(x
+ posOnBar(-100 + ld
->min
/ 10), x
+ posOnBar(100 + ld
->max
/ 10), y
+ Y_OUTBAR
);
153 #if defined(OVERRIDE_CHANNEL_FUNCTION)
154 if (safetyCh
[channel
] != OVERRIDE_CHANNEL_UNDEFINED
)
155 lcd
->drawBitmap(x
- X_OFFSET
+ 7, y
+ 7, chanMonLockedBitmap
);
157 lcd
->drawSolidVerticalLine(x
+ w
/ 2, y
+ Y_OUTBAR
, h
, TEXT_COLOR
);
158 if (chanVal
> calcRESXto100((ld
&& ld
->revert
) ? -ld
->offset
: ld
->offset
))
159 lcdDrawNumber(x
+ limPos
, y
+ h
, chanVal
, SMLSIZE
| TEXT_COLOR
| RIGHT
, 0, NULL
, "%");
161 lcdDrawNumber(x
+ limPos
, y
+ h
, chanVal
, SMLSIZE
| TEXT_COLOR
, 0, NULL
, "%");
164 coord_t
drawChannelsMonitorLegend(coord_t x
, const char * s
, int color
)
166 lcdDrawSolidFilledRect(x
, MENU_FOOTER_TOP
+ 2, LEG_COLORBOX
+ 2, LEG_COLORBOX
+ 2, BARGRAPH_BGCOLOR
);
167 lcdDrawSolidFilledRect(x
+ 1, MENU_FOOTER_TOP
+ 3, LEG_COLORBOX
, LEG_COLORBOX
, color
);
168 lcdDrawText(x
+ 20, MENU_FOOTER_TOP
, s
, TEXT_STATUSBAR_COLOR
);
169 return x
+ 25 + getTextWidth(s
);
172 bool menuChannelsMonitor(event_t event
, uint8_t page
)
174 uint8_t channel
= 8 * page
;
175 coord_t x
, y
= Y_OFFSET
;
177 x
= drawChannelsMonitorLegend(MENUS_MARGIN_LEFT
, STR_MONITOR_OUTPUT_DESC
, BARGRAPH1_COLOR
);
178 drawChannelsMonitorLegend(x
, STR_MONITOR_MIXER_DESC
, BARGRAPH2_COLOR
);
181 for (uint8_t i
= 0; i
< 8; i
++, channel
++, y
+= ROW_HEIGHT
) {
183 x
= 1 + LCD_W
/ 2 + X_OFFSET
;
186 drawComboOutputBar(x
, y
, COLUMN_SIZE
, BAR_HEIGHT
, channel
);
187 drawSingleMixerBar(x
, y
+ Y_MIXBAR
+ 1, COLUMN_SIZE
, BAR_HEIGHT
, channel
);