Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

scrollbar_generic.cpp

Go to the documentation of this file.
00001 /*
00002         ClanGUI, copyrights by various people. Have a look in the CREDITS file.
00003         
00004         This sourcecode is distributed using the Library GNU Public Licence,
00005         version 2 or (at your option) any later version. Please read LICENSE
00006         for details.
00007 */
00008 
00009 #include "precomp.h"
00010 #include "scrollbar_generic.h"
00011 #include "API/GUI/scrollbar.h"
00012 #include "API/GUI/component.h"
00013 #include "API/GUI/component_options.h"
00014 #include "API/GUI/stylemanager.h"
00015 #include "API/GUI/button.h"
00016 #include "API/Display/Input/input.h"
00017 #include "API/Display/Input/mouse.h"
00018 
00019 #define cl_max(a,b) (a > b ? a : b)
00020 #define cl_min(a,b) (a < b ? a : b)
00021 
00023 // Construction:
00024 
00025 CL_ComponentOptions CL_ScrollBar_Generic::create_options(
00026         const CL_Rect &pos,
00027         int min,
00028         int max,
00029         int value,
00030         bool orientation,
00031         bool tracking)
00032 {
00033         CL_ComponentOptions options;
00034 
00035         options.add_option_as_int("x", pos.x1);
00036         options.add_option_as_int("y", pos.y1);
00037         options.add_option_as_int("width", pos.get_width());
00038         options.add_option_as_int("height", pos.get_height());
00039         options.add_option_as_int("min", min);
00040         options.add_option_as_int("max", max);
00041         options.add_option_as_int("value", value);
00042         options.add_option_as_bool("orientation", orientation);
00043         options.add_option_as_bool("tracking", tracking);
00044 
00045         return options;
00046 }
00047 
00048 CL_ScrollBar_Generic::CL_ScrollBar_Generic(
00049         CL_ScrollBar *self,
00050         const CL_ComponentOptions &options,
00051         CL_StyleManager *style)
00052 :
00053         scrollbar(self),
00054         tracking(true),
00055         dragging(false),
00056         fixed_length(false),
00057         slider_length(16),
00058         initialized(false)
00059 /*      scroll_timer(250),
00060         decrease_button(NULL),
00061         increase_button(NULL),
00062         delete_increase_button(false),
00063         delete_decrease_button(false),
00064         mouse_captured(false),
00065         scrolling(false),
00066         section_scrolling(false),
00067         scroll_direction(1)
00068         drag_offset_x(0),
00069         drag_offset_y(0),
00070         drag_rect(0,0,0,0),
00071         capture_orgpos(0),
00072         capture_org_drag_offset_x(0),
00073         capture_org_drag_offset_y(0),
00074         capture_x_offset(0),
00075         capture_y_offset(0),
00076         last_capture_x(0),
00077         last_capture_y(0)
00078 */
00079 {
00080         if(options.exists("orientation"))
00081         {
00082                 CL_String s(options.get_value("orientation"));
00083                 s.to_lower();
00084                 if (s == "hor" || s == "horizontal" || s == "1")
00085                         vertical = false;
00086                 else if (s == "ver" || s == "vertical" || s == "0")
00087                         vertical = true;
00088                 else
00089                         throw CL_Error("Invalid scrollbar orientation value");
00090         }
00091         else
00092                 vertical = false;
00093 
00094         if (options.exists("min"))
00095                 set_min_value(options.get_value_as_int("min"));
00096         else
00097                 set_min_value(0);
00098 
00099         if (options.exists("max"))
00100                 set_max_value(options.get_value_as_int("max"));
00101         else
00102                 set_max_value(min_value);
00103 
00104         if (options.exists("value"))
00105                 set_value(options.get_value_as_int("value"));
00106         else
00107                 set_value(min_value);
00108 
00109 /*      if (vertical)
00110         {
00111                 drag_offset_x = 0;
00112                 if(scroll_range > 0)
00113                         drag_offset_y = cur_position * (scrollbar->get_height() - 32) / scroll_range + 16;
00114                 else
00115                         drag_offset_y = 0;
00116                 drag_rect = CL_Rect(0, 0, 16, scroller_size);
00117         }
00118         else
00119         {
00120                 if(scroll_range > 0)
00121                         drag_offset_x = cur_position * (scrollbar->get_width() - 32) / scroll_range + 16;
00122                 else
00123                         drag_offset_x = 0;
00124                 drag_offset_y = 0;
00125                 drag_rect = CL_Rect(0, 0, scroller_size, 16);
00126         }
00127 */
00128         CL_Rect rect(0, 0, scrollbar->get_width(), scrollbar->get_height());
00129         client_area = new CL_Component(rect, scrollbar, style);
00130 
00131 /*      slot_timer = scroll_timer.sig_timer.connect(
00132                 CL_CreateSlot(this, &CL_ScrollBar_Generic::on_scroll_timer));
00133         slot_resize = scrollbar->sig_resized().connect(
00134                 CL_CreateSlot(this, &CL_ScrollBar_Generic::on_resize));
00135         slot_mousemove = scrollbar->sig_mouse_moved().connect(
00136                 CL_CreateSlot(this, &CL_ScrollBar_Generic::on_mouse_move));
00137 */      slot_keydown = scrollbar->sig_key_down().connect(
00138                 CL_CreateSlot(this, &CL_ScrollBar_Generic::on_key_down));
00139         slot_keyup = scrollbar->sig_key_up().connect(
00140                 CL_CreateSlot(this, &CL_ScrollBar_Generic::on_key_up));
00141         slot_child_add = scrollbar->sig_child_add().connect(
00142                 CL_CreateSlot(this, &CL_ScrollBar_Generic::on_child_add));
00143         slot_child_remove = scrollbar->sig_child_remove().connect(
00144                 CL_CreateSlot(this, &CL_ScrollBar_Generic::on_child_remove));
00145 
00146         initialized = true;
00147 }
00148 
00150 // Attributes:
00151 
00152 int CL_ScrollBar_Generic::get_range() const
00153 {
00154         return max_value - min_value + 1;
00155 }
00156 
00158 // Operations:
00159 
00160 void CL_ScrollBar_Generic::set_vertical(bool enable)
00161 {
00162         throw CL_Error("CL_ScrollBar_Generic::set_vertical() is not implemented");
00163 }
00164 
00165 void CL_ScrollBar_Generic::set_min_value(int value)
00166 {
00167         min_value = value;
00168         if(max_value < min_value)
00169                 max_value = min_value;
00170         
00171         if(cur_value < min_value)
00172                 cur_value = min_value;
00173 
00174         calculate_slider_size();
00175 }
00176 
00177 void CL_ScrollBar_Generic::set_max_value(int value)
00178 {
00179         max_value = value;
00180         if(max_value < min_value)
00181                 max_value = min_value;
00182         
00183         if(cur_value > max_value)
00184                 cur_value = max_value;
00185 
00186         calculate_slider_size();
00187 }
00188 
00189 void CL_ScrollBar_Generic::set_value(int value)
00190 {
00191         if (value < min_value) value = min_value;
00192         if (value > max_value) value = max_value;
00193 
00194         if (cur_value != value)
00195         {
00196                 cur_value = value;
00197                 sig_value_changed(cur_value);
00198         }
00199 
00200         calculate_slider_size();
00201 }
00202 
00204 // Callbacks:
00205 
00206 void CL_ScrollBar_Generic::on_child_add(CL_Component *child)
00207 {
00208         CL_Rect rect_child = child->get_position();
00209         CL_Rect rect_clientarea = client_area->get_position();
00210 
00211 /*      if(rect_child.x2 < rect_clientarea.get_width() / 2)     // Left side
00212                 rect_clientarea.x1 = rect_child.x2;
00213         else
00214                 rect_clientarea.x2 = rect_child.x1;
00215 */
00216         if(rect_child.y2 < rect_clientarea.get_height() / 2)    // Top side
00217                 rect_clientarea.y1 = rect_child.y2;
00218         else
00219                 rect_clientarea.y2 = rect_child.y1;
00220 
00221         client_area->set_position(rect_clientarea);
00222 
00223         calculate_slider_size();
00224 }
00225 
00226 void CL_ScrollBar_Generic::on_child_remove(CL_Component *child)
00227 {
00228 }
00229 
00230 void CL_ScrollBar_Generic::on_key_down(CL_Component *comp, CL_InputDevice *device, CL_Key key)
00231 {
00232 //      int x2 = drag_offset_x+drag_rect.x2;
00233 //      int y2 = drag_offset_y+drag_rect.y2;
00234 
00235         // TODO: Check if it is mouse or keyboard
00236 
00237         // Mouse input
00238 /*      if (mouse_captured == false)
00239         {
00240                 CL_Rect slider = get_slider_rect();
00241 
00242                 if (key.x >= slider.x1 && 
00243                         key.y >= slider.y1 && 
00244                         key.x <= slider.x2 && 
00245                         key.y <= slider.y2)
00246                 {
00247                         mouse_captured = true;
00248                         scrollbar->capture_mouse();
00249                         capture_x_offset = (int) key.x - drag_offset_x;
00250                         capture_y_offset = (int) key.y - drag_offset_y;
00251                         last_capture_x = (int) key.x;
00252                         last_capture_y = (int) key.y;
00253                         capture_orgpos = cur_value;
00254                         capture_org_drag_offset_x = drag_offset_x;
00255                         capture_org_drag_offset_y = drag_offset_y;
00256                 }
00257                 else
00258                 {
00259                         if (vertical)
00260                         {
00261                                 if (key.y >= 16 && key.y <= scrollbar->get_height()-16)
00262                                 {
00263                                         if (key.y < drag_offset_y)
00264                                                 scroll_direction = cl_min(-5, -scroll_range/10);
00265                                         else
00266                                                 scroll_direction = cl_max(5, scroll_range/10);
00267 
00268                                         set_cur_position(cur_position+scroll_direction);
00269                                         scrolling = true;
00270                                         section_scrolling = true;
00271                                         scroll_timer.enable();
00272                                 }
00273                         }
00274                         else
00275                         {
00276                                 if (key.x >= 16 && key.x <= scrollbar->get_width()-16)
00277                                 {
00278                                         if (key.x < drag_offset_x)
00279                                                 scroll_direction = cl_min(-5, -scroll_range/10);
00280                                         else
00281                                                 scroll_direction = cl_max(5, scroll_range/10);
00282 
00283                                         set_cur_position(cur_position+scroll_direction);
00284                                         scrolling = true;
00285                                         section_scrolling = true;
00286                                         scroll_timer.enable();
00287                                 }
00288                         }
00289                 }
00290         }
00291 */}
00292 
00293 void CL_ScrollBar_Generic::on_key_up(CL_Component *comp, CL_InputDevice *device, CL_Key key)
00294 {
00295 /*      if (device == CL_Input::pointers[0])
00296         {
00297                 if (mouse_captured)
00298                 {
00299                         scrollbar->release_mouse();
00300                         mouse_captured = false;
00301                 }
00302                 else if (scrolling && section_scrolling)
00303                 {
00304                         scrolling = false;
00305                         scroll_timer.disable();
00306                 }
00307         }
00308 */
00309 }
00310 
00311 /*
00312 void CL_ScrollBar_Generic::on_mouse_move(CL_Component *comp, CL_InputDevice *device, int x, int y)
00313 {
00314         if (mouse_captured)
00315         {
00316                 if (vertical)
00317                 {
00318                         drag_offset_y += y - last_capture_y;
00319                         last_capture_y = y;
00320 
00321                         int pos = int((float((drag_offset_y-16)*scroll_range) / (scrollbar->get_height()-32-drag_rect.y2))+0.5f);
00322                         if (x < - 50 || x >= scrollbar->get_width()+50 ||
00323                                 y < - 50 || y >= scrollbar->get_height()+50)
00324                         {
00325                                 scrollbar->release_mouse();
00326                                 mouse_captured = false;
00327                                 drag_offset_x = capture_org_drag_offset_x;
00328                                 drag_offset_y = capture_org_drag_offset_y;
00329                                 set_cur_position(capture_orgpos);
00330                         }
00331                         else
00332                         {
00333                                 set_cur_position(pos);
00334                         }
00335                 } 
00336                 else
00337                 {
00338                         drag_offset_x += x - last_capture_x;
00339                         last_capture_x = x;
00340 
00341                         int pos = ((drag_offset_x-16)*scroll_range) / (scrollbar->get_width()-64);
00342                         if (x < - 50 || x >= scrollbar->get_width()+50 ||
00343                                 y < - 50 || y >= scrollbar->get_height()+50)
00344                         {
00345                                 scrollbar->release_mouse();
00346                                 mouse_captured = false;
00347                                 drag_offset_x = capture_org_drag_offset_x;
00348                                 drag_offset_y = capture_org_drag_offset_y;
00349                                 set_cur_position(capture_orgpos);
00350                         }
00351                         else
00352                         {
00353                                 set_cur_position(pos);
00354                         }
00355                 }
00356         }
00357 }
00358 
00359 void CL_ScrollBar_Generic::on_scroll_timer()
00360 {
00361         if ((cur_position > 0 && scroll_direction < 0) ||
00362                 (cur_position < scroll_range && scroll_direction > 0))
00363         {
00364                 int mouse_x = CL_Mouse::get_x();
00365                 int mouse_y = CL_Mouse::get_y();
00366 
00367                 if (section_scrolling)
00368                 {
00369                         CL_Rect scr_scroll = scrollbar->get_screen_rect();
00370                         bool perform_scroll = false;
00371                         if (scroll_direction < 0)
00372                         {
00373                                 if (vertical)
00374                                 {
00375                                         if (mouse_x >= scr_scroll.x1 && 
00376                                                 mouse_y >= scr_scroll.y1+16 &&
00377                                                 mouse_x < scr_scroll.x2 &&
00378                                                 mouse_y < scr_scroll.y1 + drag_offset_y)
00379                                         {
00380                                                 perform_scroll = true;
00381                                         }
00382                                 }
00383                                 else
00384                                 {
00385                                         if (mouse_x >= scr_scroll.x1+16 && 
00386                                                 mouse_y >= scr_scroll.y1 &&
00387                                                 mouse_x < scr_scroll.x1 + drag_offset_x &&
00388                                                 mouse_y < scr_scroll.y2)
00389                                         {
00390                                                 perform_scroll = true;
00391                                         }
00392                                 }
00393                         }
00394                         else
00395                         {
00396                                 if (vertical)
00397                                 {
00398                                         if (mouse_x >= scr_scroll.x1 && 
00399                                                 mouse_y >= scr_scroll.y1+drag_offset_y+drag_rect.y2 &&
00400                                                 mouse_x < scr_scroll.x2 &&
00401                                                 mouse_y < scr_scroll.y2-16)
00402                                         {
00403                                                 perform_scroll = true;
00404                                         }
00405                                 }
00406                                 else
00407                                 {
00408                                         if (mouse_x >= scr_scroll.x1+drag_offset_x+drag_rect.x2 && 
00409                                                 mouse_y >= scr_scroll.y1 &&
00410                                                 mouse_x < scr_scroll.x2-16 &&
00411                                                 mouse_y < scr_scroll.y2)
00412                                         {
00413                                                 perform_scroll = true;
00414                                         }
00415                                 }
00416                         }
00417                         if (perform_scroll)
00418                         {
00419                                 set_cur_position(cur_position + scroll_direction);
00420                         }
00421                 }
00422                 else
00423                 {
00424                         CL_Button *check_button = increase_button;
00425                         if (scroll_direction < 0) check_button = decrease_buttton;
00426 
00427                         CL_Rect scr_button = check_button->get_screen_rect();
00428                         if (mouse_x >= scr_button.x1 &&
00429                                 mouse_y >= scr_button.y1 &&
00430                                 mouse_x < scr_button.x2 &&
00431                                 mouse_y < scr_button.y2)
00432                         {
00433                                 set_cur_position(cur_position + scroll_direction);
00434                         }
00435                 }
00436         }
00437 }
00438 
00439 
00440 void CL_ScrollBar_Generic::on_decrease_pressed()
00441 {
00442         scrolling = true;
00443         scroll_direction = -1;
00444         section_scrolling = false;
00445         scroll_timer.enable();
00446 
00447         if (cur_position > 0)
00448         {
00449                 cur_position--;
00450                 sig_scrolled(cur_position);
00451         }
00452 }
00453 
00454 void CL_ScrollBar_Generic::on_increase_pressed()
00455 {
00456         scrolling = true;
00457         scroll_direction = 1;
00458         section_scrolling = false;
00459         scroll_timer.enable();
00460         if (cur_position < scroll_range) 
00461         {
00462                 cur_position++;
00463                 sig_scrolled(cur_position);
00464         }
00465 
00466 }
00467 
00468 void CL_ScrollBar_Generic::on_decrease_released()
00469 {
00470         if (scrolling && scroll_direction == -1)
00471         {
00472                 scrolling = false;
00473                 scroll_timer.disable();
00474         }
00475 }
00476 
00477 void CL_ScrollBar_Generic::on_increase_released()
00478 {
00479         if (scrolling && scroll_direction == 1)
00480         {
00481                 scrolling = false;
00482                 scroll_timer.disable();
00483         }
00484 
00485 }
00486 
00487 void CL_ScrollBar_Generic::on_resize(int old_width, int old_height)
00488 {
00489         if (increase_button == NULL) return;
00490 
00491         if (vertical)
00492         {
00493                 increase_button->set_position(
00494                         increase_button->get_position().x1,
00495                         scrollbar->get_height()-increase_button->get_height());
00496         }
00497         else
00498         {
00499                 increase_button->set_position(
00500                         scrollbar->get_width()-increase_button->get_width(),
00501                         increase_button->get_position().y1);
00502         }
00503 }
00504 */
00505 
00507 // Implementation:
00508 
00509 void CL_ScrollBar_Generic::calculate_slider_size()
00510 {
00511         if(initialized == false)
00512                 return;
00513 
00514         int slider_offset;
00515 
00516         if(fixed_length)
00517         {
00518                 throw CL_Error("fixed-length sliders not implemented");
00519         }
00520         else {
00521                 int scrollbar_length;
00522                 if (vertical)
00523                         scrollbar_length = scrollbar->get_client_area()->get_height();
00524                 else
00525                         scrollbar_length = scrollbar->get_client_area()->get_width();
00526                 
00527                 int range = get_range();
00528 
00529                 slider_length = scrollbar_length / range;
00530                 if(slider_length < 20)
00531                         slider_length = 20;
00532 
00533                 float y = 0.0f;
00534                 if(range > 1)
00535                 {
00536                         int available_area = scrollbar_length - slider_length;
00537                         y = (float)available_area / (range - 1);
00538                 }
00539 
00540                 slider_offset = y * (cur_value - min_value);
00541         }
00542 
00543         rect_slider.y1 = slider_offset;
00544         rect_slider.y2 = slider_offset + slider_length;
00545         rect_slider.x1 = 0;
00546         rect_slider.x2 = scrollbar->get_client_area()->get_width();
00547 }
00548 

Generated at Wed Apr 4 19:54:03 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001