You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Fl_Navigation.cxx 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* Copyright 2022 Pierre Ossman for Cendio AB
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining
  4. * a copy of this software and associated documentation files (the
  5. * "Software"), to deal in the Software without restriction, including
  6. * without limitation the rights to use, copy, modify, merge, publish,
  7. * distribute, sublicense, and/or sell copies of the Software, and to
  8. * permit persons to whom the Software is furnished to do so, subject to
  9. * the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be
  12. * included in all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  18. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  19. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. * SOFTWARE.
  22. */
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26. #include <assert.h>
  27. #include <stddef.h>
  28. #include <stdio.h>
  29. #include <FL/Fl_Button.H>
  30. #include <FL/Fl_Scroll.H>
  31. #include "Fl_Navigation.h"
  32. Fl_Navigation::Fl_Navigation(int x, int y, int w, int h)
  33. : Fl_Group(x, y, w, h)
  34. {
  35. int dummy;
  36. scroll = new Fl_Scroll(x, y, 1, 1);
  37. scroll->type(Fl_Scroll::VERTICAL);
  38. scroll->color(FL_BACKGROUND2_COLOR);
  39. labels = new Fl_Group(x, y, 1, 1);
  40. labels->end();
  41. scroll->end();
  42. pages = new Fl_Group(x, y, 1, 1);
  43. pages->end();
  44. Fl_Group::end();
  45. // Just to resize things, and avoid code duplication
  46. client_area(dummy, dummy, dummy, dummy, w/10);
  47. begin();
  48. }
  49. Fl_Navigation::~Fl_Navigation()
  50. {
  51. }
  52. Fl_Widget *Fl_Navigation::value()
  53. {
  54. int i;
  55. for (i = 0;i < pages->children();i++) {
  56. if (pages->child(i)->visible())
  57. return pages->child(i);
  58. }
  59. return NULL;
  60. }
  61. int Fl_Navigation::value(Fl_Widget *newpage)
  62. {
  63. int i;
  64. int found;
  65. assert(labels->children() == pages->children());
  66. found = 0;
  67. for (i = 0;i < pages->children();i++) {
  68. if (pages->child(i) == newpage) {
  69. pages->child(i)->show();
  70. ((Fl_Button*)labels->child(i))->setonly();
  71. found = 1;
  72. } else {
  73. pages->child(i)->hide();
  74. }
  75. }
  76. return found;
  77. }
  78. void Fl_Navigation::client_area(int &rx, int &ry,
  79. int &rw, int &rh, int lw)
  80. {
  81. if (!pages->children()) {
  82. int cx, cy, cw, ch;
  83. cx = x() + 1;
  84. cy = y() + 1;
  85. cw = w() - 2;
  86. ch = h() - 2;
  87. scroll->resize(cx, cy, lw, ch);
  88. labels->resize(cx, cy, lw, ch);
  89. pages->resize(cx + lw + 1, cy, cw - lw - 1, ch);
  90. }
  91. rx = pages->x();
  92. ry = pages->y();
  93. rw = pages->w();
  94. rh = pages->h();
  95. }
  96. void Fl_Navigation::draw()
  97. {
  98. draw_box(FL_BORDER_FRAME, x(), y(),
  99. labels->w()+2, h(), FL_DARK3);
  100. draw_box(FL_BORDER_FRAME, x()+1+labels->w(), y(),
  101. w() - (labels->w()+1), h(), FL_DARK3);
  102. Fl_Group::draw();
  103. }
  104. void Fl_Navigation::begin()
  105. {
  106. pages->begin();
  107. }
  108. void Fl_Navigation::end()
  109. {
  110. pages->end();
  111. Fl_Group::end();
  112. update_labels();
  113. }
  114. void Fl_Navigation::update_labels()
  115. {
  116. int i, offset;
  117. labels->clear();
  118. labels->resizable(NULL);
  119. if (!pages->children())
  120. return;
  121. offset = 0;
  122. for (i = 0;i < pages->children();i++) {
  123. Fl_Widget *page;
  124. Fl_Button *btn;
  125. page = pages->child(i);
  126. btn = new Fl_Button(labels->x(), labels->y() + offset,
  127. labels->w(), page->labelsize() * 3,
  128. page->label());
  129. btn->box(FL_FLAT_BOX);
  130. btn->type(FL_RADIO_BUTTON);
  131. btn->color(FL_BACKGROUND2_COLOR);
  132. btn->selection_color(FL_SELECTION_COLOR);
  133. btn->labelsize(page->labelsize());
  134. btn->labelfont(page->labelfont());
  135. btn->image(page->image());
  136. btn->deimage(page->deimage());
  137. btn->callback(label_pressed, this);
  138. labels->add(btn);
  139. offset += page->labelsize() * 3;
  140. }
  141. labels->size(labels->w(), offset);
  142. // FIXME: Retain selection
  143. value(pages->child(0));
  144. }
  145. void Fl_Navigation::label_pressed(Fl_Widget *widget, void *user_data)
  146. {
  147. Fl_Navigation *self = (Fl_Navigation *) user_data;
  148. int i, idx;
  149. idx = -1;
  150. for (i = 0;i < self->labels->children();i++) {
  151. if (self->labels->child(i) == widget)
  152. idx = i;
  153. }
  154. assert(idx >= 0);
  155. assert(idx < self->pages->children());
  156. self->value(self->pages->child(idx));
  157. }