* minor changes, edited some tooltips (exr half and zbuf were not that helpful)
* UV coord buttons overlapped others since merging uv/face and editmode. * added some quad join and triangulate into the Ctrl+F face menu. * active face cant be hidden anymore.
This commit is contained in:
@@ -38,7 +38,7 @@ struct EditFace;
|
||||
struct Mesh;
|
||||
struct MCol;
|
||||
|
||||
struct MTFace *get_active_tface(struct EditFace **efa, struct MCol **mcol);
|
||||
struct MTFace *get_active_mtface(struct EditFace **efa, struct MCol **mcol);
|
||||
void calculate_uv_map(unsigned short mapmode);
|
||||
void default_uv(float uv[][2], float size);
|
||||
void make_tfaces(struct Mesh *me);
|
||||
|
||||
@@ -4836,7 +4836,7 @@ void do_fpaintbuts(unsigned short event)
|
||||
case B_COPY_TF_COL:
|
||||
case B_COPY_TF_TEX:
|
||||
me= get_mesh(OBACT);
|
||||
activetf= get_active_tface(NULL, &activemcol);
|
||||
activetf= get_active_mtface(NULL, &activemcol);
|
||||
|
||||
if(me && activetf) {
|
||||
for (a=0, tf=me->mtface, mf=me->mface; a < me->totface; a++, tf++, mf++) {
|
||||
@@ -4890,7 +4890,7 @@ void do_fpaintbuts(unsigned short event)
|
||||
break;
|
||||
|
||||
case B_TFACE_HALO:
|
||||
activetf = get_active_tface(NULL, NULL);
|
||||
activetf = get_active_mtface(NULL, NULL);
|
||||
if(activetf) {
|
||||
activetf->mode &= ~TF_BILLBOARD2;
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
@@ -4898,7 +4898,7 @@ void do_fpaintbuts(unsigned short event)
|
||||
break;
|
||||
|
||||
case B_TFACE_BILLB:
|
||||
activetf = get_active_tface(NULL, NULL);
|
||||
activetf = get_active_mtface(NULL, NULL);
|
||||
if(activetf) {
|
||||
activetf->mode &= ~TF_BILLBOARD;
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
@@ -5288,7 +5288,7 @@ static void editing_panel_mesh_texface(void)
|
||||
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_texface", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Texture face", "Editing", 960, 0, 318, 204)==0) return;
|
||||
|
||||
tf = get_active_tface(NULL, NULL);
|
||||
tf = get_active_mtface(NULL, NULL);
|
||||
if(tf) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, TF_TEX, B_REDR_3D_IMA, "Tex", 600,160,60,19, &tf->mode, 0, 0, 0, 0, "Render face with texture");
|
||||
|
||||
@@ -1601,8 +1601,8 @@ static void render_panel_format(void)
|
||||
|
||||
if(G.scene->r.imtype==R_OPENEXR) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_NOP,"Half", 892,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Use 16 bits float 'Half' type");
|
||||
uiDefButBitS(block, TOG, R_OPENEXR_ZBUF, B_NOP,"Zbuf", 952,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save the zbuffer as 32 bits unsigned int");
|
||||
uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_NOP,"Half", 892,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Use 16 bit floats instead of 32 bit floats per channel");
|
||||
uiDefButBitS(block, TOG, R_OPENEXR_ZBUF, B_NOP,"Zbuf", 952,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save the z-depth per pixel (32 bit unsigned int zbuffer)");
|
||||
uiBlockEndAlign(block);
|
||||
uiDefButBitS(block, TOG, R_PREVIEW_JPG, B_NOP,"Preview",1027,yofs+44,90,20, &G.scene->r.subimtype, 0, 0, 0, 0, "When animation render, save JPG preview images in same directory");
|
||||
}
|
||||
|
||||
@@ -1157,7 +1157,7 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
|
||||
}
|
||||
else {
|
||||
image_info(ima, ibuf, str);
|
||||
uiDefBut(block, LABEL, 0, str, 10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
|
||||
uiDefBut(block, LABEL, 0, str, 10, 112, 300, 20, NULL, 1, 0, 0, 0, "");
|
||||
}
|
||||
|
||||
/* exception, let's do because we only use this panel 3 times in blender... but not real good code! */
|
||||
@@ -1167,33 +1167,33 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
|
||||
|
||||
/* fields */
|
||||
uiBlockBeginAlign(block);
|
||||
but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 70, 100, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
|
||||
but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 90, 100, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
|
||||
uiButSetFunc(but, image_field_test, ima, iuser);
|
||||
uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 10, 50, 100, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
|
||||
uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 10, 70, 100, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 10, 100, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
|
||||
uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 35, 100, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
|
||||
|
||||
if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
|
||||
sprintf(str, "(%d) Frames:", iuser->framenr);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiBlockSetFunc(block, image_user_change, iuser, NULL);
|
||||
uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 70, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes");
|
||||
uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 90, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes");
|
||||
|
||||
if(ima->anim) {
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 50,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
but= uiDefBut(block, BUT, redraw, "<", 290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 70,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
but= uiDefBut(block, BUT, redraw, "<", 290, 70, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
|
||||
uiButSetFunc(but, set_frames_cb, ima, iuser);
|
||||
}
|
||||
else
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 50,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
uiDefButI(block, NUM, imagechanged, str, 120, 70,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
|
||||
|
||||
uiDefButI(block, NUM, imagechanged, "Offs:", 120,30,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
|
||||
uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,30,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)");
|
||||
uiDefButI(block, NUM, imagechanged, "Offs:", 120,50,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
|
||||
uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,50,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)");
|
||||
|
||||
uiDefButI(block, NUM, imagechanged, "StartFr:", 120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
|
||||
uiDefButS(block, TOG, imagechanged, "Cyclic", 220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
|
||||
uiDefButI(block, NUM, imagechanged, "StartFr:", 120,30,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
|
||||
uiDefButS(block, TOG, imagechanged, "Cyclic", 220,30,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
|
||||
|
||||
uiBlockSetFunc(block, NULL, iuser, NULL);
|
||||
}
|
||||
@@ -1201,9 +1201,9 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiBlockSetFunc(block, image_generated_change_cb, ima, iuser);
|
||||
uiDefButS(block, NUM, imagechanged, "SizeX:", 120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
|
||||
uiDefButS(block, NUM, imagechanged, "SizeY:", 220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
|
||||
uiDefButS(block, TOG, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
|
||||
uiDefButS(block, NUM, imagechanged, "SizeX:", 120,90,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
|
||||
uiDefButS(block, NUM, imagechanged, "SizeY:", 220,90,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
|
||||
uiDefButS(block, TOG, imagechanged, "UV Test grid",120,70,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
|
||||
uiBlockSetFunc(block, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ void what_image(SpaceImage *sima)
|
||||
if(sima->image && sima->image->source==IMA_SRC_VIEWER) {}
|
||||
else if (G.obedit == OBACT) {
|
||||
sima->image= NULL;
|
||||
activetf = get_active_tface(NULL, NULL);
|
||||
activetf = get_active_mtface(NULL, NULL);
|
||||
|
||||
if(activetf && activetf->mode & TF_TEX) {
|
||||
sima->image= activetf->tpage;
|
||||
@@ -489,7 +489,7 @@ void draw_tfaces(void)
|
||||
/* draw active face edges */
|
||||
/*if (activetface){*/
|
||||
/* colors: R=u G=v */
|
||||
activetface = get_active_tface(&efa, NULL);
|
||||
activetface = get_active_mtface(&efa, NULL);
|
||||
if (activetface) {
|
||||
setlinestyle(2);
|
||||
tface=activetface;
|
||||
@@ -756,15 +756,14 @@ void image_editvertex_buts(uiBlock *block)
|
||||
digits= 2;
|
||||
}
|
||||
|
||||
uiDefBut(block, LABEL, 0, "UV Vertex:",10,55,300,19,0,0,0,0,0,"");
|
||||
uiBlockBeginAlign(block);
|
||||
if(nactive==1) {
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 35, 290, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex Y:", 10, 15, 290, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 10, 150, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex Y:", 160, 10, 150, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
|
||||
}
|
||||
else {
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Median X:", 10, 35, 290, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Median Y:", 10, 15, 290, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Median X:", 10, 10, 150, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Median Y:", 160, 10, 150, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
|
||||
}
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
@@ -2042,7 +2042,7 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
|
||||
if (em->selected.last) {
|
||||
EditSelection *ese = em->selected.last;
|
||||
|
||||
if(ese->type == EDITVERT) {
|
||||
if( ese->type == EDITVERT && ((EditVert *)ese->data)->h==0) {
|
||||
EditVert *ev = (EditVert*)ese->data;
|
||||
float size = BIF_GetThemeValuef(TH_VERTEX_SIZE)*4;
|
||||
|
||||
@@ -2061,7 +2061,7 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(1);
|
||||
|
||||
} else if(ese->type == EDITEDGE) {
|
||||
} else if(ese->type == EDITEDGE && ((EditEdge *)ese->data)->h==0) {
|
||||
EditEdge *eed = (EditEdge*)ese->data;
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -2081,7 +2081,7 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
|
||||
glDepthMask(1);
|
||||
|
||||
|
||||
} else if(ese->type == EDITFACE) {
|
||||
} else if(ese->type == EDITFACE && ((EditFace *)ese->data)->h==0) {
|
||||
EditFace *efa = (EditFace*)ese->data;
|
||||
|
||||
/* repeate this pattern
|
||||
|
||||
@@ -552,7 +552,7 @@ void calculate_uv_map(unsigned short mapmode)
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
|
||||
MTFace *get_active_tface(EditFace **act_efa, MCol **mcol)
|
||||
MTFace *get_active_mtface(EditFace **act_efa, MCol **mcol)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditFace *efa = NULL;
|
||||
@@ -564,6 +564,9 @@ MTFace *get_active_tface(EditFace **act_efa, MCol **mcol)
|
||||
for (ese = em->selected.last; ese; ese=ese->prev){
|
||||
if(ese->type == EDITFACE) {
|
||||
efa = (EditFace *)ese->data;
|
||||
|
||||
if (efa->h)
|
||||
efa= NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3282,30 +3282,31 @@ void BME_Menu() {
|
||||
|
||||
void Vertex_Menu() {
|
||||
short ret;
|
||||
ret= pupmenu("Vertex Specials%t|Merge%x4|Remove Doubles%x5|Smooth %x10|Blend From Shape%x16|Propagate To All Shapes%x17|Select Vertex Path%x18");
|
||||
ret= pupmenu("Vertex Specials%t|Remove Doubles%x1|Merge%x2|Smooth %x3|Select Vertex Path%x4|Blend From Shape%x5|Propagate To All Shapes%x6");
|
||||
|
||||
switch(ret)
|
||||
{
|
||||
case 4:
|
||||
mergemenu();
|
||||
break;
|
||||
case 5:
|
||||
case 1:
|
||||
notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit));
|
||||
BIF_undo_push("Remove Doubles");
|
||||
break;
|
||||
case 10:
|
||||
case 2:
|
||||
mergemenu();
|
||||
break;
|
||||
case 3:
|
||||
vertexsmooth();
|
||||
break;
|
||||
case 16:
|
||||
shape_copy_select_from();
|
||||
break;
|
||||
case 17:
|
||||
shape_propagate();
|
||||
break;
|
||||
case 18:
|
||||
case 4:
|
||||
pathselect();
|
||||
BIF_undo_push("Select Vertex Path");
|
||||
break;
|
||||
case 5:
|
||||
shape_copy_select_from();
|
||||
break;
|
||||
case 6:
|
||||
shape_propagate();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3365,7 +3366,8 @@ void Edge_Menu() {
|
||||
void Face_Menu() {
|
||||
short ret;
|
||||
ret= pupmenu(
|
||||
"Face Specials%t|Flip Normals %x1|Bevel %x2|Shade Smooth %x3|Shade Flat %x4|%l|"
|
||||
"Face Specials%t|Flip Normals%x1|Bevel%x2|Shade Smooth%x3|Shade Flat%x4|"
|
||||
"Triangulate (Ctrl T)%x5|Quads from Triangles (Alt J)%x6|Flip Triangle Edges (Ctrl Shift F)%x7|%l|"
|
||||
"UV Rotate (Shift - CCW)%x10|UV Mirror (Shift - Switch Axis)%x11|"
|
||||
"Color Rotate (Shift - CCW)%x12|Color Mirror (Shift - Switch Axis)%x13");
|
||||
|
||||
@@ -3385,6 +3387,20 @@ void Face_Menu() {
|
||||
mesh_set_smooth_faces(0);
|
||||
break;
|
||||
|
||||
case 5: /* Quads to Tris */
|
||||
convert_to_triface(0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
countall();
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
break;
|
||||
case 6: /* Tris to Quads */
|
||||
join_triangles();
|
||||
break;
|
||||
case 7: /* Flip triangle edges */
|
||||
edge_flip();
|
||||
break;
|
||||
|
||||
|
||||
/* uv texface options */
|
||||
case 10:
|
||||
mesh_rotate_uvs();
|
||||
|
||||
@@ -3001,8 +3001,8 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
|
||||
}
|
||||
#endif
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo Editing|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Redo Editing|Shift U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo Editing|Ctrl Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Redo Editing|Ctrl Shift Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
|
||||
uiDefIconTextBlockBut(block, editmode_undohistorymenu, NULL, ICON_RIGHTARROW_THIN, "Undo History", 0, yco-=20, 120, 19, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
@@ -1061,9 +1061,9 @@ static TBitem tb_mesh_edit_face[]= {
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Convert to Triangles|Ctrl T", 2, NULL},
|
||||
{ 0, "Convert to Quads|Alt J", 3, NULL},
|
||||
{ 0, "Flip Triangle Edges|Ctrl F", 4, NULL},
|
||||
{ 0, "Set Smooth|W, Alt 3", 6, NULL},
|
||||
{ 0, "Set Solid|W, Alt 4", 7, NULL},
|
||||
{ 0, "Flip Triangle Edges|Ctrl Shift F", 4, NULL},
|
||||
{ 0, "Set Smooth|Ctrl F, 3", 6, NULL},
|
||||
{ 0, "Set Solid|Ctrl F, 4", 7, NULL},
|
||||
{ -1, "", 0, do_view3d_edit_mesh_facesmenu}};
|
||||
|
||||
|
||||
@@ -1071,13 +1071,13 @@ static TBitem tb_mesh_edit_normal[]= {
|
||||
{ 0, "Recalculate Outside|Ctrl N", 2, NULL},
|
||||
{ 0, "Recalculate Inside|Ctrl Shift N", 1, NULL},
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Flip|W, 9", 0, NULL},
|
||||
{ 0, "Flip|Ctrl F, 1", 0, NULL},
|
||||
{ -1, "", 0, do_view3d_edit_mesh_normalsmenu}};
|
||||
|
||||
static TBitem tb_mesh_edit[]= {
|
||||
{ 0, "Exit Editmode|Tab", TB_TAB, NULL},
|
||||
{ 0, "Undo|U", 'u', NULL},
|
||||
{ 0, "Redo|Shift U", 'U', NULL},
|
||||
{ 0, "Undo|Ctrl Z", 'u', NULL},
|
||||
{ 0, "Redo|Ctrl Shift Z", 'U', NULL},
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Extrude|E", 'e', NULL},
|
||||
{ 0, "Duplicate|Shift D", 'D', NULL},
|
||||
|
||||
Reference in New Issue
Block a user