SOL9 2.0 Class: SplitPane

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * SplitPane.h 
 * Copyright (c) 2011 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL++2000
// 2000.02.18
#pragma once

#include <sol\Composite.h>
#include <sol\Sash.h>
#include <sol\ClientDC.h>

namespace SOL {

class SplitPane :public Composite {
private:
    int        direction;

    Sash    sash;
    View*    first;
    View*    second;
    int        position;

private:
    void arrange(Action& action)
    {
        RECT rec;
        getClientRect(&rec);
        int w = rec.right;
        int h = rec.bottom;

        RECT r;
        sash.getWindowRect(&r);
        POINT p;
        p.x = r.left;
        p.y = r.top;
        ::ScreenToClient(getWindow(), &p);

        int thickness = sash.getThickness();

        if (direction == VERTICAL) {
            position = p.y;

            if(first) {
                first -> reshape(0, 0, w, position);
            }

            sash.reshape(0, position, w, thickness);
            if(second) {
                //<added date="2000.07.03">
                second -> update();
                //</added>
                second -> reshape(0, position+thickness, 
                    w, h-position-thickness);
            }
        }

        if (direction == HORIZONTAL) {
            position = p.x;
            if(first) {
                first -> reshape(0, 0, position, h);
            }

            sash.reshape(position, 0, thickness, h);
            if(second) {
                //<added date="2000.07.03">
                second -> update(NULL);
                //</added>
                second -> reshape(position+thickness, 0, 
                    w-position-thickness, h);
            }
        }
    }

private:
    long  size(Event& event)
    {
        RECT     rec;
        getClientRect(&rec);
        int w = rec.right;
        int h = rec.bottom;

        int thickness = sash.getThickness();

        RECT cr;
        sash.getClientRect(&cr);
        int pos = 0;

        if (direction == VERTICAL) {
            if (position - 10> h) {
                pos = h - thickness;
                if(first) {
                    first -> reshape(0, 0, w, pos);
                }
                sash.reshape(0, pos, w, thickness);
                if(second) {
                    second->reshape(0, pos+thickness, w, 2);
                }
            }
            else {
                if(first) {
                    //first -> reshape(0, 0, w, position);
                    first -> reshape(0, 0, position, w);

                }
                sash.reshape(0, position, w, thickness);
                if(second) {
                    second -> reshape(0, position+thickness, 
                        w, h-position-thickness);
                }
            }
        }

        if (direction == HORIZONTAL) {
            if (position - 10> w) {
                pos = w - thickness;
                if(first) {
                    first -> reshape(0, 0, pos, h);
                }
                sash.reshape(pos, 0, thickness, h);
                if(second) {
                    second->reshape(pos+thickness, 0, 2, h);
                }
            }
            else {
                if(first) {
                    first -> reshape(0, 0, position, h);
                }
                sash.reshape(position, 0, thickness, h);
                if(second) {
                    second -> reshape(position+thickness, 0, 
                        w-position-thickness, h);
                }
            }
        }
        //2009/11/16
        if (first) {
            first->update();
        }
        if (second) {
            second->update();
        }
        return NULL;
    }
  
public:
    static const int VERTICAL   = 0;
    static const int HORIZONTAL = 1;
  
public:
    SplitPane():Composite() { }

public:
    SplitPane(View* parent, const TCHAR* label, Args& args)
    :Composite(parent, label, 
            args.set(XmNstyle, (ulong)(WS_VISIBLE|WS_CHILD) )
                .set(XmNclassName, _T("SplitPane"))
                .set(XmNclassStyle, 0))
    {
        first  = NULL;
        second = NULL;
        RECT rc;
        getClientRect(&rc);
        position = 80;

        direction   = VERTICAL;
        ulong val = 0;
        if (args.get(XmNdirection, &val)) {
            direction = (int)val;
        }

        int dir = Sash::VERTICAL;
        HCURSOR cursor = LoadCursor(NULL, IDC_SIZENS);
        if (direction == HORIZONTAL) {
            dir = Sash::HORIZONTAL;
            cursor = LoadCursor(NULL, IDC_SIZEWE);
        }

        Args ar;
        ar.set(XmNdirection, dir);
        ar.set(XmNcursor, (ulong)cursor);
        sash.create(this, _T(""), ar);
        sash.addCallback(XmNdragFinishedCallback, this,
            (Callback)&SplitPane::arrange, NULL);

        addEventHandler(WM_SIZE, this, 
            (Handler)&SplitPane::size, NULL);

        setValues(args);
    }

public:
    virtual Boolean create(View* parent, const TCHAR* label, Args& args)
    {
        Boolean rc = Composite::create(parent, label, 
            args.set(XmNstyle, (ulong)(WS_VISIBLE|WS_CHILD) )
                .set(XmNclassName, _T("SplitPane"))
                .set(XmNclassStyle, 0));

        first  = NULL;
        second = NULL;
        //RECT r;
        //getClientRect(&r);
        position = 80;

        direction   = VERTICAL;
        ulong val = 0;
        if (args.get(XmNdirection, &val)) {
            direction = (int)val;
        }

        int dir = Sash::VERTICAL;
        HCURSOR cursor = LoadCursor(NULL, IDC_SIZENS);
        if (direction == HORIZONTAL) {
            dir = Sash::HORIZONTAL;
            cursor = LoadCursor(NULL, IDC_SIZEWE);
        }

        Args ar;
        ar.set(XmNdirection, dir);
        ar.set(XmNcursor, (ulong)cursor);
        sash.create(this, _T(""), ar);
        sash.addCallback(XmNdragFinishedCallback, this,
            (Callback)&SplitPane::arrange, NULL);

        addEventHandler(WM_SIZE, this, 
            (Handler)&SplitPane::size, NULL);

        setValues(args);
        return rc;
    }

public:
    void add(View* view1)
    {
        if(first == NULL) {
            first = view1;
        }
        else {
            second = view1;
        }
        RECT    rc;
        getClientRect(&rc);
        send(WM_SIZE, 0, MAKELONG(rc.right, rc.bottom));
    }

public:
    void setSashPosition(int pos)
    {
        RECT    rc;
        getClientRect(&rc);

        //<added date="2000.06.30">
        position = pos;
        //</added>

        if (direction == VERTICAL) {
            if(pos > 0 && pos <rc.bottom) {
                position = pos;
                RECT    rc;
                getClientRect(&rc);
                send(WM_SIZE, 0, MAKELONG(rc.right, rc.bottom));
            }
        }

        if (direction == HORIZONTAL) {
            if(pos > 0 && pos <rc.right) {
                position = pos;
                RECT    rc;
                getClientRect(&rc);
                send(WM_SIZE, 0, MAKELONG(rc.right, rc.bottom));
            }
        }
    }


    int        getSashPosition() { 
        return position; 
    }
};

}



Last modified: 1 Feb 2012

Copyright (c) 2009-2012 Antillia.com ALL RIGHTS RESERVED.