root/headers/private/interface/ColumnListView.h
/*
Open Tracker License

Terms and Conditions

Copyright (c) 1991-2000, Be Incorporated. All rights reserved.

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 applies to all licensees
and 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 TITLE, MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BE INCORPORATED 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.

Except as contained in this notice, the name of Be Incorporated shall not be
used in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from Be Incorporated.

Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
of Be Incorporated in the United States and other countries. Other brand product
names are registered trademarks or trademarks of their respective holders.
All rights reserved.
*/

/*******************************************************************************
/
/       File:                   ColumnListView.h
/
/   Description:    Experimental multi-column list view.
/
/       Copyright 2000+, Be Incorporated, All Rights Reserved
/
*******************************************************************************/


#ifndef _COLUMN_LIST_VIEW_H
#define _COLUMN_LIST_VIEW_H

#include <BeBuild.h>
#include <View.h>
#include <List.h>
#include <Invoker.h>
#include <ListView.h>

class BScrollBar;

namespace BPrivate {

class OutlineView;
class TitleView;
class BRowContainer;
class RecursiveOutlineIterator;

}       // ns BPrivate

class BColumn;
class BColumnListView;
class BField;
class BRow;

enum LatchType {
        B_NO_LATCH                                      = 0,
        B_OPEN_LATCH                            = 1,
        B_PRESSED_LATCH                         = 2,
        B_CLOSED_LATCH                          = 3
};

typedef enum {
        B_ALLOW_COLUMN_NONE                     = 0,
        B_ALLOW_COLUMN_MOVE                     = 1,
        B_ALLOW_COLUMN_RESIZE           = 2,
        B_ALLOW_COLUMN_POPUP            = 4,
        B_ALLOW_COLUMN_REMOVE           = 8
} column_flags;

enum ColumnListViewColor {
        B_COLOR_BACKGROUND                      = 0,
        B_COLOR_TEXT                            = 1,
        B_COLOR_ROW_DIVIDER                     = 2,
        B_COLOR_SELECTION                       = 3,
        B_COLOR_SELECTION_TEXT          = 4,
        B_COLOR_NON_FOCUS_SELECTION     = 5,
        B_COLOR_EDIT_BACKGROUND         = 6,
        B_COLOR_EDIT_TEXT                       = 7,
        B_COLOR_HEADER_BACKGROUND       = 8,
        B_COLOR_HEADER_TEXT                     = 9,
        B_COLOR_SEPARATOR_LINE          = 10,
        B_COLOR_SEPARATOR_BORDER        = 11,

        B_COLOR_TOTAL                           = 12
};

enum ColumnListViewFont {
        B_FONT_ROW                                      = 0,
        B_FONT_HEADER                           = 1,

        B_FONT_TOTAL                            = 2
};


// A single row/column intersection in the list.
class BField {
public:
                                                                BField();
        virtual                                         ~BField();
};

// A single line in the list.  Each line contains a BField object
// for each column in the list, associated by their "logical field"
// index.  Hierarchies are formed by adding other BRow objects as
// a parent of a row, using the AddRow() function in BColumnListView().
class BRow {
public:
                                                                BRow();
                                                                BRow(float height);
        virtual                                         ~BRow();
        virtual bool                            HasLatch() const;

                        int32                           CountFields() const;
                        BField*                         GetField(int32 logicalFieldIndex);
        const   BField*                         GetField(int32 logicalFieldIndex) const;
                        void                            SetField(BField* field,
                                                                        int32 logicalFieldIndex);

                        float                           Height() const;
                        bool                            IsExpanded() const;
                        bool                            IsSelected() const;

                        void                            Invalidate();

private:
        // Blows up into the debugger if the validation fails.
                        void                            ValidateFields() const;
                        void                            ValidateField(const BField* field,
                                                                        int32 logicalFieldIndex) const;
private:
                        BList                           fFields;
                        BPrivate::
                        BRowContainer*          fChildList;
                        bool                            fIsExpanded;
                        float                           fHeight;
                        BRow*                           fNextSelected;
                        BRow*                           fPrevSelected;
                        BRow*                           fParent;
                        BColumnListView*        fList;


        friend class BColumnListView;
        friend class BPrivate::RecursiveOutlineIterator;
        friend class BPrivate::OutlineView;
};

// Information about a single column in the list.  A column knows
// how to display the BField objects that occur at its location in
// each of the list's rows.  See ColumnTypes.h for particular
// subclasses of BField and BColumn that handle common data types.
class BColumn {
public:
                                                                BColumn(float width, float minWidth,
                                                                        float maxWidth,
                                                                        alignment align = B_ALIGN_LEFT);
        virtual                                         ~BColumn();

                        float                           Width() const;
                        void                            SetWidth(float width);
                        float                           MinWidth() const;
                        float                           MaxWidth() const;

