代码之家  ›  专栏  ›  技术社区  ›  Tea Tree

如何让ControlP5 Dropodownlist打开而不是关闭?

  •  0
  • Tea Tree  · 技术社区  · 3 年前

    使用文档中的MWE:

    import controlP5.*;
    import java.util.*;
    
    
    ControlP5 cp5;
    
    void setup() {
      size(400, 400);
      cp5 = new ControlP5(this);
      List l = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h");
      /* add a ScrollableList, by default it behaves like a DropdownList */
      cp5.addScrollableList("dropdown")
         .setPosition(100, 100)
         .setSize(200, 100)
         .setBarHeight(20)
         .setItemHeight(20)
         .addItems(l)
         // .setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST
         ;
         
         
    }
    
    void draw() {
      background(240);
    }
    

    我怎样才能让下拉列表打开而不是关闭?我正试图将列表放在屏幕的下边缘。我在文档中找不到选项。

    0 回复  |  直到 3 年前
        1
  •  3
  •   George Profenza    3 年前

    因为ControlP5对Java泛型继承的使用在这种情况下实际上相当棘手 ScrollableListView s display() 方法被覆盖:

    • ScrollableList extends Controller< ScrollableList >
    • 在java中,一个类可以子类化一个类,而不是多个类,因此定制的子类类似 PopUpScrollableList 将继承 Controller< ScrollableList > ,不 Controller< PopUpScrollableList >
    • 在中访问了许多属性 可滚动ListView s 显示器() 属于 ScrollableList 它们要么 private protected

    太长,读不下去了 @laancelot建议克隆库,修改 可滚动ListView s 显示器() 与自定义滚动列表相比,直接使用方法并重新编译库听起来更容易。

    话虽如此,对于初学者来说,设置IDE和编译java库可能不是最友好的事情,因此我可以推荐一个简单的解决方法:简单地移动列表的y位置,使其看起来在上方而不是下方:

    import controlP5.*;
    import java.util.*;
    
    
    ControlP5 cp5;
    
    ScrollableList list;
    int listX = 100;
    int listY = 100;
    int listWidth = 200;
    int listHeight = 100;
    int barHeight = 20;
    
    void setup() {
      size(400, 400);
      cp5 = new ControlP5(this);
      List l = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h");
      /* add a ScrollableList, by default it behaves like a DropdownList */
      list = cp5.addScrollableList("dropdown")
         .setPosition(listX, listY)
         .setSize(listWidth, listHeight)
         .setBarHeight(barHeight)
         .setItemHeight(20)
         .addItems(l)
         // .setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST
        ;
     
         
         
    }
    
    void draw() {
      // hack: shift the list up when it's open
      if(list.isOpen()){
        list.setPosition(listX, listY - listHeight + barHeight);
      }else{
        list.setPosition(listX, listY);
      }
      background(240);
    }
    

    controlp5 pop-up list

    它在视觉上并不完美,可能是一种潜在的用户体验,但它是使用ControlP5进行这种自定义行为的最简单选择。

    或者,值得考虑定制不同的UI库或编写自定义列表。

    为了便于讨论,这里是列表示例的修改版本 Guido library :

    /**
     *    A list
     *
     *
     *    Make sure to try your scroll wheel!
     */
    
    import de.bezier.guido.*;
    
    Listbox listbox;
    SimpleButton button;
    Object lastItemClicked;
    
    void setup ()
    {
        size(400, 400);
        
        // make the manager
        
        Interactive.make( this );
        
        // create a list box
        listbox = new Listbox( 20, 30, width-40, height-80 );
        for ( int i = 0, r = int(10+random(100)); i < r; i++ )
        {
            listbox.addItem( "Item " + i );
        }
        listbox.visible = false;
        // create button
        button = new SimpleButton("pop-up list", 20, 350, width-40, 24 );
        
    }
    
    void draw ()
    {
        background( 20 );
        listbox.visible = button.on;
        if ( lastItemClicked != null )
        {
            fill( 255 );
            text( "Clicked " + lastItemClicked.toString(), 30, 20 );
        }
    }
    
    public void itemClicked ( int i, Object item )
    {
        lastItemClicked = item;
    }
    
    public class Listbox
    {
        float x, y, width, height;
        
        ArrayList items;
        int itemHeight = 20;
        int listStartAt = 0;
        int hoverItem = -1;
        
        float valueY = 0;
        boolean hasSlider = false;
        boolean visible = true;
        
        Listbox ( float xx, float yy, float ww, float hh ) 
        {
            x = xx; y = yy;
            valueY = y;
            
            width = ww; height = hh;
            
            // register it
            Interactive.add( this );
        }
        
        public void addItem ( String item )
        {
            if ( items == null ) items = new ArrayList();
            items.add( item );
            
            hasSlider = items.size() * itemHeight > height;
        }
        
        public void mouseMoved ( float mx, float my )
        {
            if(!visible){
              return;
            }
            if ( hasSlider && mx > width-20 ) return;
            
            hoverItem = listStartAt + int((my-y) / itemHeight);
        }
        
        public void mouseExited ( float mx, float my )
        {
            if(!visible){
              return;
            }
            hoverItem = -1;
        }
        
        // called from manager
        void mouseDragged ( float mx, float my )
        {
            if(!visible){
              return;
            }
            if ( !hasSlider ) return;
            if ( mx < x+width-20 ) return;
            
            valueY = my-10;
            valueY = constrain( valueY, y, y+height-20 );
            
            update();
        }
        
        // called from manager
        void mouseScrolled ( float step )
        {
            if(!visible){
              return;
            }
            valueY += step;
            valueY = constrain( valueY, y, y+height-20 );
            
            update();
        }
        
        void update ()
        {
            if(!visible){
              return;
            }
            float totalHeight = items.size() * itemHeight;
            float itemsInView = height / itemHeight;
            float listOffset = map( valueY, y, y+height-20, 0, totalHeight-height );
            
            listStartAt = int( listOffset / itemHeight );
        }
        
        public void mousePressed ( float mx, float my )
        {
            if(!visible){
              return;
            }
            if ( hasSlider && mx > width-20 ) return;
            
            int item = listStartAt + int( (my-y) / itemHeight);
            itemClicked( item, items.get(item) );
        }
    
        void draw ()
        {
            if(!visible){
              return;
            }
            noStroke();
            fill( 100 );
            rect( x,y,this.width,this.height );
            if ( items != null )
            {
                for ( int i = 0; i < int(height/itemHeight) && i < items.size(); i++ )
                {
                    stroke( 80 );
                    fill( (i+listStartAt) == hoverItem ? 200 : 120 );
                    rect( x, y + (i*itemHeight), this.width, itemHeight );
                    
                    noStroke();
                    fill( 0 );
                    text( items.get(i+listStartAt).toString(), x+5, y+(i+1)*itemHeight-5 );
                }
            }
            
            if ( hasSlider )
            {
                stroke( 80 );
                fill( 100 );
                rect( x+width-20, y, 20, height );
                fill( 120 );
                rect( x+width-20, valueY, 20, 20 );
            }
        }
    }
    
    public class SimpleButton
    {
        float x, y, width, height;
        boolean on;
        
        String label = "";
        
        SimpleButton ( float xx, float yy, float w, float h )
        {
            x = xx; y = yy; width = w; height = h;
            
            Interactive.add( this ); // register it with the manager
        }
        
        SimpleButton ( String label, float xx, float yy, float w, float h )
        {
          this(xx, yy, w, h);
          this.label = label;
        }
        
        // called by manager
        
        void mousePressed () 
        {
            on = !on;
        }
    
        void draw () 
        {
            if ( on ) fill( 200 );
            else fill( 100 );
            
            rect(x, y, width, height);
            
            if ( on ) fill( 100 );
            else fill( 200 );
            
            text(label, x + 10, y + this.height * 0.65);
        }
    }
    

    pop up list

    草图中的代码要冗长得多,但可以移动到单独的GUI选项卡中。 希望因为它更简单,所以可以比ControlP5更容易地操纵自定义行为。