QBPlasticPopupMenu.m 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. //
  2. // QBPlasticPopupMenu.m
  3. // QBPopupMenu
  4. //
  5. // Created by Tanaka Katsuma on 2013/11/25.
  6. // Copyright (c) 2013年 Katsuma Tanaka. All rights reserved.
  7. //
  8. #import "QBPlasticPopupMenu.h"
  9. @implementation QBPlasticPopupMenu
  10. #pragma mark - Creating Paths
  11. - (CGMutablePathRef)upperHeadPathInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
  12. {
  13. CGMutablePathRef path = CGPathCreateMutable();
  14. CGPathMoveToPoint(path, NULL, rect.origin.x, rect.origin.y + cornerRadius);
  15. CGPathAddArcToPoint(path, NULL, rect.origin.x, rect.origin.y, rect.origin.x + cornerRadius, rect.origin.y, cornerRadius);
  16. CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y);
  17. CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
  18. CGPathAddLineToPoint(path, NULL, rect.origin.x, rect.origin.y + rect.size.height);
  19. CGPathCloseSubpath(path);
  20. return path;
  21. }
  22. - (CGMutablePathRef)lowerHeadPathInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
  23. {
  24. CGMutablePathRef path = CGPathCreateMutable();
  25. CGPathMoveToPoint(path, NULL, rect.origin.x, rect.origin.y);
  26. CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y);
  27. CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
  28. CGPathAddLineToPoint(path, NULL, rect.origin.x + cornerRadius, rect.origin.y + rect.size.height);
  29. CGPathAddArcToPoint(path, NULL, rect.origin.x, rect.origin.y + rect.size.height, rect.origin.x, rect.origin.y + rect.size.height - cornerRadius, cornerRadius);
  30. CGPathCloseSubpath(path);
  31. return path;
  32. }
  33. - (CGMutablePathRef)upperTailPathInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
  34. {
  35. CGMutablePathRef path = CGPathCreateMutable();
  36. CGPathMoveToPoint(path, NULL, rect.origin.x, rect.origin.y);
  37. CGPathMoveToPoint(path, NULL, rect.origin.x + rect.size.width - cornerRadius, rect.origin.y);
  38. CGPathAddArcToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y, rect.origin.x + rect.size.width, rect.origin.y + cornerRadius, cornerRadius);
  39. CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
  40. CGPathAddLineToPoint(path, NULL, rect.origin.x, rect.origin.y + rect.size.height);
  41. CGPathCloseSubpath(path);
  42. return path;
  43. }
  44. - (CGMutablePathRef)lowerTailPathInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
  45. {
  46. CGMutablePathRef path = CGPathCreateMutable();
  47. CGPathMoveToPoint(path, NULL, rect.origin.x, rect.origin.y);
  48. CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y);
  49. CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - cornerRadius);
  50. CGPathAddArcToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, rect.origin.x + rect.size.width - cornerRadius, rect.origin.y + rect.size.height, cornerRadius);
  51. CGPathAddLineToPoint(path, NULL, rect.origin.x, rect.origin.y + rect.size.height);
  52. CGPathCloseSubpath(path);
  53. return path;
  54. }
  55. #pragma mark - Drawing Popup Menu Image
  56. - (void)drawArrowInRect:(CGRect)rect direction:(QBPopupMenuArrowDirection)direction highlighted:(BOOL)highlighted
  57. {
  58. CGContextRef context = UIGraphicsGetCurrentContext();
  59. // Border
  60. CGContextSaveGState(context); {
  61. CGRect arrowRect = CGRectZero;
  62. switch (direction) {
  63. case QBPopupMenuArrowDirectionDown:
  64. arrowRect = CGRectMake(rect.origin.x, rect.origin.y - 0.6, rect.size.width, rect.size.height);
  65. break;
  66. case QBPopupMenuArrowDirectionUp:
  67. arrowRect = CGRectMake(rect.origin.x, rect.origin.y + 0.6, rect.size.width, rect.size.height);
  68. break;
  69. case QBPopupMenuArrowDirectionLeft:
  70. arrowRect = CGRectMake(rect.origin.x + 0.6, rect.origin.y - 0.5, rect.size.width, rect.size.height);
  71. break;
  72. case QBPopupMenuArrowDirectionRight:
  73. arrowRect = CGRectMake(rect.origin.x - 0.6, rect.origin.y - 0.5, rect.size.width, rect.size.height);
  74. break;
  75. default:
  76. break;
  77. }
  78. CGMutablePathRef path = [self arrowPathInRect:arrowRect direction:direction];
  79. CGContextAddPath(context, path);
  80. CGContextSetRGBFillColor(context, 0, 0, 0, 1.0);
  81. CGContextFillPath(context);
  82. CGPathRelease(path);
  83. } CGContextRestoreGState(context);
  84. // Highlight
  85. CGContextSaveGState(context); {
  86. CGRect arrowRect = CGRectZero;
  87. switch (direction) {
  88. case QBPopupMenuArrowDirectionUp:
  89. arrowRect = CGRectMake(rect.origin.x, rect.origin.y + 2, rect.size.width, rect.size.height);
  90. break;
  91. case QBPopupMenuArrowDirectionLeft:
  92. arrowRect = CGRectMake(rect.origin.x + 2, rect.origin.y - 0.5 + 1, rect.size.width - 1, rect.size.height - 2);
  93. break;
  94. case QBPopupMenuArrowDirectionRight:
  95. arrowRect = CGRectMake(rect.origin.x - 1, rect.origin.y - 0.5 + 1, rect.size.width - 1, rect.size.height - 2);
  96. break;
  97. default:
  98. break;
  99. }
  100. CGMutablePathRef path = [self arrowPathInRect:arrowRect direction:direction];
  101. CGContextAddPath(context, path);
  102. if (highlighted) {
  103. CGContextSetRGBFillColor(context, 0.384, 0.608, 0.906, 1.0);
  104. } else {
  105. CGContextSetRGBFillColor(context, 0.471, 0.471, 0.471, 1.0);
  106. }
  107. CGContextFillPath(context);
  108. CGPathRelease(path);
  109. } CGContextRestoreGState(context);
  110. // Body
  111. CGContextSaveGState(context); {
  112. switch (direction) {
  113. case QBPopupMenuArrowDirectionDown:
  114. {
  115. if (highlighted) {
  116. CGMutablePathRef path = [self arrowPathInRect:CGRectMake(rect.origin.x, rect.origin.y - 2, rect.size.width, rect.size.height) direction:direction];
  117. CGContextAddPath(context, path);
  118. CGContextClip(context);
  119. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  120. CGFloat components[8];
  121. components[0] = 0.027; components[1] = 0.169; components[2] = 0.733; components[3] = 1;
  122. components[4] = 0.020; components[5] = 0.114; components[6] = 0.675; components[7] = 1;
  123. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  124. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y - 2);
  125. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
  126. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  127. CGGradientRelease(gradient);
  128. CGColorSpaceRelease(colorSpace);
  129. CGPathRelease(path);
  130. }
  131. }
  132. break;
  133. case QBPopupMenuArrowDirectionUp:
  134. {
  135. CGMutablePathRef path = [self arrowPathInRect:CGRectMake(rect.origin.x + 1.4, rect.origin.y + 2 + 1.4, rect.size.width - 2.8, rect.size.height - 1.4) direction:direction];
  136. CGContextAddPath(context, path);
  137. CGContextClip(context);
  138. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  139. CGFloat components[8];
  140. if (highlighted) {
  141. components[0] = 0.290; components[1] = 0.580; components[2] = 1.000; components[3] = 1;
  142. components[4] = 0.216; components[5] = 0.471; components[6] = 0.871; components[7] = 1;
  143. } else {
  144. components[0] = 0.401; components[1] = 0.401; components[2] = 0.401; components[3] = 1;
  145. components[4] = 0.314; components[5] = 0.314; components[6] = 0.314; components[7] = 1;
  146. }
  147. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  148. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y + 2);
  149. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
  150. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  151. CGGradientRelease(gradient);
  152. CGColorSpaceRelease(colorSpace);
  153. CGPathRelease(path);
  154. }
  155. break;
  156. case QBPopupMenuArrowDirectionLeft:
  157. {
  158. CGMutablePathRef path = [self arrowPathInRect:CGRectMake(rect.origin.x + 2, rect.origin.y - 0.5 + 2, rect.size.width - 1, rect.size.height - 2) direction:direction];
  159. CGContextAddPath(context, path);
  160. CGContextClip(context);
  161. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  162. CGFloat components[16];
  163. if (highlighted) {
  164. components[0] = 0.082; components[1] = 0.376; components[2] = 0.859; components[3] = 1;
  165. components[4] = 0.004; components[5] = 0.333; components[6] = 0.851; components[7] = 1;
  166. components[8] = 0.000; components[9] = 0.282; components[10] = 0.839; components[11] = 1;
  167. components[12] = 0.000; components[13] = 0.216; components[14] = 0.796; components[15] = 1;
  168. } else {
  169. components[0] = 0.216; components[1] = 0.216; components[2] = 0.216; components[3] = 1;
  170. components[4] = 0.165; components[5] = 0.165; components[6] = 0.165; components[7] = 1;
  171. components[8] = 0.102; components[9] = 0.102; components[10] = 0.102; components[11] = 1;
  172. components[12] = 0.051; components[13] = 0.051; components[14] = 0.051; components[15] = 1;
  173. }
  174. CGFloat locations[4] = { 0.0, 0.5, 0.5, 1.0 };
  175. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 4);
  176. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y - 1);
  177. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
  178. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  179. CGGradientRelease(gradient);
  180. CGColorSpaceRelease(colorSpace);
  181. CGPathRelease(path);
  182. }
  183. break;
  184. case QBPopupMenuArrowDirectionRight:
  185. {
  186. CGMutablePathRef path = [self arrowPathInRect:CGRectMake(rect.origin.x - 1, rect.origin.y - 0.5 + 2, rect.size.width - 1, rect.size.height - 2) direction:direction];
  187. CGContextAddPath(context, path);
  188. CGContextClip(context);
  189. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  190. CGFloat components[16];
  191. if (highlighted) {
  192. components[0] = 0.082; components[1] = 0.376; components[2] = 0.859; components[3] = 1;
  193. components[4] = 0.004; components[5] = 0.333; components[6] = 0.851; components[7] = 1;
  194. components[8] = 0.000; components[9] = 0.282; components[10] = 0.839; components[11] = 1;
  195. components[12] = 0.000; components[13] = 0.216; components[14] = 0.796; components[15] = 1;
  196. } else {
  197. components[0] = 0.216; components[1] = 0.216; components[2] = 0.216; components[3] = 1;
  198. components[4] = 0.165; components[5] = 0.165; components[6] = 0.165; components[7] = 1;
  199. components[8] = 0.102; components[9] = 0.102; components[10] = 0.102; components[11] = 1;
  200. components[12] = 0.051; components[13] = 0.051; components[14] = 0.051; components[15] = 1;
  201. }
  202. CGFloat locations[4] = { 0.0, 0.5, 0.5, 1.0 };
  203. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 4);
  204. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y - 1);
  205. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
  206. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  207. CGGradientRelease(gradient);
  208. CGColorSpaceRelease(colorSpace);
  209. CGPathRelease(path);
  210. }
  211. break;
  212. default:
  213. break;
  214. }
  215. } CGContextRestoreGState(context);
  216. }
  217. - (void)drawHeadInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius highlighted:(BOOL)highlighted
  218. {
  219. CGContextRef context = UIGraphicsGetCurrentContext();
  220. // Border
  221. CGContextSaveGState(context); {
  222. CGMutablePathRef path = [self headPathInRect:rect cornerRadius:cornerRadius];
  223. CGContextAddPath(context, path);
  224. CGContextSetRGBFillColor(context, 0, 0, 0, 1.0);
  225. CGContextFillPath(context);
  226. CGPathRelease(path);
  227. } CGContextRestoreGState(context);
  228. // Highlight
  229. CGContextSaveGState(context); {
  230. CGMutablePathRef path = [self headPathInRect:CGRectMake(rect.origin.x + 1, rect.origin.y + 1, rect.size.width - 1, rect.size.height - 2)
  231. cornerRadius:cornerRadius - 1];
  232. CGContextAddPath(context, path);
  233. if (highlighted) {
  234. CGContextSetRGBFillColor(context, 0.384, 0.608, 0.906, 1.0);
  235. } else {
  236. CGContextSetRGBFillColor(context, 0.471, 0.471, 0.471, 1.0);
  237. }
  238. CGContextFillPath(context);
  239. CGPathRelease(path);
  240. } CGContextRestoreGState(context);
  241. // Upper head
  242. CGContextSaveGState(context); {
  243. CGMutablePathRef path = [self upperHeadPathInRect:CGRectMake(rect.origin.x + 1, rect.origin.y + 2, rect.size.width - 1, rect.size.height / 2 - 2) cornerRadius:cornerRadius - 1];
  244. CGContextAddPath(context, path);
  245. CGContextClip(context);
  246. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  247. CGFloat components[8];
  248. if (highlighted) {
  249. components[0] = 0.216; components[1] = 0.471; components[2] = 0.871; components[3] = 1;
  250. components[4] = 0.059; components[5] = 0.353; components[6] = 0.839; components[7] = 1;
  251. } else {
  252. components[0] = 0.314; components[1] = 0.314; components[2] = 0.314; components[3] = 1;
  253. components[4] = 0.165; components[5] = 0.165; components[6] = 0.165; components[7] = 1;
  254. }
  255. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  256. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y + 2);
  257. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height / 2 - 2);
  258. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  259. CGGradientRelease(gradient);
  260. CGColorSpaceRelease(colorSpace);
  261. CGPathRelease(path);
  262. } CGContextRestoreGState(context);
  263. // Lower head
  264. CGContextSaveGState(context); {
  265. CGMutablePathRef path = [self lowerHeadPathInRect:CGRectMake(rect.origin.x + 1, rect.origin.y + rect.size.height / 2, rect.size.width - 1, rect.size.height / 2 - 1) cornerRadius:cornerRadius - 1];
  266. CGContextAddPath(context, path);
  267. CGContextClip(context);
  268. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  269. CGFloat components[8];
  270. if (highlighted) {
  271. components[0] = 0.047; components[1] = 0.306; components[2] = 0.827; components[3] = 1;
  272. components[4] = 0.027; components[5] = 0.176; components[6] = 0.737; components[7] = 1;
  273. } else {
  274. components[0] = 0.102; components[1] = 0.102; components[2] = 0.102; components[3] = 1;
  275. components[4] = 0; components[5] = 0; components[6] = 0; components[7] = 1;
  276. }
  277. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  278. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height / 2);
  279. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height - 1);
  280. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  281. CGGradientRelease(gradient);
  282. CGColorSpaceRelease(colorSpace);
  283. CGPathRelease(path);
  284. } CGContextRestoreGState(context);
  285. }
  286. - (void)drawTailInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius highlighted:(BOOL)highlighted
  287. {
  288. CGContextRef context = UIGraphicsGetCurrentContext();
  289. // Border
  290. CGContextSaveGState(context); {
  291. CGMutablePathRef path = [self tailPathInRect:rect cornerRadius:cornerRadius];
  292. CGContextAddPath(context, path);
  293. CGContextSetRGBFillColor(context, 0, 0, 0, 1.0);
  294. CGContextFillPath(context);
  295. CGPathRelease(path);
  296. } CGContextRestoreGState(context);
  297. // Highlight
  298. CGContextSaveGState(context); {
  299. CGMutablePathRef path = [self tailPathInRect:CGRectMake(rect.origin.x, rect.origin.y + 1, rect.size.width - 1, rect.size.height - 2) cornerRadius:cornerRadius - 1];
  300. CGContextAddPath(context, path);
  301. if (highlighted) {
  302. CGContextSetRGBFillColor(context, 0.384, 0.608, 0.906, 1.0);
  303. } else {
  304. CGContextSetRGBFillColor(context, 0.471, 0.471, 0.471, 1.0);
  305. }
  306. CGContextFillPath(context);
  307. CGPathRelease(path);
  308. } CGContextRestoreGState(context);
  309. // Upper body
  310. CGContextSaveGState(context); {
  311. CGMutablePathRef path = [self upperTailPathInRect:CGRectMake(rect.origin.x, rect.origin.y + 2, rect.size.width - 1, rect.size.height / 2 - 2) cornerRadius:cornerRadius - 1];
  312. CGContextAddPath(context, path);
  313. CGContextClip(context);
  314. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  315. CGFloat components[8];
  316. if (highlighted) {
  317. components[0] = 0.216; components[1] = 0.471; components[2] = 0.871; components[3] = 1;
  318. components[4] = 0.059; components[5] = 0.353; components[6] = 0.839; components[7] = 1;
  319. } else {
  320. components[0] = 0.314; components[1] = 0.314; components[2] = 0.314; components[3] = 1;
  321. components[4] = 0.165; components[5] = 0.165; components[6] = 0.165; components[7] = 1;
  322. }
  323. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  324. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y + 2);
  325. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height / 2 - 2);
  326. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  327. CGGradientRelease(gradient);
  328. CGColorSpaceRelease(colorSpace);
  329. CGPathRelease(path);
  330. } CGContextRestoreGState(context);
  331. // Lower body
  332. CGContextSaveGState(context); {
  333. CGMutablePathRef path = [self lowerTailPathInRect:CGRectMake(rect.origin.x, rect.origin.y + rect.size.height / 2, rect.size.width - 1, rect.size.height / 2 - 1) cornerRadius:cornerRadius - 1];
  334. CGContextAddPath(context, path);
  335. CGContextClip(context);
  336. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  337. CGFloat components[8];
  338. if (highlighted) {
  339. components[0] = 0.047; components[1] = 0.306; components[2] = 0.827; components[3] = 1;
  340. components[4] = 0.027; components[5] = 0.176; components[6] = 0.737; components[7] = 1;
  341. } else {
  342. components[0] = 0.102; components[1] = 0.102; components[2] = 0.102; components[3] = 1;
  343. components[4] = 0; components[5] = 0; components[6] = 0; components[7] = 1;
  344. }
  345. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  346. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height / 2);
  347. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height - 1);
  348. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  349. CGGradientRelease(gradient);
  350. CGColorSpaceRelease(colorSpace);
  351. CGPathRelease(path);
  352. } CGContextRestoreGState(context);
  353. }
  354. - (void)drawBodyInRect:(CGRect)rect firstItem:(BOOL)firstItem lastItem:(BOOL)lastItem highlighted:(BOOL)highlighted
  355. {
  356. CGContextRef context = UIGraphicsGetCurrentContext();
  357. // Border
  358. CGContextSaveGState(context); {
  359. CGMutablePathRef path = [self bodyPathInRect:rect];
  360. CGContextAddPath(context, path);
  361. CGContextSetRGBFillColor(context, 0, 0, 0, 1.0);
  362. CGContextFillPath(context);
  363. CGPathRelease(path);
  364. } CGContextRestoreGState(context);
  365. // Highlight
  366. CGContextSaveGState(context); {
  367. CGMutablePathRef path = [self bodyPathInRect:CGRectMake(rect.origin.x, rect.origin.y + 1, rect.size.width, rect.size.height - 2)];
  368. CGContextAddPath(context, path);
  369. if (highlighted) {
  370. CGContextSetRGBFillColor(context, 0.384, 0.608, 0.906, 1.0);
  371. } else {
  372. CGContextSetRGBFillColor(context, 0.471, 0.471, 0.471, 1.0);
  373. }
  374. CGContextFillPath(context);
  375. CGPathRelease(path);
  376. } CGContextRestoreGState(context);
  377. // Upper body
  378. CGContextSaveGState(context); {
  379. CGMutablePathRef path = [self bodyPathInRect:CGRectMake(rect.origin.x, rect.origin.y + 2, rect.size.width, rect.size.height / 2 - 2)];
  380. CGContextAddPath(context, path);
  381. CGContextClip(context);
  382. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  383. CGFloat components[8];
  384. if (highlighted) {
  385. components[0] = 0.216; components[1] = 0.471; components[2] = 0.871; components[3] = 1;
  386. components[4] = 0.059; components[5] = 0.353; components[6] = 0.839; components[7] = 1;
  387. } else {
  388. components[0] = 0.314; components[1] = 0.314; components[2] = 0.314; components[3] = 1;
  389. components[4] = 0.165; components[5] = 0.165; components[6] = 0.165; components[7] = 1;
  390. }
  391. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  392. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y + 2);
  393. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height / 2 - 2);
  394. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  395. CGGradientRelease(gradient);
  396. CGColorSpaceRelease(colorSpace);
  397. CGPathRelease(path);
  398. } CGContextRestoreGState(context);
  399. // Lower body
  400. CGContextSaveGState(context); {
  401. CGMutablePathRef path = [self bodyPathInRect:CGRectMake(rect.origin.x, rect.origin.y + rect.size.height / 2, rect.size.width, rect.size.height / 2 - 1)];
  402. CGContextAddPath(context, path);
  403. CGContextClip(context);
  404. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  405. CGFloat components[8];
  406. if (highlighted) {
  407. components[0] = 0.047; components[1] = 0.306; components[2] = 0.827; components[3] = 1;
  408. components[4] = 0.027; components[5] = 0.176; components[6] = 0.737; components[7] = 1;
  409. } else {
  410. components[0] = 0.102; components[1] = 0.102; components[2] = 0.102; components[3] = 1;
  411. components[4] = 0; components[5] = 0; components[6] = 0; components[7] = 1;
  412. }
  413. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
  414. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height / 2);
  415. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height - 1);
  416. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  417. CGGradientRelease(gradient);
  418. CGColorSpaceRelease(colorSpace);
  419. CGPathRelease(path);
  420. } CGContextRestoreGState(context);
  421. // Draw separator
  422. if (!firstItem) {
  423. [self drawLeftSeparatorInRect:CGRectMake(rect.origin.x, rect.origin.y + 2, 1, rect.size.height - 3) highlighted:highlighted];
  424. }
  425. if (!lastItem) {
  426. [self drawRightSeparatorInRect:CGRectMake(rect.origin.x + rect.size.width - 1, rect.origin.y + 2, 1, rect.size.height - 3) highlighted:highlighted];
  427. }
  428. }
  429. - (void)drawLeftSeparatorInRect:(CGRect)rect highlighted:(BOOL)highlighted
  430. {
  431. CGContextRef context = UIGraphicsGetCurrentContext();
  432. // Left separator
  433. CGContextSaveGState(context); {
  434. CGContextAddRect(context, rect);
  435. CGContextClip(context);
  436. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  437. CGFloat components[16];
  438. if (highlighted) {
  439. components[0] = 0.22; components[1] = 0.47; components[2] = 0.87; components[3] = 1;
  440. components[4] = 0.12; components[5] = 0.50; components[6] = 0.89; components[7] = 1;
  441. components[8] = 0.09; components[9] = 0.47; components[10] = 0.88; components[11] = 1;
  442. components[12] = 0.03; components[13] = 0.18; components[14] = 0.74; components[15] = 1;
  443. } else {
  444. components[0] = 0.31; components[1] = 0.31; components[2] = 0.31; components[3] = 1;
  445. components[4] = 0.31; components[5] = 0.31; components[6] = 0.31; components[7] = 1;
  446. components[8] = 0.24; components[9] = 0.24; components[10] = 0.24; components[11] = 1;
  447. components[12] = 0.05; components[13] = 0.05; components[14] = 0.05; components[15] = 1;
  448. }
  449. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 4);
  450. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y);
  451. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
  452. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  453. CGGradientRelease(gradient);
  454. CGColorSpaceRelease(colorSpace);
  455. } CGContextRestoreGState(context);
  456. }
  457. - (void)drawRightSeparatorInRect:(CGRect)rect highlighted:(BOOL)highlighted
  458. {
  459. CGContextRef context = UIGraphicsGetCurrentContext();
  460. // Right separator
  461. CGContextSaveGState(context); {
  462. CGContextAddRect(context, rect);
  463. CGContextClip(context);
  464. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  465. CGFloat components[16];
  466. if (highlighted) {
  467. components[0] = 0.22; components[1] = 0.47; components[2] = 0.87; components[3] = 1;
  468. components[4] = 0.03; components[5] = 0.18; components[6] = 0.72; components[7] = 1;
  469. components[8] = 0.02; components[9] = 0.15; components[10] = 0.73; components[11] = 1;
  470. components[12] = 0.03; components[13] = 0.17; components[14] = 0.72; components[15] = 1;
  471. } else {
  472. components[0] = 0.31; components[1] = 0.31; components[2] = 0.31; components[3] = 1;
  473. components[4] = 0.06; components[5] = 0.06; components[6] = 0.06; components[7] = 1;
  474. components[8] = 0.04; components[9] = 0.04; components[10] = 0.04; components[11] = 1;
  475. components[12] = 0; components[13] = 0; components[14] = 0; components[15] = 1;
  476. }
  477. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 4);
  478. CGPoint startPoint = CGPointMake(rect.origin.x, rect.origin.y);
  479. CGPoint endPoint = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
  480. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
  481. CGGradientRelease(gradient);
  482. CGColorSpaceRelease(colorSpace);
  483. } CGContextRestoreGState(context);
  484. }
  485. @end