// scroldlg.h - defines scrollable dialog and group classes.
//    Copyright (C) 2000 Laurynas Biveinis <lauras@softhome.net>
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
#ifndef SCROLDLG_H_
#define SCROLDLG_H_

#include "global.h"

#define Uses_TBackground
#define Uses_TDialog
#define Uses_TGroup
#define Uses_TRect
#define Uses_TScrollBar
#include <rhtvision/tv.h>

// This class is taken (and heavily edited) from Patrick Reilly's
// demo example (released into public domain), distributed with TVision
// port to DJGPP.

// Insert scrollable controls into this group and not into dialog itself.
class scrollable_group : public TGroup
{
   public:
      scrollable_group(const TRect& bounds);

      virtual void changeBounds(const TRect&);
      virtual void handleEvent(TEvent&);
      virtual void scrollDraw();
      virtual void scrollTo(int, int);
      virtual void setLimit(int, int);
      virtual void setState(ushort, Boolean);
      virtual void focusSubView(TView*);

      void insert_scrollbars(TDialog * dlg);
      
   private:
      TScrollBar * hsb;
      TScrollBar * vsb;
      TPoint delta;
      TPoint limit;
};

inline void scrollable_group::insert_scrollbars(TDialog * dlg)
{
   dlg->insert(hsb);
   dlg->insert(vsb);
}

// Insert scrollable groups into dialogs of this type, and switching
// controls with Tab and Shift-Tab will work.
// Interface is simplified, because we support just one scrollable group.
class scroll_dialog : public TDialog
{
   public:
      scroll_dialog(const TRect & bounds, const char * title);
      virtual void handleEvent(TEvent & what);

      void insert_scroll_group(scrollable_group * group);
      void insert_in_group(TView * view) const;
      void fill_next_row(TView * view);

      // Following function should be redefined selectNext instead; however
      // for that TGroup::selectNext should be declared virtual, however it is
      // not. PITA.
      void select_next(int direction);

   private:
      scrollable_group * scroll_group;
      TRect empty_row;
};

inline scroll_dialog::scroll_dialog(const TRect& bounds, const char* aTitle) :
   TDialog(bounds, aTitle),
   TWindowInit(initFrame),
   empty_row(TRect(0, 0, size.x, 1))
{
}

inline void scroll_dialog::insert_scroll_group(scrollable_group * group)
{
   TDialog::insert(group);
   scroll_group = group;
   scroll_group->insert_scrollbars(this);
}

inline void scroll_dialog::insert_in_group(TView * view) const
{
   scroll_group->insert(view);
}

inline void scroll_dialog::fill_next_row(TView * view)
{
   view->locate(empty_row);
   insert_in_group(view);
   empty_row.a.y++;
   empty_row.b.y++;
}

#endif