        virtual void                            DrawTitle(BRect rect, BView* targetView);
        virtual void                            DrawField(BField* field, BRect rect,
                                                                        BView* targetView);
        virtual int                                     CompareFields(BField* field1, BField* field2);

        virtual void                            MouseMoved(BColumnListView* parent, BRow* row,
                                                                        BField* field, BRect fieldRect,
                                                                        BPoint point, uint32 buttons, int32 code);
        virtual void                            MouseDown(BColumnListView* parent, BRow* row,
                                                                        BField* field, BRect fieldRect,
                                                                        BPoint point, uint32 buttons);
        virtual void                            MouseUp(BColumnListView* parent, BRow* row,
                                                                        BField* field);

        virtual void                            GetColumnName(BString* into) const;
        virtual float                           GetPreferredWidth(BField* field,
                                                                        BView* parent) const;

                        bool                            IsVisible() const;
                        void                            SetVisible(bool);

                        bool                            WantsEvents() const;
                        void                            SetWantsEvents(bool);

                        bool                            ShowHeading() const;
                        void                            SetShowHeading(bool);

                        alignment                       Alignment() const;
                        void                            SetAlignment(alignment);

                        int32                           LogicalFieldNum() const;

        /*!
                \param field The BField derivative to validate.

                        Implement this function on your BColumn derivatives to validate
                        BField derivatives that your BColumn will be drawing/manipulating.

                        This function will be called when BFields are added to the Column,
                        use dynamic_cast<> to determine if it is of a kind that your
                        BColumn know how ot handle. return false if it is not.

                        \note The debugger will be called if you return false from here
                        with information about what type of BField and BColumn and the
                        logical field index where it occured.

                        \note Do not call the inherited version of this, it just returns
                        true;
          */
        virtual bool                            AcceptsField(const BField* field) const;

private:
                        float                           fWidth;
                        float                           fMinWidth;
                        float                           fMaxWidth;
                        bool                            fVisible;
                        int32                           fFieldID;
                        BColumnListView*        fList;
                        bool                            fSortAscending;
                        bool                            fWantsEvents;
                        bool                            fShowHeading;
                        alignment                       fAlignment;

        friend class BPrivate::OutlineView;
        friend class BColumnListView;
        friend class BPrivate::TitleView;
};

// The column list view class.
class BColumnListView : public BView, public BInvoker {
public:
                                                                BColumnListView(BRect rect,
                                                                        const char* name, uint32 resizingMode,
                                                                        uint32 flags, border_style = B_NO_BORDER,
                                                                        bool showHorizontalScrollbar = true);
                                                                BColumnListView(const char* name,
                                                                        uint32 flags, border_style = B_NO_BORDER,
                                                                        bool showHorizontalScrollbar = true);
        virtual                                         ~BColumnListView();

        // Interaction
        virtual bool                            InitiateDrag(BPoint, bool wasSelected);
        virtual void                            MessageDropped(BMessage*, BPoint point);
        virtual void                            ExpandOrCollapse(BRow* row, bool expand);
        virtual status_t                        Invoke(BMessage* message = NULL);
        virtual void                            ItemInvoked();
        virtual void                            SetInvocationMessage(BMessage* message);
                        BMessage*                       InvocationMessage() const;
                        uint32                          InvocationCommand() const;
                        BRow*                           FocusRow() const;
                        void                            SetFocusRow(int32 index, bool select = false);
                        void                            SetFocusRow(BRow* row, bool select = false);
                        void                            SetMouseTrackingEnabled(bool);

        // Selection
                        list_view_type          SelectionMode() const;
                        void                            Deselect(BRow* row);
                        void                            AddToSelection(BRow* row);
                        void                            DeselectAll();
                        BRow*                           CurrentSelection(BRow* lastSelected = 0) const;
        virtual void                            SelectionChanged();
        virtual void                            SetSelectionMessage(BMessage* message);
                        BMessage*                       SelectionMessage();
                        uint32                          SelectionCommand() const;
                        void                            SetSelectionMode(list_view_type type);
                                // list_view_type is defined in ListView.h.

        // Sorting
                        void                            SetSortingEnabled(bool);
                        bool                            SortingEnabled() const;
                        void                            SetSortColumn(BColumn* column, bool add,
                                                                        bool ascending);
                        void                            ClearSortColumns();

        // The status view is a little area in the lower left hand corner.
                        void                            AddStatusView(BView* view);
                        BView*                          RemoveStatusView();

        // Column Manipulation
                        void                            AddColumn(BColumn* column,
                                                                        int32 logicalFieldIndex);
                        void                            MoveColumn(BColumn* column, int32 index);
                        void                            RemoveColumn(BColumn* column);
                        int32                           CountColumns() const;
                        BColumn*                        ColumnAt(int32 index) const;
                        BColumn*                        ColumnAt(BPoint point) const;
                        void                            SetColumnVisible(BColumn* column,
                                                                        bool isVisible);
                        void                            SetColumnVisible(int32, bool);
                        bool                            IsColumnVisible(int32) const;
                        void                            SetColumnFlags(column_flags flags);
                        void                            ResizeColumnToPreferred(int32 index);
                        void                            ResizeAllColumnsToPreferred();

