u8g2_button.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. u8g2_button.c
  3. Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
  4. Copyright (c) 2016, olikraus@gmail.com
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without modification,
  7. are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice, this list
  9. of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright notice, this
  11. list of conditions and the following disclaimer in the documentation and/or other
  12. materials provided with the distribution.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  14. CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  15. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  16. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  18. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  23. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  25. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "u8g2.h"
  28. /*
  29. Description:
  30. Draws normal or inverted text with optional frame around text.
  31. The text (and the frame) can be horizontally centered around the provided reference position.
  32. This procedure will use the current draw color and current font. The height of the frame
  33. depends on the setting of setFontRefHeightText(), setFontRefHeightExtendedText() or setFontRefHeightAll()
  34. Note 1: drawColor 2 (XOR) is not supported. Result will be broken with draw color 2.
  35. Note 2: This procedure will enforce font mode 1 (transparent mode)
  36. Note 3: Some fonts may add an extra gap on the right side. This is a font problem and can not be avoided (for example inb16 has this problem).
  37. The height of the button is defined by the current font and
  38. setFontRefHeightText,
  39. setFontRefHeightExtendedText
  40. setFontRefHeightAll
  41. Right padding might be influenced by the font.
  42. For example u8g2_font_inb16 may add an extra pixel gap (increase padding by one)
  43. on the right side.
  44. The current draw color is considered, but only draw color 0 and 1 are supported
  45. This function requires transparent font mode: setFontMode(1)
  46. Side effect: Font transparent mode is enabled setFontMode(1)
  47. */
  48. /*
  49. flags:
  50. U8G2_BTN_BW1 0x01
  51. U8G2_BTN_BW2 0x02
  52. U8G2_BTN_BW3 0x03
  53. U8G2_BTN_SHADOW0 0x08
  54. U8G2_BTN_SHADOW1 0x10
  55. U8G2_BTN_SHADOW2 0x18
  56. U8G2_BTN_INV 0x20
  57. U8G2_BTN_HCENTER 0x40
  58. U8G2_BTN_XFRAME 0x80
  59. Total size without shadow: width+2*padding_h+2*border
  60. Total size with U8G2_BTN_SHADOW0: width+2*padding_h+3*border
  61. Total size with U8G2_BTN_SHADOW1: width+2*padding_h+3*border+1
  62. Total size with U8G2_BTN_SHADOW2: width+2*padding_h+3*border+2
  63. U8G2_BTN_XFRAME:
  64. draw another one pixel frame with one pixel gap, will not look good with shadow
  65. */
  66. void u8g2_DrawButtonFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t text_width, u8g2_uint_t padding_h, u8g2_uint_t padding_v)
  67. {
  68. u8g2_uint_t w = text_width;
  69. u8g2_uint_t xx, yy, ww, hh;
  70. u8g2_uint_t gap_frame = U8G2_BTN_BW_MASK+1;
  71. u8g2_uint_t border_width = flags & U8G2_BTN_BW_MASK;
  72. int8_t a = u8g2_GetAscent(u8g2);
  73. int8_t d = u8g2_GetDescent(u8g2);
  74. uint8_t color_backup = u8g2->draw_color;
  75. if ( flags & U8G2_BTN_XFRAME )
  76. {
  77. border_width++;
  78. gap_frame = border_width;
  79. border_width++;
  80. }
  81. for(;;)
  82. {
  83. xx = x;
  84. xx -= padding_h;
  85. xx -= border_width;
  86. ww = w+2*padding_h+2*border_width;
  87. yy = y;
  88. yy += u8g2->font_calc_vref(u8g2);
  89. yy -= a;
  90. yy -= padding_v;
  91. yy -= border_width;
  92. hh = a-d+2*padding_v+2*border_width;
  93. if ( border_width == 0 )
  94. break;
  95. if ( border_width == gap_frame )
  96. {
  97. u8g2_SetDrawColor(u8g2, color_backup == 0 ? 1 : 0);
  98. }
  99. u8g2_DrawFrame(u8g2, xx, yy, ww, hh);
  100. u8g2_SetDrawColor(u8g2, color_backup);
  101. if ( flags & U8G2_BTN_SHADOW_MASK )
  102. {
  103. if ( border_width == (flags & U8G2_BTN_BW_MASK) )
  104. {
  105. u8g2_uint_t i;
  106. u8g2_uint_t shadow_gap = (flags & U8G2_BTN_SHADOW_MASK) >> U8G2_BTN_SHADOW_POS;
  107. shadow_gap--;
  108. for( i = 0; i < border_width; i++ )
  109. {
  110. u8g2_DrawHLine(u8g2, xx+border_width+shadow_gap,yy+hh+i+shadow_gap,ww);
  111. u8g2_DrawVLine(u8g2, xx+ww+i+shadow_gap,yy+border_width+shadow_gap,hh);
  112. }
  113. }
  114. }
  115. border_width--;
  116. } /* for */
  117. if ( flags & U8G2_BTN_INV )
  118. {
  119. u8g2_SetDrawColor(u8g2, 2); /* XOR */
  120. u8g2_DrawBox(u8g2, xx, yy, ww, hh);
  121. u8g2_SetDrawColor(u8g2, color_backup);
  122. }
  123. }
  124. void u8g2_DrawButtonUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text)
  125. {
  126. u8g2_uint_t w = u8g2_GetUTF8Width(u8g2, text);
  127. u8g2_uint_t text_x_offset = 0;
  128. if ( flags & U8G2_BTN_HCENTER )
  129. x -= (w+1)/2;
  130. if ( w < width )
  131. {
  132. if ( flags & U8G2_BTN_HCENTER )
  133. {
  134. text_x_offset = (width-w)/2;
  135. }
  136. w = width;
  137. }
  138. u8g2_SetFontMode(u8g2, 1);
  139. u8g2_DrawUTF8(u8g2, x,y, text);
  140. u8g2_DrawButtonFrame(u8g2, x-text_x_offset, y, flags, w, padding_h, padding_v);
  141. }
  142. #ifdef NOT_USED
  143. void u8g2_Draw4Pixel(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w)
  144. {
  145. u8g2_DrawPixel(u8g2, x,y-1);
  146. u8g2_DrawPixel(u8g2, x+w-1,y-1);
  147. u8g2_DrawPixel(u8g2, x+w-1,y-w);
  148. u8g2_DrawPixel(u8g2, x,y-w);
  149. }
  150. void u8g2_DrawRadio(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t is_checked)
  151. {
  152. uint8_t color_backup = u8g2->draw_color;
  153. u8g2_DrawCheckbox(u8g2, x,y,w,is_checked);
  154. u8g2_SetDrawColor(u8g2, 2);
  155. u8g2_Draw4Pixel(u8g2, x,y,w);
  156. if ( is_checked )
  157. {
  158. //u8g2_Draw4Pixel(u8g2, x+2,y-2,w-4);
  159. }
  160. u8g2_SetDrawColor(u8g2, color_backup );
  161. }
  162. #endif
  163. #ifdef _THIS_CODE_SHOULD_BE_REWRITTEN_WITHOUT_PADWIDTH_
  164. /*
  165. Shadow is not supported
  166. Note: radius must be at least as high as the border width
  167. border width | good radius values
  168. 1 | 3, 5, 7, 8, ...
  169. 2 | 3, 5, 7, 8, ...
  170. */
  171. void u8g2_DrawRButtonUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t padding_h_or_width, u8g2_uint_t padding_v, u8g2_uint_t r, const char *text)
  172. {
  173. u8g2_uint_t w = u8g2_GetUTF8Width(u8g2, text);
  174. //u8g2_uint_t w = u8g2_GetExactStrWidth(u8g2, text);
  175. u8g2_uint_t xx, yy, ww, hh;
  176. u8g2_uint_t border_width = flags & U8G2_BTN_BW_MASK;
  177. u8g2_uint_t padding_h = padding_h_or_width;
  178. u8g2_uint_t text_x_offset = 0; // used for U8G2_BTN_PADWIDTH mode
  179. int8_t a = u8g2_GetAscent(u8g2);
  180. int8_t d = u8g2_GetDescent(u8g2);
  181. uint8_t color_backup = u8g2->draw_color;
  182. if ( flags & U8G2_BTN_HCENTER )
  183. x -= w/2;
  184. if ( flags & U8G2_BTN_PADWIDTH )
  185. {
  186. padding_h = 0;
  187. if ( w < padding_h_or_width )
  188. {
  189. if ( flags & U8G2_BTN_HCENTER )
  190. {
  191. text_x_offset = (padding_h_or_width-w)/2;
  192. }
  193. w = padding_h_or_width;
  194. }
  195. }
  196. u8g2_SetFontMode(u8g2, 1);
  197. for(;;)
  198. {
  199. if ( padding_h >= u8g2_GetDisplayWidth(u8g2)/2 ) // padding_h is zero if U8G2_BTN_PADWIDTH is set
  200. {
  201. xx = (flags & U8G2_BTN_BW_MASK) - border_width;
  202. ww = u8g2_GetDisplayWidth(u8g2);
  203. ww -= 2*((flags & U8G2_BTN_BW_MASK) - border_width);
  204. //printf("xx=%d ww=%d\n", xx, ww);
  205. //printf("clip_x1=%d clip_x0=%d\n", u8g2->clip_x1, u8g2->clip_x0);
  206. }
  207. else
  208. {
  209. xx = x;
  210. xx -= text_x_offset;
  211. xx -= padding_h;
  212. xx -= border_width;
  213. ww = w+2*padding_h+2*border_width;
  214. }
  215. yy = y;
  216. yy += u8g2->font_calc_vref(u8g2);
  217. yy -= a;
  218. yy -= padding_v;
  219. yy -= border_width;
  220. hh = a-d+2*padding_v+2*border_width;
  221. if ( border_width == 0 )
  222. break;
  223. u8g2_DrawRFrame(u8g2, xx, yy, ww, hh, r);
  224. if ( (flags & U8G2_BTN_BW_MASK) > 1 )
  225. u8g2_DrawRFrame(u8g2, xx, yy, ww, hh, r+1);
  226. border_width--;
  227. if ( r > 1 )
  228. r--;
  229. }
  230. if ( flags & U8G2_BTN_INV )
  231. {
  232. u8g2_DrawRBox(u8g2, xx, yy, ww, hh,r);
  233. u8g2_SetDrawColor(u8g2, 1-u8g2->draw_color);
  234. }
  235. u8g2_DrawUTF8(u8g2, x,y, text);
  236. u8g2_SetDrawColor(u8g2, color_backup);
  237. }
  238. #endif