UI: List Template tweaks to get it a bit more usable
* Mouse wheel now scrolls the list. * Up/down key and alt mouse wheel change the active item. * Adding/removing items from the list now automatically scrolls so the active item is in the view. * Shift mouse wheel changes the size of the list widget to display more items. Lazy replacement for a proper grip. * Shape key list now displays the influence value next to the name, * Also fix the range of the value slider to match the defined min/max range.
This commit is contained in:
@@ -148,6 +148,7 @@ typedef struct uiLayout uiLayout;
|
||||
#define UI_BUT_LAST_ACTIVE (1<<24)
|
||||
#define UI_BUT_UNDO (1<<25)
|
||||
#define UI_BUT_IMMEDIATE (1<<26)
|
||||
#define UI_BUT_NO_TOOLTIP (1<<27)
|
||||
|
||||
#define UI_PANEL_WIDTH 340
|
||||
#define UI_COMPACT_PANEL_WIDTH 160
|
||||
@@ -603,16 +604,17 @@ int uiLayoutGetKeepAspect(uiLayout *layout);
|
||||
int uiLayoutGetWidth(uiLayout *layout);
|
||||
float uiLayoutGetScaleX(uiLayout *layout);
|
||||
float uiLayoutGetScaleY(uiLayout *layout);
|
||||
ListBase *uiLayoutBoxGetList(uiLayout *layout);
|
||||
|
||||
/* layout specifiers */
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutColumn(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align);
|
||||
uiLayout *uiLayoutBox(uiLayout *layout);
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout);
|
||||
uiLayout *uiLayoutFree(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop,
|
||||
struct PointerRNA *actptr, struct PropertyRNA *actprop);
|
||||
uiLayout *uiLayoutAbsolute(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage);
|
||||
uiLayout *uiLayoutOverlap(uiLayout *layout);
|
||||
|
||||
uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout);
|
||||
|
||||
@@ -639,14 +641,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
|
||||
void uiTemplate_view3d_select_faceselmenu(uiLayout *layout, struct bContext *C);
|
||||
void uiTemplateTextureImage(uiLayout *layout, struct bContext *C, struct Tex *tex);
|
||||
|
||||
typedef struct uiListItem {
|
||||
struct uiListItem *next, *prev;
|
||||
|
||||
struct PointerRNA data;
|
||||
uiLayout *layout;
|
||||
} uiListItem;
|
||||
|
||||
ListBase uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int type);
|
||||
void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int type);
|
||||
|
||||
/* items */
|
||||
void uiItemO(uiLayout *layout, char *name, int icon, char *opname);
|
||||
|
||||
@@ -1944,8 +1944,11 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
|
||||
{
|
||||
if(data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
if(ELEM4(event->type, LEFTMOUSE, PADENTER, RETKEY, EVT_BUT_OPEN) && event->val==KM_PRESS) {
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
if(but->dt == UI_EMBOSSN && !event->ctrl);
|
||||
else {
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(data->state == BUTTON_STATE_TEXT_EDITING) {
|
||||
@@ -3653,15 +3656,35 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
|
||||
if(but->flag & UI_HIDDEN)
|
||||
continue;
|
||||
if(ui_but_contains_pt(but, mx, my))
|
||||
/* give precedence to already activated buttons */
|
||||
if(!butover || (!butover->active && but->active))
|
||||
butover= but;
|
||||
butover= but;
|
||||
}
|
||||
}
|
||||
|
||||
return butover;
|
||||
}
|
||||
|
||||
static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y)
|
||||
{
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
int mx, my;
|
||||
|
||||
if(!ui_mouse_inside_region(ar, x, y))
|
||||
return NULL;
|
||||
|
||||
for(block=ar->uiblocks.first; block; block=block->next) {
|
||||
mx= x;
|
||||
my= y;
|
||||
ui_window_to_block(ar, block, &mx, &my);
|
||||
|
||||
for(but=block->buttons.last; but; but= but->prev)
|
||||
if(but->type == LISTBOX && ui_but_contains_pt(but, mx, my))
|
||||
return but;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ****************** button state handling **************************/
|
||||
|
||||
static int button_modal_state(uiHandleButtonState state)
|
||||
@@ -4028,6 +4051,10 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
|
||||
data->cancel= 1;
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
else if(ui_but_find_mouse_over(ar, event->x, event->y) != but) {
|
||||
data->cancel= 1;
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
else if(event->x!=event->prevx || event->y!=event->prevy) {
|
||||
/* re-enable tooltip on mouse move */
|
||||
ui_blocks_set_tooltips(ar, 1);
|
||||
@@ -4151,6 +4178,71 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar)
|
||||
{
|
||||
uiBut *but= ui_list_find_mouse_over(ar, event->x, event->y);
|
||||
int retval= WM_UI_HANDLER_CONTINUE;
|
||||
int value, min, max;
|
||||
|
||||
if(but && (event->val == KM_PRESS)) {
|
||||
Panel *pa= but->block->panel;
|
||||
|
||||
if(ELEM(event->type, UPARROWKEY, DOWNARROWKEY) ||
|
||||
((ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt))) {
|
||||
/* activate up/down the list */
|
||||
value= RNA_property_int_get(&but->rnapoin, but->rnaprop);
|
||||
|
||||
if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE))
|
||||
value--;
|
||||
else
|
||||
value++;
|
||||
|
||||
if(value < pa->list_scroll)
|
||||
pa->list_scroll= value;
|
||||
else if(value >= pa->list_scroll+pa->list_size)
|
||||
pa->list_scroll= value - pa->list_size + 1;
|
||||
|
||||
RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
|
||||
value= CLAMPIS(value, min, max);
|
||||
|
||||
RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
|
||||
RNA_property_update(C, &but->rnapoin, but->rnaprop);
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
retval= WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if(ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
|
||||
/* silly replacement for proper grip */
|
||||
if(pa->list_grip_size == 0)
|
||||
pa->list_grip_size= pa->list_size;
|
||||
|
||||
if(event->type == WHEELUPMOUSE)
|
||||
pa->list_grip_size--;
|
||||
else
|
||||
pa->list_grip_size++;
|
||||
|
||||
pa->list_grip_size= MAX2(pa->list_grip_size, 1);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
retval= WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if(ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
|
||||
/* list template will clamp */
|
||||
if(event->type == WHEELUPMOUSE)
|
||||
pa->list_scroll--;
|
||||
else
|
||||
pa->list_scroll++;
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
retval= WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *but)
|
||||
{
|
||||
uiHandleButtonData *data;
|
||||
@@ -4615,6 +4707,9 @@ static int ui_handler_region(bContext *C, wmEvent *event, void *userdata)
|
||||
if(!but || !button_modal_state(but->active->state))
|
||||
retval= ui_handler_panel_region(C, event);
|
||||
|
||||
if(retval == WM_UI_HANDLER_CONTINUE)
|
||||
retval= ui_handle_list_event(C, event, ar);
|
||||
|
||||
if(retval == WM_UI_HANDLER_CONTINUE) {
|
||||
if(but)
|
||||
retval= ui_handle_button_event(C, event, but);
|
||||
|
||||
@@ -98,6 +98,7 @@ typedef enum uiItemType {
|
||||
ITEM_LAYOUT_BOX,
|
||||
ITEM_LAYOUT_ABSOLUTE,
|
||||
ITEM_LAYOUT_SPLIT,
|
||||
ITEM_LAYOUT_OVERLAP,
|
||||
|
||||
ITEM_LAYOUT_ROOT
|
||||
#if 0
|
||||
@@ -148,7 +149,6 @@ typedef struct uiLayoutItemFlow {
|
||||
typedef struct uiLayoutItemBx {
|
||||
uiLayout litem;
|
||||
uiBut *roundbox;
|
||||
ListBase items;
|
||||
} uiLayoutItemBx;
|
||||
|
||||
typedef struct uiLayoutItemSplt {
|
||||
@@ -286,6 +286,7 @@ static int ui_layout_local_dir(uiLayout *layout)
|
||||
switch(layout->item.type) {
|
||||
case ITEM_LAYOUT_ROW:
|
||||
case ITEM_LAYOUT_ROOT:
|
||||
case ITEM_LAYOUT_OVERLAP:
|
||||
return UI_LAYOUT_HORIZONTAL;
|
||||
case ITEM_LAYOUT_COLUMN:
|
||||
case ITEM_LAYOUT_COLUMN_FLOW:
|
||||
@@ -362,7 +363,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
|
||||
int cols= (len >= 20)? 2: 1;
|
||||
int colbuts= len/(2*cols);
|
||||
|
||||
uiBlockSetCurLayout(block, uiLayoutFree(layout, 0));
|
||||
uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, 0));
|
||||
|
||||
unit= UI_UNIT_X*0.75;
|
||||
butw= unit;
|
||||
@@ -390,7 +391,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
|
||||
/* matrix layout */
|
||||
int row, col;
|
||||
|
||||
uiBlockSetCurLayout(block, uiLayoutFree(layout, 1));
|
||||
uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, 1));
|
||||
|
||||
len= ceil(sqrt(len));
|
||||
|
||||
@@ -1869,6 +1870,42 @@ static void ui_litem_layout_split(uiLayout *litem)
|
||||
litem->y= y;
|
||||
}
|
||||
|
||||
/* overlap layout */
|
||||
static void ui_litem_estimate_overlap(uiLayout *litem)
|
||||
{
|
||||
uiItem *item;
|
||||
int itemw, itemh;
|
||||
|
||||
litem->w= 0;
|
||||
litem->h= 0;
|
||||
|
||||
for(item=litem->items.first; item; item=item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
|
||||
litem->w= MAX2(itemw, litem->w);
|
||||
litem->h= MAX2(itemh, litem->h);
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_litem_layout_overlap(uiLayout *litem)
|
||||
{
|
||||
uiItem *item;
|
||||
int itemw, itemh, x, y;
|
||||
|
||||
x= litem->x;
|
||||
y= litem->y;
|
||||
|
||||
for(item=litem->items.first; item; item=item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_position(item, x, y-itemh, litem->w, itemh);
|
||||
|
||||
litem->h= MAX2(litem->h, itemh);
|
||||
}
|
||||
|
||||
litem->x= x;
|
||||
litem->y= y - litem->h;
|
||||
}
|
||||
|
||||
/* layout create functions */
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, int align)
|
||||
{
|
||||
@@ -1928,7 +1965,7 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
|
||||
return &flow->litem;
|
||||
}
|
||||
|
||||
static uiLayout *ui_layout_box(uiLayout *layout, int type)
|
||||
static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type)
|
||||
{
|
||||
uiLayoutItemBx *box;
|
||||
|
||||
@@ -1945,30 +1982,32 @@ static uiLayout *ui_layout_box(uiLayout *layout, int type)
|
||||
|
||||
box->roundbox= uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
return &box->litem;
|
||||
return box;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutBox(uiLayout *layout)
|
||||
{
|
||||
return ui_layout_box(layout, ROUNDBOX);
|
||||
return (uiLayout*)ui_layout_box(layout, ROUNDBOX);
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout)
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr, PropertyRNA *actprop)
|
||||
{
|
||||
return ui_layout_box(layout, LISTBOX);
|
||||
uiLayoutItemBx *box= ui_layout_box(layout, LISTBOX);
|
||||
uiBut *but= box->roundbox;
|
||||
|
||||
but->rnasearchpoin= *ptr;
|
||||
but->rnasearchprop= prop;
|
||||
but->rnapoin= *actptr;
|
||||
but->rnaprop= actprop;
|
||||
|
||||
return (uiLayout*)box;
|
||||
}
|
||||
|
||||
ListBase *uiLayoutBoxGetList(uiLayout *layout)
|
||||
{
|
||||
uiLayoutItemBx *box= (uiLayoutItemBx*)layout;
|
||||
return &box->items;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutFree(uiLayout *layout, int align)
|
||||
uiLayout *uiLayoutAbsolute(uiLayout *layout, int align)
|
||||
{
|
||||
uiLayout *litem;
|
||||
|
||||
litem= MEM_callocN(sizeof(uiLayout), "uiLayoutFree");
|
||||
litem= MEM_callocN(sizeof(uiLayout), "uiLayoutAbsolute");
|
||||
litem->item.type= ITEM_LAYOUT_ABSOLUTE;
|
||||
litem->root= layout->root;
|
||||
litem->align= align;
|
||||
@@ -1987,11 +2026,28 @@ uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout)
|
||||
uiBlock *block;
|
||||
|
||||
block= uiLayoutGetBlock(layout);
|
||||
uiLayoutFree(layout, 0);
|
||||
uiLayoutAbsolute(layout, 0);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutOverlap(uiLayout *layout)
|
||||
{
|
||||
uiLayout *litem;
|
||||
|
||||
litem= MEM_callocN(sizeof(uiLayout), "uiLayoutOverlap");
|
||||
litem->item.type= ITEM_LAYOUT_OVERLAP;
|
||||
litem->root= layout->root;
|
||||
litem->active= 1;
|
||||
litem->enabled= 1;
|
||||
litem->context= layout->context;
|
||||
BLI_addtail(&layout->items, litem);
|
||||
|
||||
uiBlockSetCurLayout(layout->root->block, litem);
|
||||
|
||||
return litem;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage)
|
||||
{
|
||||
uiLayoutItemSplt *split;
|
||||
@@ -2149,6 +2205,9 @@ static void ui_item_estimate(uiItem *item)
|
||||
case ITEM_LAYOUT_SPLIT:
|
||||
ui_litem_estimate_split(litem);
|
||||
break;
|
||||
case ITEM_LAYOUT_OVERLAP:
|
||||
ui_litem_estimate_overlap(litem);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2169,6 +2228,7 @@ static void ui_item_align(uiLayout *litem, int nr)
|
||||
bitem->but->alignnr= nr;
|
||||
}
|
||||
else if(item->type == ITEM_LAYOUT_ABSOLUTE);
|
||||
else if(item->type == ITEM_LAYOUT_OVERLAP);
|
||||
else if(item->type == ITEM_LAYOUT_BOX) {
|
||||
box= (uiLayoutItemBx*)item;
|
||||
box->roundbox->alignnr= nr;
|
||||
@@ -2234,6 +2294,9 @@ static void ui_item_layout(uiItem *item)
|
||||
case ITEM_LAYOUT_SPLIT:
|
||||
ui_litem_layout_split(litem);
|
||||
break;
|
||||
case ITEM_LAYOUT_OVERLAP:
|
||||
ui_litem_layout_overlap(litem);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2268,9 +2331,6 @@ static void ui_layout_free(uiLayout *layout)
|
||||
ui_layout_free((uiLayout*)item);
|
||||
}
|
||||
|
||||
if(layout->item.type == ITEM_LAYOUT_BOX)
|
||||
BLI_freelistN(&((uiLayoutItemBx*)layout)->items);
|
||||
|
||||
MEM_freeN(layout);
|
||||
}
|
||||
|
||||
|
||||
@@ -357,6 +357,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
|
||||
float x1f, x2f, y1f, y2f;
|
||||
int x1, x2, y1, y2, winx, winy, ofsx, ofsy, w, h, a;
|
||||
|
||||
if(but->flag & UI_BUT_NO_TOOLTIP)
|
||||
return NULL;
|
||||
|
||||
/* create tooltip data */
|
||||
data= MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
|
||||
|
||||
|
||||
@@ -1925,25 +1925,6 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
|
||||
|
||||
/************************* List Template **************************/
|
||||
|
||||
#if 0
|
||||
static void list_item_add(ListBase *lb, ListBase *itemlb, uiLayout *layout, PointerRNA *data)
|
||||
{
|
||||
CollectionPointerLink *link;
|
||||
uiListItem *item;
|
||||
|
||||
/* add to list to store in box */
|
||||
item= MEM_callocN(sizeof(uiListItem), "uiListItem");
|
||||
item->layout= layout;
|
||||
item->data= *data;
|
||||
BLI_addtail(itemlb, item);
|
||||
|
||||
/* add to list to return from function */
|
||||
link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
|
||||
RNA_pointer_create(NULL, &RNA_UIListItem, item, &link->ptr);
|
||||
BLI_addtail(lb, link);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
|
||||
{
|
||||
ID *id= NULL;
|
||||
@@ -1974,60 +1955,102 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
|
||||
return rnaicon;
|
||||
}
|
||||
|
||||
ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int listtype)
|
||||
static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon)
|
||||
{
|
||||
uiBlock *block= uiLayoutGetBlock(layout);
|
||||
uiLayout *split;
|
||||
char *name, *namebuf;
|
||||
int icon;
|
||||
|
||||
/* retrieve icon and name */
|
||||
icon= list_item_icon_get(C, itemptr, rnaicon);
|
||||
if(!icon || icon == ICON_DOT)
|
||||
icon= 0;
|
||||
|
||||
namebuf= RNA_struct_name_get_alloc(itemptr, NULL, 0);
|
||||
name= (namebuf)? namebuf: "";
|
||||
|
||||
/* hardcoded types */
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
|
||||
if(itemptr->type == &RNA_MeshTextureFaceLayer || itemptr->type == &RNA_MeshColorLayer) {
|
||||
uiItemL(layout, name, icon);
|
||||
uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
|
||||
}
|
||||
else if(itemptr->type == &RNA_MaterialTextureSlot) {
|
||||
uiItemL(layout, name, icon);
|
||||
uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
|
||||
}
|
||||
else if(itemptr->type == &RNA_ShapeKey) {
|
||||
split= uiLayoutSplit(layout, 0.75f);
|
||||
|
||||
uiItemL(split, name, icon);
|
||||
|
||||
if(i == 0) uiItemL(split, "", 0);
|
||||
else uiItemR(split, "", 0, itemptr, "value", 0);
|
||||
//uiItemR(split, "", ICON_MUTE_IPO_OFF, itemptr, "mute", 0);
|
||||
}
|
||||
else
|
||||
uiItemL(layout, name, icon);
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
|
||||
/* free name */
|
||||
if(namebuf)
|
||||
MEM_freeN(namebuf);
|
||||
}
|
||||
|
||||
void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int listtype)
|
||||
{
|
||||
//Scene *scene= CTX_data_scene(C);
|
||||
PropertyRNA *prop= NULL, *activeprop;
|
||||
PropertyType type, activetype;
|
||||
StructRNA *ptype;
|
||||
uiLayout *box, *row, *col, *subrow;
|
||||
uiLayout *box, *row, *col, *subrow, *overlap;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
Panel *pa;
|
||||
ListBase lb, *itemlb;
|
||||
char *name, str[32];
|
||||
int rnaicon=0, icon=0, i= 0, activei= 0, len= 0, items, found, min, max;
|
||||
|
||||
lb.first= lb.last= NULL;
|
||||
|
||||
/* validate arguments */
|
||||
block= uiLayoutGetBlock(layout);
|
||||
pa= block->panel;
|
||||
|
||||
if(!pa) {
|
||||
printf("uiTemplateList: only works inside a panel.\n");
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!activeptr->data)
|
||||
return lb;
|
||||
return;
|
||||
|
||||
if(ptr->data) {
|
||||
prop= RNA_struct_find_property(ptr, propname);
|
||||
if(!prop) {
|
||||
printf("uiTemplateList: property not found: %s\n", propname);
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
activeprop= RNA_struct_find_property(activeptr, activepropname);
|
||||
if(!activeprop) {
|
||||
printf("uiTemplateList: property not found: %s\n", activepropname);
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
|
||||
if(prop) {
|
||||
type= RNA_property_type(prop);
|
||||
if(type != PROP_COLLECTION) {
|
||||
printf("uiTemplateList: expected collection property.\n");
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
activetype= RNA_property_type(activeprop);
|
||||
if(activetype != PROP_INT) {
|
||||
printf("uiTemplateList: expected integer property.\n");
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
|
||||
/* get icon */
|
||||
@@ -2040,12 +2063,10 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
||||
activei= RNA_property_int_get(activeptr, activeprop);
|
||||
|
||||
if(listtype == 'i') {
|
||||
box= uiLayoutListBox(layout);
|
||||
box= uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
|
||||
col= uiLayoutColumn(box, 1);
|
||||
row= uiLayoutRow(col, 0);
|
||||
|
||||
itemlb= uiLayoutBoxGetList(box);
|
||||
|
||||
if(ptr->data && prop) {
|
||||
/* create list items */
|
||||
RNA_PROP_BEGIN(ptr, itemptr, prop) {
|
||||
@@ -2054,9 +2075,8 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
||||
row= uiLayoutRow(col, 0);
|
||||
|
||||
icon= list_item_icon_get(C, &itemptr, rnaicon);
|
||||
uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
|
||||
//list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
|
||||
but= uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -2082,9 +2102,6 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
||||
|
||||
if(name)
|
||||
MEM_freeN(name);
|
||||
|
||||
/* add to list to return */
|
||||
//list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -2106,9 +2123,11 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
||||
/* default rows */
|
||||
if(rows == 0)
|
||||
rows= 5;
|
||||
if(pa->list_grip_size != 0)
|
||||
rows= pa->list_grip_size;
|
||||
|
||||
/* layout */
|
||||
box= uiLayoutListBox(layout);
|
||||
box= uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
|
||||
row= uiLayoutRow(box, 0);
|
||||
col = uiLayoutColumn(row, 1);
|
||||
|
||||
@@ -2119,44 +2138,28 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
||||
len= RNA_property_collection_length(ptr, prop);
|
||||
items= CLAMPIS(len, rows, MAX2(rows, 5));
|
||||
|
||||
/* if list length changes and active is out of view, scroll to it */
|
||||
if(pa->list_last_len != len)
|
||||
if((activei < pa->list_scroll || activei >= pa->list_scroll+items))
|
||||
pa->list_scroll= activei;
|
||||
|
||||
pa->list_scroll= MIN2(pa->list_scroll, len-items);
|
||||
pa->list_scroll= MAX2(pa->list_scroll, 0);
|
||||
|
||||
itemlb= uiLayoutBoxGetList(box);
|
||||
pa->list_size= items;
|
||||
pa->list_last_len= len;
|
||||
|
||||
if(ptr->data && prop) {
|
||||
/* create list items */
|
||||
RNA_PROP_BEGIN(ptr, itemptr, prop) {
|
||||
if(i >= pa->list_scroll && i<pa->list_scroll+items) {
|
||||
name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
|
||||
overlap= uiLayoutOverlap(col);
|
||||
|
||||
subrow= uiLayoutRow(col, 0);
|
||||
|
||||
icon= list_item_icon_get(C, &itemptr, rnaicon);
|
||||
subrow= uiLayoutRow(overlap, 0);
|
||||
but= uiDefButR(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
|
||||
|
||||
/* create button */
|
||||
if(!icon || icon == ICON_DOT)
|
||||
but= uiDefButR(block, LISTROW, 0, (name)? name: "", 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
else
|
||||
but= uiDefIconTextButR(block, LISTROW, 0, icon, (name)? name: "", 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
|
||||
|
||||
/* XXX hardcoded */
|
||||
if(itemptr.type == &RNA_MeshTextureFaceLayer || itemptr.type == &RNA_MeshColorLayer) {
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
}
|
||||
else if (itemptr.type == &RNA_MaterialTextureSlot) {
|
||||
uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
|
||||
}
|
||||
/* XXX - end hardcoded cruft */
|
||||
|
||||
if(name)
|
||||
MEM_freeN(name);
|
||||
|
||||
/* add to list to return */
|
||||
//list_item_add(&lb, itemlb, subrow, &itemptr);
|
||||
subrow= uiLayoutRow(overlap, 0);
|
||||
list_item_row(C, subrow, ptr, &itemptr, i, rnaicon);
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -2177,9 +2180,6 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
||||
uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &pa->list_scroll, 0, len-items, items, 0, "");
|
||||
}
|
||||
}
|
||||
|
||||
/* return items in list */
|
||||
return lb;
|
||||
}
|
||||
|
||||
/************************* Operator Search Template **************************/
|
||||
|
||||
@@ -106,6 +106,7 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
|
||||
void *activedata; /* runtime for panel manipulation */
|
||||
|
||||
int list_scroll, list_size;
|
||||
int list_last_len, list_grip_size;
|
||||
char list_search[64];
|
||||
} Panel;
|
||||
|
||||
|
||||
@@ -391,6 +391,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
|
||||
prop= RNA_def_property(srna, "value", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "curval");
|
||||
RNA_def_property_float_funcs(prop, NULL, "rna_ShapeKey_value_set", "rna_ShapeKey_value_range");
|
||||
RNA_def_property_ui_range(prop, -10.0f, 10.0f, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Value", "Value of shape key at the current frame.");
|
||||
RNA_def_property_update(prop, 0, "rna_Key_update_data");
|
||||
|
||||
|
||||
@@ -489,20 +489,6 @@ static void rna_UILayout_scale_y_set(PointerRNA *ptr, float value)
|
||||
uiLayoutSetScaleY(ptr->data, value);
|
||||
}
|
||||
|
||||
static PointerRNA rna_UIListItem_layout_get(PointerRNA *ptr)
|
||||
{
|
||||
uiListItem *item= (uiListItem*)ptr->data;
|
||||
PointerRNA newptr;
|
||||
RNA_pointer_create(NULL, &RNA_UILayout, item->layout, &newptr);
|
||||
return newptr;
|
||||
}
|
||||
|
||||
static PointerRNA rna_UIListItem_data_get(PointerRNA *ptr)
|
||||
{
|
||||
uiListItem *item= (uiListItem*)ptr->data;
|
||||
return item->data;
|
||||
}
|
||||
|
||||
#else // RNA_RUNTIME
|
||||
|
||||
static void rna_def_ui_layout(BlenderRNA *brna)
|
||||
@@ -566,21 +552,6 @@ static void rna_def_ui_layout(BlenderRNA *brna)
|
||||
RNA_def_property_float_funcs(prop, "rna_UILayout_scale_y_get", "rna_UILayout_scale_y_set", NULL);
|
||||
|
||||
RNA_api_ui_layout(srna);
|
||||
|
||||
/* list item */
|
||||
|
||||
srna= RNA_def_struct(brna, "UIListItem", NULL);
|
||||
RNA_def_struct_ui_text(srna, "UI List Item", "User interface list.");
|
||||
|
||||
prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "UILayout");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_pointer_funcs(prop, "rna_UIListItem_layout_get", NULL, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "data", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "AnyType");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_pointer_funcs(prop, "rna_UIListItem_data_get", NULL, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_panel(BlenderRNA *brna)
|
||||
|
||||
@@ -335,8 +335,6 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
parm= RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display.", 0, INT_MAX);
|
||||
parm= RNA_def_enum(func, "type", list_type_items, 0, "Type", "Type of list to use.");
|
||||
parm= RNA_def_collection(func, "items", 0, "", "Items visible in the list.");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func= RNA_def_function(srna, "template_running_jobs", "uiTemplateRunningJobs");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
|
||||
Reference in New Issue
Block a user