Changeset 1276

Show
Ignore:
Timestamp:
06/23/08 14:51:11 (3 months ago)
Author:
drobilla
Message:

Arrange embedded widgets more sanely if placing ports below GUI doesn't work well.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • flowcanvas/flowcanvas/Module.hpp

    r1274 r1276  
    7878        size_t num_ports() const { return _ports.size(); } 
    7979 
    80         void   set_ports_y_offset(double offset)   { _ports_y_offset = offset; } 
    81         double ports_y_offset(double offset) const { return _ports_y_offset; } 
    82  
    8380protected: 
    8481        virtual void on_drop(double new_x, double new_y); 
     
    9491        double _border_width; 
    9592        bool   _title_visible; 
    96         double _ports_y_offset; 
     93        double _embed_width; 
     94        double _embed_height; 
    9795        double _icon_size; 
    98  
    9996        double _widest_input; 
    10097        double _widest_output; 
     
    120117         
    121118        void embed_size_request(Gtk::Requisition* req, bool force); 
    122          
    123         int _last_embed_request_width; 
    124         int _last_embed_request_height; 
    125119}; 
    126120 
  • flowcanvas/src/Module.cpp

    r1274 r1276  
    5050        , _border_width(1.0) 
    5151        , _title_visible(show_title) 
    52         , _ports_y_offset(0) 
     52        , _embed_width(0) 
     53        , _embed_height(0) 
    5354        , _icon_size(16) 
    5455        , _widest_input(0) 
     
    6061        , _embed_container(NULL) 
    6162        , _embed_item(NULL) 
    62         , _last_embed_request_width(0) 
    63         , _last_embed_request_height(0) 
    6463{ 
    6564        _module_box.property_fill_color_rgba() = MODULE_FILL_COLOUR; 
     
    436435                delete _embed_item; 
    437436                _embed_item = NULL; 
    438                 _ports_y_offset = 0; 
    439                 _minimum_width = 0; // resize() will takes care of this 
     437                _embed_width = 0; 
     438                _embed_height = 0; 
    440439                return; 
    441440        } else { 
     
    464463Module::embed_size_request(Gtk::Requisition* r, bool force) 
    465464{ 
    466         if (!force && _last_embed_request_width == r->width && _last_embed_request_height == r->height) 
     465        if (!force && _embed_width == r->width && _embed_height == r->height) 
    467466                return; 
    468467 
    469         if (r->width + 4 > _width) 
    470                set_minimum_width(r->width + 4)
    471          
    472         _ports_y_offset = r->height + 2
    473          
     468        _embed_width = r->width; 
     469        _embed_height = r->height
     470         
     471        cerr << "*** EMBED WIDTH: " << r->width << endl
     472 
    474473        resize(); 
    475474 
     
    479478 
    480479        _embed_container->size_allocate(allocation); 
    481         _embed_item->property_width() = _width - 4; 
     480        _embed_item->property_width() = r->width - 4; 
    482481        _embed_item->property_height() = r->height; 
    483  
    484         _last_embed_request_width = r->width; 
    485         _last_embed_request_height = r->height; 
    486482} 
    487483 
     
    494490        // The amount of space between a port edge and the module edge (on the 
    495491        // side that the port isn't right on the edge). 
    496         const double hor_pad = (_title_visible ? 8.0 : 16.0); 
     492        const double hor_pad = (_title_visible ? 10.0 : 20.0); 
    497493         
    498494        double width = (_title_visible 
    499                 ? _canvas_title.property_text_width() + 8.0 
     495                ? _canvas_title.property_text_width() + 10.0 
    500496                : 1.0); 
    501497         
     
    504500 
    505501        // Fit ports to module (or vice-versa) 
    506         if (_widest_input < width - hor_pad) 
    507                 _widest_input = width - hor_pad; 
    508         if (_widest_output < width - hor_pad) 
    509                 _widest_output = width - hor_pad; 
    510  
    511         width = std::max(width, 
    512                         (std::max(_widest_input, _widest_output) + hor_pad)); 
    513                         
     502        double widest_in  = (_embed_item ? _widest_input  : std::max(_widest_input,  width - hor_pad)); 
     503        double widest_out = (_embed_item ? _widest_output : std::max(_widest_output, width - hor_pad)); 
     504         
     505        const double widest = std::max(widest_in, widest_out); 
     506        const double title_height = _canvas_title.property_text_height(); 
     507 
     508        double above_w   = std::max(width, widest + hor_pad); 
     509        double between_w = std::max(width, widest_in + widest_out + _embed_width); 
     510         
     511        above_w = std::max(above_w, _embed_width); 
     512 
     513        // Basic height contains title, icon 
     514        double header_height = 2; 
     515        if (_title_visible) 
     516                header_height += 2 + title_height; 
     517        if (_icon_box && _icon_size > title_height) 
     518                header_height += _icon_size - title_height; 
     519 
     520        double height = header_height; 
     521 
     522        double above_h = 0.0f; 
     523        if (_ports.size() > 0) 
     524                above_h += _ports.size() * ((*_ports.begin())->height()+2.0); 
     525 
     526        double between_h = std::max(above_h, _embed_height); 
     527        above_h += _embed_height; 
     528         
     529        // Decide where to place embedded widget if necessary (minimize area) 
     530        enum { BETWEEN, ABOVE } embed_pos = ABOVE; 
     531        if (above_w * above_h > between_w * between_h) { 
     532                embed_pos = BETWEEN; 
     533                height += between_h; 
     534                width = between_w; 
     535                if (_embed_item) 
     536                        _embed_item->property_x() = widest_in; 
     537        } else { 
     538                height += above_h; 
     539                width = above_w; 
     540        } 
     541 
     542        if (!_title_visible) { 
     543                if (_ports.size() > 0) 
     544                        height += 0.5; 
     545                if (_widest_input == 0.0 || _widest_output == 0.0f) 
     546                        width += 10.0; 
     547        } 
     548 
    514549        width += _border_width * 2.0; 
    515  
    516         if (width > _minimum_width) 
    517                 set_width(width); 
    518         else if (_width < _minimum_width) 
    519                 set_width(_minimum_width); 
    520          
    521         const double title_height = _canvas_title.property_text_height(); 
    522  
    523         // Set height to contain ports and title 
    524         double height_base = 2; 
    525         if (_title_visible) 
    526                 height_base += 2 + title_height; 
    527          
    528         if (_icon_box && _icon_size > title_height) 
    529                 height_base += _icon_size - title_height; 
    530  
    531         height_base += _ports_y_offset; 
    532  
    533         double h = height_base; 
    534         if (_ports.size() > 0) 
    535                 h += _ports.size() * ((*_ports.begin())->height()+2.0); 
    536  
    537         if (!_title_visible && _ports.size() > 0) 
    538                 h += 0.5; 
    539  
    540         set_height(h); 
     550         
     551        // Actually set width and height 
     552        set_width(width); 
     553        set_height(height); 
     554         
     555        // Offset ports below embedded widget 
     556        if (embed_pos == ABOVE) { 
     557                header_height += _embed_height; 
     558        } 
    541559         
    542560        // Move ports to appropriate locations 
    543          
    544561        int i = 0; 
    545562        for (PortVector::iterator pi = _ports.begin(); pi != _ports.end(); ++pi, ++i) { 
    546563                const boost::shared_ptr<Port> p = (*pi); 
    547564 
    548                 const double y = height_base + (i * (p->height() + 2.0)); 
     565                const double y = header_height + (i * (p->height() + 2.0)); 
    549566                if (p->is_input()) { 
    550                         p->set_width(_widest_input); 
     567                        p->set_width(widest_in); 
    551568                        p->property_x() = 0.5; 
    552569                        p->property_y() = y; 
    553570                } else { 
    554                         p->set_width(_widest_output); 
     571                        p->set_width(widest_out); 
    555572                        p->property_x() = _width - p->width() - 0.5; 
    556573                        p->property_y() = y;