/* Copyright 2022 Pierre Ossman for Cendio AB * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "Fl_Navigation.h" Fl_Navigation::Fl_Navigation(int x, int y, int w, int h) : Fl_Group(x, y, w, h) { int dummy; scroll = new Fl_Scroll(x, y, 1, 1); scroll->type(Fl_Scroll::VERTICAL); scroll->color(FL_BACKGROUND2_COLOR); labels = new Fl_Group(x, y, 1, 1); labels->end(); scroll->end(); pages = new Fl_Group(x, y, 1, 1); pages->end(); Fl_Group::end(); // Just to resize things, and avoid code duplication client_area(dummy, dummy, dummy, dummy, w/10); begin(); } Fl_Navigation::~Fl_Navigation() { } Fl_Widget *Fl_Navigation::value() { int i; for (i = 0;i < pages->children();i++) { if (pages->child(i)->visible()) return pages->child(i); } return nullptr; } int Fl_Navigation::value(Fl_Widget *newpage) { int i; int found; assert(labels->children() == pages->children()); found = 0; for (i = 0;i < pages->children();i++) { if (pages->child(i) == newpage) { pages->child(i)->show(); ((Fl_Button*)labels->child(i))->setonly(); found = 1; } else { pages->child(i)->hide(); } } return found; } void Fl_Navigation::client_area(int &rx, int &ry, int &rw, int &rh, int lw) { if (!pages->children()) { int cx, cy, cw, ch; cx = x() + 1; cy = y() + 1; cw = w() - 2; ch = h() - 2; scroll->resize(cx, cy, lw, ch); labels->resize(cx, cy, lw, ch); pages->resize(cx + lw + 1, cy, cw - lw - 1, ch); } rx = pages->x(); ry = pages->y(); rw = pages->w(); rh = pages->h(); } void Fl_Navigation::draw() { draw_box(FL_BORDER_FRAME, x(), y(), labels->w()+2, h(), FL_DARK3); draw_box(FL_BORDER_FRAME, x()+1+labels->w(), y(), w() - (labels->w()+1), h(), FL_DARK3); Fl_Group::draw(); } void Fl_Navigation::begin() { pages->begin(); } void Fl_Navigation::end() { pages->end(); Fl_Group::end(); update_labels(); } void Fl_Navigation::update_labels() { int i, offset; labels->clear(); labels->resizable(nullptr); if (!pages->children()) return; offset = 0; for (i = 0;i < pages->children();i++) { Fl_Widget *page; Fl_Button *btn; page = pages->child(i); btn = new Fl_Button(labels->x(), labels->y() + offset, labels->w(), page->labelsize() * 3, page->label()); btn->box(FL_FLAT_BOX); btn->type(FL_RADIO_BUTTON); btn->color(FL_BACKGROUND2_COLOR); btn->selection_color(FL_SELECTION_COLOR); btn->labelsize(page->labelsize()); btn->labelfont(page->labelfont()); btn->image(page->image()); btn->deimage(page->deimage()); btn->callback(label_pressed, this); labels->add(btn); offset += page->labelsize() * 3; } labels->size(labels->w(), offset); // FIXME: Retain selection value(pages->child(0)); } void Fl_Navigation::label_pressed(Fl_Widget *widget, void *user_data) { Fl_Navigation *self = (Fl_Navigation *) user_data; int i, idx; idx = -1; for (i = 0;i < self->labels->children();i++) { if (self->labels->child(i) == widget) idx = i; } assert(idx >= 0); assert(idx < self->pages->children()); self->value(self->pages->child(idx)); }