OSLIDCUS.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. // Filename : OSLIDCUS.CPP
  21. // Description : custom slide bar
  22. #include <OMOUSE.h>
  23. #include <OSLIDCUS.h>
  24. // ------- begin of inline function bound ---------//
  25. inline int bound(int v, int lowerLimit, int upperLimit)
  26. {
  27. err_when( lowerLimit > upperLimit );
  28. return v<lowerLimit ? lowerLimit : (v>upperLimit ? upperLimit : v);
  29. }
  30. // ------- end of inline function bound ---------//
  31. // ------- begin of function SlideBar::init_scroll ---------//
  32. void SlideBar::init_scroll(short x1, short y1, short x2, short y2, int viewSize, SlideBarFP dispFunc)
  33. {
  34. scrn_x1 = x1;
  35. scrn_y1 = y1;
  36. scrn_x2 = x2;
  37. scrn_y2 = y2;
  38. scrn_bar_width = 0;
  39. scroll_type = 1;
  40. view_size = viewSize;
  41. disp_func = dispFunc;
  42. drag_flag = 0;
  43. }
  44. // ------- end of function SlideBar::init_scroll ---------//
  45. // ------- begin of function SlideBar::init_slide ---------//
  46. // set view_size to 0
  47. void SlideBar::init_slide(short x1, short y1, short x2, short y2, short barWidth, SlideBarFP dispFunc)
  48. {
  49. scrn_x1 = x1;
  50. scrn_y1 = y1;
  51. scrn_x2 = x2;
  52. scrn_y2 = y2;
  53. scrn_bar_width = barWidth;
  54. scroll_type = 0;
  55. view_size = 0;
  56. disp_func = dispFunc;
  57. drag_flag = 0;
  58. }
  59. // ------- end of function SlideBar::init_scroll ---------//
  60. void SlideBar::set(int minRecno, int maxRecno, int viewRecno)
  61. {
  62. min_recno = minRecno;
  63. max_recno = maxRecno;
  64. view_recno = viewRecno;
  65. // empty if (max_recno - min_recno + scroll_type == 0)
  66. err_when( max_recno - min_recno + scroll_type < 0);
  67. }
  68. int SlideBar::set_view_recno(int viewRecno)
  69. {
  70. view_recno = viewRecno;
  71. if( view_recno > max_recno - view_size + scroll_type )
  72. view_recno = max_recno - view_size + scroll_type;
  73. if( view_recno < min_recno )
  74. view_recno = min_recno;
  75. return view_recno;
  76. }
  77. void SlideBar::set_min_recno(int minRecno)
  78. {
  79. min_recno = minRecno;
  80. err_when( max_recno - min_recno + scroll_type < 0);
  81. if( view_recno > max_recno - view_size + scroll_type )
  82. view_recno = max_recno - view_size + scroll_type;
  83. if( view_recno < min_recno )
  84. view_recno = min_recno;
  85. }
  86. void SlideBar::set_max_recno(int maxRecno)
  87. {
  88. max_recno = maxRecno;
  89. err_when( max_recno - min_recno + scroll_type < 0);
  90. if( view_recno > max_recno - view_size + scroll_type )
  91. view_recno = max_recno - view_size + scroll_type;
  92. if( view_recno < min_recno )
  93. view_recno = min_recno;
  94. }
  95. int SlideBar::is_empty()
  96. {
  97. return max_recno - min_recno + scroll_type <= 0;
  98. }
  99. // [int] disablePaint : don't call paint (default = 0)
  100. // return 2 if the view_recno does not change
  101. int SlideBar::detect()
  102. {
  103. int retValue = 0;
  104. if( !drag_flag )
  105. {
  106. short rectLeft = rect_left();
  107. short rectRight = rect_right();
  108. if( mouse.single_click(scrn_x1, scrn_y1, scrn_x2, scrn_y2) )
  109. {
  110. short clickX = mouse.click_x();
  111. if( clickX >= rectLeft && clickX <= rectRight )
  112. {
  113. drag_flag = 1;
  114. drag_cur_x = clickX;
  115. drag_rect_left = rectLeft;
  116. drag_last_view_recno = view_recno;
  117. retValue = 2;
  118. }
  119. else
  120. {
  121. // suppose click position will be the center of the button
  122. short newScrollButtonX1 = clickX - (rectRight - rectLeft)/2;
  123. view_recno = calc_view_recno(newScrollButtonX1);
  124. drag_flag = 1;
  125. drag_cur_x = clickX;
  126. drag_rect_left = rect_left(); // rect_left() != rectLeft
  127. drag_last_view_recno = view_recno;
  128. }
  129. retValue = 1;
  130. }
  131. }
  132. else
  133. {
  134. // detect draggin on the scroll bar, don't detect any other buttons
  135. if( !mouse.left_press )
  136. {
  137. drag_flag = 0;
  138. }
  139. int oldValue = view_recno;
  140. int dragX = mouse.cur_x;
  141. int newScrollButtonX1 = dragX - drag_cur_x + drag_rect_left;
  142. // control the boundary of scrollButtonY1
  143. drag_last_view_recno = view_recno;
  144. view_recno = calc_view_recno(newScrollButtonX1);
  145. retValue = drag_last_view_recno == view_recno ? 2 : 1;
  146. }
  147. if( retValue == 1 )
  148. paint();
  149. return retValue;
  150. }
  151. void SlideBar::paint()
  152. {
  153. (*disp_func)(this, 1);
  154. }
  155. void SlideBar::paint(int newViewRecno)
  156. {
  157. set_view_recno(newViewRecno);
  158. paint();
  159. //view_recno = bound(newViewRecno, min_recno, max_recno);
  160. //(*disp_func)(this, 1);
  161. }
  162. // instruction for disp_func
  163. //
  164. // for scroll bar style,
  165. // draw a rectangle from rect_left() to rect_right()
  166. // display from min_recno to max_recno
  167. //
  168. // for slider style,
  169. // draw the slide button at (rect_left(), scrn_y2)
  170. short SlideBar::rect_left()
  171. {
  172. err_when( view_recno < min_recno );
  173. // err_when( view_recno > max_view_recno() );
  174. if( is_empty() )
  175. return scrn_x1; // empty
  176. else
  177. return bound( scrn_x1 + (view_recno-min_recno)*(scrn_x2-scrn_x1+1-scrn_bar_width)/(max_recno-min_recno+scroll_type),
  178. scrn_x1, scrn_x2 );
  179. }
  180. short SlideBar::rect_right()
  181. {
  182. // slide bar style need not call rect_right(), it should be rect_left() + scrn_bar_width - 1
  183. // as view_size = 0
  184. err_when( view_recno < min_recno );
  185. // err_when( view_recno > max_view_recno() );
  186. if( is_empty() )
  187. return scrn_x2; // empty
  188. else
  189. return bound( scrn_x1+scrn_bar_width-1 + (view_recno+view_size-min_recno)*(scrn_x2-scrn_x1+1-scrn_bar_width)/(max_recno-min_recno+scroll_type),
  190. scrn_x1, scrn_x2 );
  191. }
  192. // reverse function, pass the proposed rect_left to return the corresponding view_recno
  193. int SlideBar::calc_view_recno(short scrnX)
  194. {
  195. int nomin = (scrnX-scrn_x1)*(max_recno-min_recno+scroll_type);
  196. int demon = (scrn_x2-scrn_x1+1-scrn_bar_width);
  197. int roundDivision = (2*nomin+demon) / demon / 2;
  198. return bound( min_recno + roundDivision, min_recno, max_view_recno() );
  199. }
  200. int SlideBar::max_view_recno()
  201. {
  202. if( is_empty() )
  203. return min_recno;
  204. else
  205. return bound( max_recno - view_size + scroll_type, min_recno, max_recno);
  206. }
  207. // .....................................................//
  208. // ------- begin of function SlideVBar::init_scroll ---------//
  209. void SlideVBar::init_scroll(short x1, short y1, short x2, short y2, int viewSize, SlideVBarFP dispFunc)
  210. {
  211. scrn_x1 = x1;
  212. scrn_y1 = y1;
  213. scrn_x2 = x2;
  214. scrn_y2 = y2;
  215. scrn_bar_height = 0;
  216. scroll_type = 1;
  217. view_size = viewSize;
  218. disp_func = dispFunc;
  219. drag_flag = 0;
  220. }
  221. // ------- end of function SlideVBar::init_scroll ---------//
  222. // ------- begin of function SlideVBar::init_slide ---------//
  223. // set view_size to 0
  224. void SlideVBar::init_slide(short x1, short y1, short x2, short y2, short barHeight, SlideVBarFP dispFunc)
  225. {
  226. scrn_x1 = x1;
  227. scrn_y1 = y1;
  228. scrn_x2 = x2;
  229. scrn_y2 = y2;
  230. scrn_bar_height = barHeight;
  231. scroll_type = 0;
  232. view_size = 0;
  233. disp_func = dispFunc;
  234. drag_flag = 0;
  235. }
  236. // ------- end of function SlideVBar::init_scroll ---------//
  237. void SlideVBar::set(int minRecno, int maxRecno, int viewRecno)
  238. {
  239. min_recno = minRecno;
  240. max_recno = maxRecno;
  241. view_recno = viewRecno;
  242. // empty if (max_recno - min_recno + scroll_type == 0)
  243. err_when( max_recno - min_recno + scroll_type < 0);
  244. }
  245. int SlideVBar::set_view_recno(int viewRecno)
  246. {
  247. view_recno = viewRecno;
  248. if( view_recno > max_recno - view_size + scroll_type )
  249. view_recno = max_recno - view_size + scroll_type;
  250. if( view_recno < min_recno )
  251. view_recno = min_recno;
  252. return view_recno;
  253. }
  254. void SlideVBar::set_min_recno(int minRecno)
  255. {
  256. min_recno = minRecno;
  257. err_when( max_recno - min_recno + scroll_type < 0);
  258. if( view_recno > max_recno - view_size + scroll_type )
  259. view_recno = max_recno - view_size + scroll_type;
  260. if( view_recno < min_recno )
  261. view_recno = min_recno;
  262. }
  263. void SlideVBar::set_max_recno(int maxRecno)
  264. {
  265. max_recno = maxRecno;
  266. err_when( max_recno - min_recno + scroll_type < 0);
  267. if( view_recno > max_recno - view_size + scroll_type )
  268. view_recno = max_recno - view_size + scroll_type;
  269. if( view_recno < min_recno )
  270. view_recno = min_recno;
  271. }
  272. int SlideVBar::is_empty()
  273. {
  274. return max_recno - min_recno + scroll_type <= 0;
  275. }
  276. // [int] disablePaint : don't call paint (default = 0)
  277. // return 2 if the view_recno does not change
  278. int SlideVBar::detect()
  279. {
  280. int retValue = 0;
  281. if( !drag_flag )
  282. {
  283. short rectTop = rect_top();
  284. short rectBottom = rect_bottom();
  285. if( mouse.single_click(scrn_x1, scrn_y1, scrn_x2, scrn_y2) )
  286. {
  287. short clickY = mouse.click_y();
  288. if( clickY >= rectTop && clickY <= rectBottom )
  289. {
  290. drag_flag = 1;
  291. drag_cur_y = clickY;
  292. drag_rect_top = rectTop;
  293. drag_last_view_recno = view_recno;
  294. retValue = 2;
  295. }
  296. else
  297. {
  298. // suppose click position will be the center of the button
  299. short newScrollButtonY1 = clickY - (rectBottom - rectTop)/2;
  300. view_recno = calc_view_recno(newScrollButtonY1);
  301. drag_flag = 1;
  302. drag_cur_y = clickY;
  303. drag_rect_top = rect_top(); // rect_top() != rectTop
  304. drag_last_view_recno = view_recno;
  305. }
  306. retValue = 1;
  307. }
  308. }
  309. else
  310. {
  311. // detect draggin on the scroll bar, don't detect any other buttons
  312. if( !mouse.left_press )
  313. {
  314. drag_flag = 0;
  315. }
  316. int oldValue = view_recno;
  317. int dragY = mouse.cur_y;
  318. int newScrollButtonY1 = dragY - drag_cur_y + drag_rect_top;
  319. // control the boundary of scrollButtonY1
  320. drag_last_view_recno = view_recno;
  321. view_recno = calc_view_recno(newScrollButtonY1);
  322. retValue = drag_last_view_recno == view_recno ? 2 : 1;
  323. }
  324. if( retValue == 1 )
  325. paint();
  326. return retValue;
  327. }
  328. void SlideVBar::paint()
  329. {
  330. (*disp_func)(this, 1);
  331. }
  332. void SlideVBar::paint(int newViewRecno)
  333. {
  334. set_view_recno(newViewRecno);
  335. paint();
  336. //view_recno = bound(newViewRecno, min_recno, max_recno);
  337. //(*disp_func)(this, 1);
  338. }
  339. // instruction for disp_func
  340. //
  341. // for scroll bar style,
  342. // draw a rectangle from rect_top() to rect_bottom()
  343. // display from min_recno to max_recno
  344. //
  345. // for slider style,
  346. // draw the slide button at (rect_top(), scrn_y2)
  347. short SlideVBar::rect_top()
  348. {
  349. err_when( view_recno < min_recno );
  350. // err_when( view_recno > max_view_recno() );
  351. if( is_empty() )
  352. return scrn_y1; // empty
  353. else
  354. return bound( scrn_y1 + (view_recno-min_recno)*(scrn_y2-scrn_y1+1-scrn_bar_height)/(max_recno-min_recno+scroll_type),
  355. scrn_y1, scrn_y2 );
  356. }
  357. short SlideVBar::rect_bottom()
  358. {
  359. // slide bar style need not call rect_bottom(), it should be rect_top() + scrn_bar_height - 1
  360. // as view_size = 0
  361. err_when( view_recno < min_recno );
  362. // err_when( view_recno > max_view_recno() );
  363. if( is_empty() )
  364. return scrn_y2; // empty
  365. else
  366. return bound( scrn_y1+scrn_bar_height-1 + (view_recno+view_size-min_recno)*(scrn_y2-scrn_y1+1-scrn_bar_height)/(max_recno-min_recno+scroll_type),
  367. scrn_y1, scrn_y2 );
  368. }
  369. // reverse function, pass the proposed rect_top to return the corresponding view_recno
  370. int SlideVBar::calc_view_recno(short scrnY)
  371. {
  372. int nomin = (scrnY-scrn_y1)*(max_recno-min_recno+scroll_type);
  373. int demon = scrn_y2-scrn_y1+1-scrn_bar_height;
  374. int roundDivision = (2*nomin+demon) / demon / 2;
  375. return bound( min_recno + roundDivision, min_recno, max_view_recno() );
  376. }
  377. int SlideVBar::max_view_recno()
  378. {
  379. if( is_empty() )
  380. return min_recno; // empty
  381. else
  382. return bound( max_recno - view_size + scroll_type, min_recno, max_recno);
  383. }