        // Row manipulation
                        const BRow*                     RowAt(int32 index, BRow *parent = 0) const;
                        BRow*                           RowAt(int32 index, BRow *parent = 0);
                        const BRow*                     RowAt(BPoint) const;
                        BRow*                           RowAt(BPoint);
                        bool                            GetRowRect(const BRow* row, BRect* _rect) const;
                        bool                            FindParent(BRow* row, BRow** _parent,
                                                                        bool *_isVisible) const;
                        int32                           IndexOf(BRow* row);
                        int32                           CountRows(BRow* parent = 0) const;
                        void                            AddRow(BRow* row, BRow* parent = NULL);
                        void                            AddRow(BRow* row, int32 index,
                                                                        BRow* parent = NULL);
                        void                            AddRows(BList* rows, int32 index,
                                                                        BRow* parent = NULL);

                        void                            ScrollTo(const BRow* Row);
                        void                            ScrollTo(BPoint point);

        // Does not delete row or children at this time.
        // todo: Make delete row and children
                        void                            RemoveRow(BRow* row);
                        void                            RemoveRows(BList* rows);
                        void                            UpdateRow(BRow* row);
                        bool                            SwapRows(int32 index1, int32 index2, BRow*
                                                                        parentRow1 = NULL, BRow* parentRow2 = NULL);
                        void                            Clear();

                        void                            InvalidateRow(BRow* row);

        // Appearance (DEPRECATED)
                        void                            GetFont(BFont* font) const
                                                                        { BView::GetFont(font); }
        virtual void                            SetFont(const BFont* font,
                                                                        uint32 mask = B_FONT_ALL);
        virtual void                            SetHighColor(rgb_color);
                        void                            SetSelectionColor(rgb_color);
                        void                            SetBackgroundColor(rgb_color);
                        void                            SetEditColor(rgb_color);
                        const rgb_color         SelectionColor() const;
                        const rgb_color         BackgroundColor() const;
                        const rgb_color         EditColor() const;

        // Appearance (NEW STYLE)
                        void                            SetColor(ColumnListViewColor colorIndex,
                                                                        rgb_color color);
                        void                            ResetColors();
                        void                            SetFont(ColumnListViewFont fontIndex,
                                                                        const BFont* font,
                                                                        uint32 mask = B_FONT_ALL);
                        rgb_color                       Color(ColumnListViewColor colorIndex) const;
                        void                            GetFont(ColumnListViewFont fontIndex,
                                                                        BFont* font) const;

                        BPoint                          SuggestTextPosition(const BRow* row,
                                                                        const BColumn* column = NULL) const;

                        BRect                           GetFieldRect(const BRow* row,
                                                                        const BColumn* column) const;

                        void                            SetLatchWidth(float width);
                        float                           LatchWidth() const;
        virtual void                            DrawLatch(BView* view, BRect frame,
                                                                        LatchType type, BRow* row);
        virtual void                            MakeFocus(bool isfocus = true);
                        void                            SaveState(BMessage* archive);
                        void                            LoadState(BMessage* archive);

                        BView*                          ScrollView() const
                                                                        { return (BView*)fOutlineView; }
                        void                            SetEditMode(bool state);
                        void                            Refresh();

        virtual BSize                           MinSize();
        virtual BSize                           PreferredSize();
        virtual BSize                           MaxSize();


protected:
        virtual void                            MessageReceived(BMessage* message);
        virtual void                            KeyDown(const char* bytes, int32 numBytes);
        virtual void                            AttachedToWindow();
        virtual void                            WindowActivated(bool active);
        virtual void                            Draw(BRect updateRect);

        virtual void                            LayoutInvalidated(bool descendants = false);
        virtual void                            DoLayout();

private:
                        void                            _Init();
                        void                            _UpdateColors();
                        void                            _GetChildViewRects(const BRect& bounds,
                                                                        BRect& titleRect, BRect& outlineRect,
                                                                        BRect& vScrollBarRect,
                                                                        BRect& hScrollBarRect);

                        rgb_color                       fColorList[B_COLOR_TOTAL];
                        bool                            fCustomColors;
                        BPrivate::TitleView* fTitleView;
                        BPrivate::OutlineView* fOutlineView;
                        BList                           fColumns;
                        BScrollBar*                     fHorizontalScrollBar;
                        BScrollBar*             fVerticalScrollBar;
                        BList                           fSortColumns;
                        BView*                          fStatusView;
                        BMessage*                       fSelectionMessage;
                        bool                            fSortingEnabled;
                        float                           fLatchWidth;
                        border_style            fBorderStyle;
                        bool                            fShowingHorizontalScrollBar;
};

#endif // _COLUMN_LIST_VIEW_H