微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何让 ControlP5 Dropodownlist 打开而不是向下?

如何解决如何让 ControlP5 Dropodownlist 打开而不是向下?

使用文档中的这个 MWE:

CronJob

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

解决方法

因为 ControlP5 使用 Java 泛型继承实际上在这种情况下非常棘手,应该覆盖 ScrollableListViewdisplay() 方法:

  • ScrollableList extends Controller< ScrollableList >
  • 在java中,一个类可以子类化单个类,而不是多个类,因此像PopUpScrollableList这样的自定义子类将继承Controller< ScrollableList >,而不是Controller< PopUpScrollableList >
  • ScrollableListViewdisplay() 中访问了一堆属于 ScrollableList 的属性,它们是 privateprotected

TLDR; @laancelot 建议克隆库,直接修改 ScrollableListViewdisplay() 方法并重新编译库,与子类化和自定义滚动列表相比,这听起来更容易。

话虽如此,对于初学者来说,设置 IDE 和编译 Java 库可能不是最友好的事情,因此我可以推荐一个hacky 解决方法:只需移动列表的 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,24 );
    
}

void draw ()
{
    background( 20 );
    listbox.visible = button.on;
    if ( lastItemClicked != null )
    {
        fill( 255 );
        text( "Clicked " + lastItemClicked.toString(),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+height-20 );
        
        update();
    }
    
    // called from manager
    void mouseScrolled ( float step )
    {
        if(!visible){
          return;
        }
        valueY += step;
        valueY = constrain( valueY,y+height-20 );
        
        update();
    }
    
    void update ()
    {
        if(!visible){
          return;
        }
        float totalHeight = items.size() * itemHeight;
        float itemsInView = height / itemHeight;
        float listOffset = map( valueY,y+height-20,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,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),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,height );
            fill( 120 );
            rect( x+width-20,valueY,20 );
        }
    }
}

public class SimpleButton
{
    float x,height;
    boolean on;
    
    String label = "";
    
    SimpleButton ( float xx,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 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,height);
        
        if ( on ) fill( 100 );
        else fill( 200 );
        
        text(label,x + 10,y + this.height * 0.65);
    }
}

pop up list

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。