Changeset 2769 for trunk/src/comctl32/treeview.c
- Timestamp:
- Feb 12, 2000, 7:10:40 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comctl32/treeview.c
r2740 r2769 1 /* $Id: treeview.c,v 1.2 3 2000-02-10 18:51:19cbratschi Exp $ */1 /* $Id: treeview.c,v 1.24 2000-02-12 18:10:40 cbratschi Exp $ */ 2 2 /* Treeview control 3 3 * … … 32 32 * WM_HSCROLL is broken. 33 33 * use separate routine to get item text/image. 34 * WM_SETREDRAW isn't handled35 34 * 36 35 * Separate drawing/calculation. … … 44 43 45 44 /* WINE 991212 level */ 45 46 /* CB: todo 47 48 - sub parent lines aren't redrawn in expand handler 49 - invisible sibling lines aren't drawn in WM_PAINT 50 - WM_LBUTTONDOWN: bug in highlight code 51 - WM_SIZE: redraw doesn't work 52 - hscroll not set 53 54 */ 46 55 47 56 #include <string.h> … … 74 83 static void TREEVIEW_Refresh(HWND hwnd); 75 84 static void TREEVIEW_Draw(HWND hwnd,HDC hdc,RECT *updateRect); 85 static void TREEVIEW_UnqueueRefresh(HWND hwnd,BOOL calc,BOOL refresh); 86 static void TREEVIEW_QueueRefresh(HWND hwnd); 76 87 77 88 static LRESULT CALLBACK TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); … … 488 499 489 500 //CB: todo 490 TREEVIEW_Refresh(hwnd); 501 if (!(infoPtr->uInternalStatus & TV_NOREDRAW)) 502 TREEVIEW_Refresh(hwnd); 491 503 492 504 return 1; … … 539 551 #define TREEVIEW_LEFT_MARGIN 8 540 552 553 //CB: hack for PS_DOT bug in Open32 pen handling 554 555 BOOL drawPixel; 556 HDC drawDC; 557 558 VOID CALLBACK TREEVIEW_DDAProc(int x,int y,LPARAM lpData) 559 { 560 if (drawPixel) SetPixel(drawDC,x,y,(COLORREF)lpData); 561 else SetPixel(drawDC,x,y,RGB(255,255,255)); 562 drawPixel = !drawPixel; 563 } 564 565 static void TREEVIEW_Polyline(HDC hdc,const POINT *lppt,int cPoints,COLORREF color) 566 { 567 INT x; 568 569 drawPixel = TRUE; 570 drawDC = hdc; 571 for (x = 0;x < cPoints-1;x++) 572 LineDDA(lppt[x].x,lppt[x].y,lppt[x+1].x,lppt[x+1].y,TREEVIEW_DDAProc,color); 573 } 541 574 542 575 static void … … 550 583 RECT r; 551 584 552 553 585 if (wineItem->state & TVIS_BOLD) 554 586 hOldFont = SelectObject (hdc, infoPtr->hBoldFont); 555 587 else 556 hOldFont = SelectObject (hdc, infoPtr->hFont); 557 558 cditem=0; 559 //TRACE ("cdmode:%x\n",infoPtr->cdmode); 560 if (infoPtr->cdmode & CDRF_NOTIFYITEMDRAW) { 561 cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, 562 wineItem, CDDS_ITEMPREPAINT); 563 564 if (cditem & CDRF_SKIPDEFAULT) 565 return; 566 } 588 hOldFont = SelectObject (hdc, infoPtr->hFont); 589 590 cditem = 0; 591 592 if (infoPtr->cdmode & CDRF_NOTIFYITEMDRAW) 593 { 594 cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, wineItem, CDDS_ITEMPREPAINT); 595 596 if (cditem & CDRF_SKIPDEFAULT) return; 597 } 567 598 568 599 /* … … 576 607 * Display the tree hierarchy 577 608 */ 578 if ( dwStyle & TVS_HASLINES)609 if ((dwStyle & TVS_HASLINES) && (wineItem->hItem != infoPtr->TopRootItem)) 579 610 { 580 611 /* … … 586 617 * points[2] is attached to the parent or the up sibling 587 618 */ 588 if ( 619 if (dwStyle & TVS_LINESATROOT) 589 620 { 590 621 TREEVIEW_ITEM *upNode = NULL; 591 622 BOOL hasParentOrSibling = TRUE; 592 623 RECT upRect = {0,0,0,0}; 593 624 HPEN hOldPen, hnewPen; 594 625 POINT points[3]; 595 626 /* 596 627 * determine the target location of the line at root, either be linked … … 606 637 if (upNode) 607 638 upRect = upNode->rect; 608 609 if ( wineItem->iLevel == 0)639 //CB: todo: draw full lines to avoid problems with PS_DOT and scrolling 640 if (wineItem->iLevel == 0) 610 641 { 611 642 points[2].x = points[1].x = upRect.left+8; … … 613 644 points[2].y = upRect.bottom-3; 614 645 points[1].y = points[0].y = center; 615 } 616 else 646 } else 617 647 { 618 648 points[2].x = points[1].x = 8 + (20*wineItem->iLevel); 619 points[2].y = ( 649 points[2].y = (upNode->cChildren == 0) ? 620 650 upRect.top : /* is linked to the "L" above */ 621 651 ( wineItem->upsibling != NULL) ? … … 629 659 * Get a dotted pen 630 660 */ 661 #if 0 //CB: workaround for Open32 PS_DOT bug 631 662 hnewPen = CreatePen(PS_DOT, 0, infoPtr->clrLine); 632 663 hOldPen = SelectObject( hdc, hnewPen ); 633 664 634 665 if (hasParentOrSibling) 635 Polyline 666 Polyline(hdc,points,3); 636 667 else 637 Polyline 668 Polyline(hdc,points,2); 638 669 639 670 DeleteObject(hnewPen); 640 671 SelectObject(hdc, hOldPen); 672 #else 673 if (hasParentOrSibling) 674 TREEVIEW_Polyline(hdc,points,3,infoPtr->clrLine); 675 else 676 TREEVIEW_Polyline(hdc,points,2,infoPtr->clrLine); 677 #endif 641 678 } 642 679 } … … 650 687 if (( dwStyle & TVS_HASBUTTONS) && ( dwStyle & TVS_HASLINES)) 651 688 { 652 653 689 if ( (wineItem->cChildren) || 690 (wineItem->cChildren == I_CHILDRENCALLBACK)) 654 691 { 655 692 /* Setup expand box coordinate to facilitate the LMBClick handling */ … … 659 696 wineItem->expandBox.bottom = center+5; 660 697 661 Rectangle ( 662 hdc, 663 wineItem->expandBox.left, 664 wineItem->expandBox.top , 665 wineItem->expandBox.right, 666 wineItem->expandBox.bottom); 667 668 MoveToEx (hdc, xpos-2, center, NULL); 669 LineTo (hdc, xpos+3, center); 670 671 if (!(wineItem->state & TVIS_EXPANDED)) { 672 MoveToEx (hdc, xpos, center-2, NULL); 673 LineTo (hdc, xpos, center+3); 674 } 698 Rectangle(hdc,wineItem->expandBox.left,wineItem->expandBox.top,wineItem->expandBox.right,wineItem->expandBox.bottom); 699 700 MoveToEx (hdc, xpos-2, center, NULL); 701 LineTo (hdc, xpos+3, center); 702 703 if (!(wineItem->state & TVIS_EXPANDED)) 704 { 705 MoveToEx (hdc, xpos, center-2, NULL); 706 LineTo (hdc, xpos, center+3); 707 } 675 708 } 676 709 } … … 680 713 */ 681 714 xpos += 13; /* update position */ 682 if (wineItem->mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) { 715 if (wineItem->mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) 716 { 683 717 INT imageIndex; 684 718 HIMAGELIST *himlp = NULL; 685 719 686 /* State images are displayed to the left of the Normal image687 * image number is in state; zero should be `display no image'.688 * FIXME: that last sentence looks like it needs some checking.689 */690 691 692 693 694 //TRACE ("imindex:%d\n",imageIndex); 720 /* State images are displayed to the left of the Normal image 721 * image number is in state; zero should be `display no image'. 722 * FIXME: that last sentence looks like it needs some checking. 723 */ 724 if (infoPtr->himlState) 725 himlp=&infoPtr->himlState; 726 imageIndex=wineItem->state>>12; 727 imageIndex++; /* yeah, right */ 728 695 729 if ((himlp) && (imageIndex)) 696 730 { 697 731 imageIndex--; /* see FIXME */ 698 732 ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL); 699 700 701 702 703 704 xpos+=cx;733 ImageList_GetIconSize (*himlp, &cx, &cy); 734 wineItem->statebitmap.left=xpos-2; 735 wineItem->statebitmap.right=xpos-2+cx; 736 wineItem->statebitmap.top=r.top+1; 737 wineItem->statebitmap.bottom=r.top+1+cy; 738 xpos += cx; 705 739 } 706 740 707 708 709 710 711 712 741 /* Now, draw the normal image; can be either selected or 742 * non-selected image. 743 */ 744 745 himlp=NULL; 746 if (infoPtr->himlNormal) 713 747 himlp=&infoPtr->himlNormal; /* get the image list */ 714 748 715 749 imageIndex = wineItem->iImage; 716 if ( (wineItem->state & TVIS_SELECTED) && 717 (wineItem->iSelectedImage)) { 750 if ( (wineItem->state & TVIS_SELECTED) && 751 (wineItem->iSelectedImage)) 752 { 718 753 719 754 /* The item is curently selected */ 720 721 TREEVIEW_SendDispInfoNotify722 (hwnd, wineItem, TVN_GETDISPINFO, TVIF_SELECTEDIMAGE); 723 724 imageIndex = wineItem->iSelectedImage;725 } else{755 if (wineItem->iSelectedImage == I_IMAGECALLBACK) 756 TREEVIEW_SendDispInfoNotify(hwnd, wineItem, TVN_GETDISPINFO, TVIF_SELECTEDIMAGE); 757 758 imageIndex = wineItem->iSelectedImage; 759 } else 760 { 726 761 /* The item is not selected */ 727 if (wineItem->iImage == I_IMAGECALLBACK) 728 TREEVIEW_SendDispInfoNotify 729 (hwnd, wineItem, TVN_GETDISPINFO, TVIF_IMAGE); 762 if (wineItem->iImage == I_IMAGECALLBACK) 763 TREEVIEW_SendDispInfoNotify(hwnd, wineItem, TVN_GETDISPINFO, TVIF_IMAGE); 730 764 731 765 imageIndex = wineItem->iImage; 732 766 } 733 767 734 768 if (himlp) 735 769 { 736 770 ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL); 737 738 739 740 741 742 xpos+=cx;771 ImageList_GetIconSize (*himlp, &cx, &cy); 772 wineItem->bitmap.left=xpos-2; 773 wineItem->bitmap.right=xpos-2+cx; 774 wineItem->bitmap.top=r.top+1; 775 wineItem->bitmap.bottom=r.top+1+cy; 776 xpos += cx; 743 777 } 744 778 } … … 763 797 wineItem->text.bottom= r.bottom; 764 798 765 if (wineItem->pszText== LPSTR_TEXTCALLBACKA) { 799 if (wineItem->pszText== LPSTR_TEXTCALLBACKA) 800 { 766 801 //TRACE("LPSTR_TEXTCALLBACK\n"); 767 802 TREEVIEW_SendDispInfoNotify (hwnd, wineItem, TVN_GETDISPINFO, TVIF_TEXT); … … 782 817 783 818 if (!(cditem & CDRF_NOTIFYPOSTPAINT) && 784 (wineItem->state & (TVIS_SELECTED | TVIS_DROPHILITED)) ) { 785 oldBkMode = SetBkMode (hdc, OPAQUE); 786 oldBkColor = SetBkColor (hdc, GetSysColor( COLOR_HIGHLIGHT)); 787 oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT)); 788 } else { 789 oldBkMode = SetBkMode (hdc, TRANSPARENT); 790 oldBkColor = SetBkColor (hdc, infoPtr->clrBk); 819 (wineItem->state & (TVIS_SELECTED | TVIS_DROPHILITED)) ) 820 { 821 oldBkMode = SetBkMode (hdc, OPAQUE); 822 oldBkColor = SetBkColor (hdc, GetSysColor( COLOR_HIGHLIGHT)); 823 oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT)); 824 } else 825 { 826 oldBkMode = SetBkMode (hdc, TRANSPARENT); 827 oldBkColor = SetBkColor (hdc, infoPtr->clrBk); 791 828 /* oldTextColor = SetTextColor(hdc, infoPtr->clrText); */ 792 829 } 793 830 794 831 … … 845 882 // TRACE ("item:%d,mark:%d\n", (int)wineItem->hItem, 846 883 // (int) infoPtr->insertMarkItem); 847 if (wineItem->hItem==infoPtr->insertMarkItem) { 848 HPEN hNewPen, hOldPen; 849 int offset; 850 851 hNewPen = CreatePen(PS_SOLID, 2, infoPtr->clrInsertMark); 852 hOldPen = SelectObject( hdc, hNewPen ); 853 854 if (infoPtr->insertBeforeorAfter) 855 offset=wineItem->text.top+1; 856 else 857 offset=wineItem->text.bottom-1; 858 859 MoveToEx (hdc, wineItem->text.left, offset-3, NULL); 860 LineTo (hdc, wineItem->text.left, offset+3); 861 862 MoveToEx (hdc, wineItem->text.left, offset, NULL); 863 LineTo (hdc, r.right-2, offset); 864 865 MoveToEx (hdc, r.right-2, offset+3, NULL); 866 LineTo (hdc, r.right-2, offset-3); 867 868 DeleteObject(hNewPen); 869 870 SelectObject(hdc, hOldPen); 871 } 872 873 if (cditem & CDRF_NOTIFYPOSTPAINT) { 874 cditem=TREEVIEW_SendCustomDrawItemNotify 875 (hwnd, hdc, wineItem, CDDS_ITEMPOSTPAINT); 876 //TRACE("postpaint:cditem-app returns 0x%x\n",cditem); 877 } 884 if (wineItem->hItem==infoPtr->insertMarkItem) 885 { 886 HPEN hNewPen, hOldPen; 887 int offset; 888 889 hNewPen = CreatePen(PS_SOLID, 2, infoPtr->clrInsertMark); 890 hOldPen = SelectObject( hdc, hNewPen ); 891 892 if (infoPtr->insertBeforeorAfter) 893 offset=wineItem->text.top+1; 894 else 895 offset=wineItem->text.bottom-1; 896 897 MoveToEx (hdc, wineItem->text.left, offset-3, NULL); 898 LineTo (hdc, wineItem->text.left, offset+3); 899 900 MoveToEx (hdc, wineItem->text.left, offset, NULL); 901 LineTo (hdc, r.right-2, offset); 902 903 MoveToEx (hdc, r.right-2, offset+3, NULL); 904 LineTo (hdc, r.right-2, offset-3); 905 906 DeleteObject(hNewPen); 907 908 SelectObject(hdc, hOldPen); 909 } 910 911 if (cditem & CDRF_NOTIFYPOSTPAINT) 912 { 913 cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, wineItem, CDDS_ITEMPOSTPAINT); 914 //TRACE("postpaint:cditem-app returns 0x%x\n",cditem); 915 } 878 916 879 917 SelectObject (hdc, hOldFont); … … 894 932 if (lpRect == NULL) 895 933 return FALSE; 934 935 TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE); 896 936 897 937 /* … … 1007 1047 { 1008 1048 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 1009 TREEVIEW_ITEM *wineItem; 1010 1011 wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)wParam); 1012 if (!wineItem) return 0; 1013 1014 return (wineItem->state & lParam); 1049 TREEVIEW_ITEM *wineItem; 1050 1051 wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)wParam); 1052 if (!wineItem) return 0; 1053 1054 return (wineItem->state & lParam); 1055 } 1056 1057 static void TREEVIEW_Refresh(HWND hwnd) 1058 { 1059 InvalidateRect(hwnd,NULL,TRUE); 1015 1060 } 1016 1061 … … 1019 1064 if (item && item->visible) 1020 1065 { 1021 //CB: todo: only redraw text and icon 1022 InvalidateRect(hwnd,&item->rect,TRUE); 1023 } 1024 } 1025 1026 static void TREEVIEW_Refresh(HWND hwnd) 1027 { 1028 InvalidateRect(hwnd,NULL,TRUE); 1029 } 1030 1031 static void TREEVIEW_CalcItems(HWND hwnd) 1032 { 1033 //CB: todo: TREEVIEW_Draw should only draw, not calculate! 1034 } 1035 1036 static void TREEVIEW_SetScrollbars(HWND hwnd) 1037 { 1038 //CB: todo: dito 1039 } 1040 1041 static int TREEVIEW_GetFirstVisibleItem(HWND hwnd) 1042 { 1043 //CB: todo 1044 1045 return 0; 1066 RECT rect = item->rect; 1067 1068 rect.left += TREEVIEW_LEFT_MARGIN; 1069 if (item->iLevel != 0) rect.left += (5*item->iLevel); 1070 rect.left += 15; 1071 InvalidateRect(hwnd,&rect,TRUE); 1072 } 1073 } 1074 1075 //CB: HDC parameter is optional 1076 1077 static void TREEVIEW_CalcItems(HWND hwnd,HDC hdc,TREEVIEW_INFO *infoPtr) 1078 { 1079 TREEVIEW_ITEM *item,*prevItem; 1080 INT iItem, indent, x, y, cx, height, itemHeight; 1081 TEXTMETRICA tm; 1082 RECT rect,view; 1083 BOOL ownDC = FALSE; 1084 1085 GetClientRect(hwnd,&rect); 1086 infoPtr->uVisibleHeight = rect.bottom-rect.top; 1087 infoPtr->uVisibleWidth = rect.right-rect.left; 1088 view = rect; 1089 OffsetRect(&view,infoPtr->cx,infoPtr->cy); 1090 1091 iItem = (INT)infoPtr->TopRootItem; 1092 infoPtr->firstVisible = 0; 1093 item = NULL; 1094 indent = 0; 1095 x = y = 0; 1096 1097 while (iItem) 1098 { 1099 prevItem = item; 1100 item = &infoPtr->items[iItem]; 1101 item->iLevel = indent; 1102 1103 if ((infoPtr->uInternalStatus & TV_CALCALL) || !item->calculated) 1104 { 1105 ImageList_GetIconSize(infoPtr->himlNormal,&cx,&itemHeight); 1106 if (infoPtr->uItemHeight > itemHeight) 1107 itemHeight = infoPtr->uItemHeight; 1108 1109 if (!hdc) 1110 { 1111 ownDC = TRUE; 1112 hdc = GetDC(hwnd); 1113 } 1114 1115 GetTextMetricsA(hdc,&tm); 1116 if ((tm.tmHeight + tm.tmExternalLeading) > itemHeight) 1117 itemHeight = tm.tmHeight + tm.tmExternalLeading; 1118 1119 infoPtr->uRealItemHeight = itemHeight; 1120 1121 height = itemHeight * item->iIntegral +1; 1122 item->calculated = TRUE; 1123 } else height = infoPtr->uRealItemHeight*item->iIntegral+1; 1124 1125 item->rect.top = y - infoPtr->cy + rect.top; 1126 item->rect.bottom = item->rect.top + height ; 1127 item->rect.left = x - infoPtr->cx + rect.left; 1128 item->rect.right = rect.right; 1129 1130 if ((((y >= view.top) && (y <= view.bottom)) || ((y+height >= view.top) && (y+height <= view.bottom))) && 1131 (x >= view.left) && (x <= view.right)) 1132 { 1133 item->visible = TRUE; 1134 if (!infoPtr->firstVisible) 1135 infoPtr->firstVisible = item->hItem; 1136 } else item->visible = FALSE; 1137 1138 /* look up next item */ 1139 1140 if ((item->firstChild) && (item->state & TVIS_EXPANDED)) 1141 { 1142 iItem = (INT)item->firstChild; 1143 indent++; 1144 x += infoPtr->uIndent; 1145 if (x > infoPtr->uTotalWidth) 1146 infoPtr->uTotalWidth=x; 1147 } else 1148 { 1149 iItem = (INT)item->sibling; 1150 while ((!iItem) && (indent > 0)) 1151 { 1152 indent--; 1153 x -= infoPtr->uIndent; 1154 prevItem = item; 1155 item =& infoPtr->items[(INT)item->parent]; 1156 iItem = (INT)item->sibling; 1157 } 1158 } 1159 y +=height; 1160 } /* while */ 1161 1162 if (ownDC) ReleaseDC(hwnd,hdc); 1163 1164 /* FIXME: infoPtr->uTotalWidth should also take item label into account */ 1165 1166 infoPtr->uTotalHeight = y; 1167 1168 infoPtr->uInternalStatus &= ~TV_CALCALL; 1169 1170 //CB: todo: use SetScrollInfo, HSCROLL 1171 1172 if (infoPtr->uTotalHeight >= infoPtr->uVisibleHeight) 1173 { 1174 if (!(infoPtr->uInternalStatus & TV_VSCROLL)) 1175 ShowScrollBar (hwnd, SB_VERT, TRUE); 1176 infoPtr->uInternalStatus |= TV_VSCROLL; 1177 SetScrollRange (hwnd, SB_VERT, 0, infoPtr->uTotalHeight - infoPtr->uVisibleHeight, FALSE); 1178 SetScrollPos (hwnd, SB_VERT, infoPtr->cy, TRUE); 1179 } else 1180 { 1181 if (infoPtr->uInternalStatus & TV_VSCROLL) 1182 ShowScrollBar (hwnd, SB_VERT, FALSE); 1183 infoPtr->uInternalStatus &= ~TV_VSCROLL; 1184 } 1046 1185 } 1047 1186 … … 1050 1189 { 1051 1190 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 1052 TEXTMETRICA tm;1053 1191 HBRUSH hbrBk; 1054 RECT rect,view; 1055 INT iItem, indent, x, y, cx, height, itemHeight; 1056 TREEVIEW_ITEM *wineItem, *prevItem; 1057 1058 //TRACE("\n"); 1192 RECT rect; 1193 TREEVIEW_ITEM *item; 1194 INT iItem,indent; 1195 INT visIndent = -1; 1196 1197 TREEVIEW_UnqueueRefresh(hwnd,TRUE,FALSE); 1059 1198 1060 1199 GetClientRect (hwnd, &rect); 1061 if ((rect.left-rect.right ==0) || (rect.top-rect.bottom==0)) return; 1062 1063 infoPtr->cdmode=TREEVIEW_SendCustomDrawNotify 1064 (hwnd, CDDS_PREPAINT, hdc, rect); 1065 1066 if (infoPtr->cdmode==CDRF_SKIPDEFAULT) return; 1067 1068 infoPtr->uVisibleHeight= rect.bottom-rect.top; 1069 infoPtr->uVisibleWidth= rect.right-rect.left; 1070 1071 view = updateRect ? *updateRect:rect; 1072 view.left = 0; 1073 view.right = rect.right; 1074 OffsetRect(&view,infoPtr->cx,infoPtr->cy); 1200 if ((rect.left == rect.right) || (rect.top == rect.bottom)) return; 1201 1202 infoPtr->cdmode = TREEVIEW_SendCustomDrawNotify(hwnd, CDDS_PREPAINT, hdc, rect); 1203 1204 if (infoPtr->cdmode == CDRF_SKIPDEFAULT) return; 1075 1205 1076 1206 /* draw background */ … … 1080 1210 DeleteObject(hbrBk); 1081 1211 1082 iItem=(INT)infoPtr->TopRootItem; 1083 infoPtr->firstVisible=0; 1084 wineItem=NULL; 1085 indent=0; 1086 x=y=0; 1087 1088 while (iItem) { 1089 prevItem=wineItem; 1090 wineItem= & infoPtr->items[iItem]; 1091 wineItem->iLevel=indent; 1092 1093 ImageList_GetIconSize (infoPtr->himlNormal, &cx, &itemHeight); 1094 if (infoPtr->uItemHeight>itemHeight) 1095 itemHeight=infoPtr->uItemHeight; 1096 1097 GetTextMetricsA (hdc, &tm); 1098 if ((tm.tmHeight + tm.tmExternalLeading) > itemHeight) 1099 itemHeight=tm.tmHeight + tm.tmExternalLeading; 1100 1101 infoPtr->uRealItemHeight=itemHeight; 1102 1103 height=itemHeight * wineItem->iIntegral +1; 1104 if ((((y >= view.top) && (y <= view.bottom)) || ((y+height >= view.top) && (y+height <= view.bottom))) && 1105 (x >= view.left) && (x <= view.right)) 1106 { 1107 wineItem->visible = TRUE; 1108 wineItem->rect.top = y - infoPtr->cy + rect.top; 1109 wineItem->rect.bottom = wineItem->rect.top + height ; 1110 wineItem->rect.left = x - infoPtr->cx + rect.left; 1111 wineItem->rect.right = rect.right; 1112 if (!infoPtr->firstVisible) 1113 infoPtr->firstVisible=wineItem->hItem; 1114 TREEVIEW_DrawItem (hwnd, hdc, wineItem); 1115 } 1116 else { 1117 wineItem->visible = FALSE; 1118 wineItem->rect.left = wineItem->rect.top = 0; 1119 wineItem->rect.right= wineItem->rect.bottom = 0; 1120 wineItem->text.left = wineItem->text.top = 0; 1121 wineItem->text.right= wineItem->text.bottom = 0; 1122 } 1123 1124 /* look up next item */ 1125 1126 if ((wineItem->firstChild) && (wineItem->state & TVIS_EXPANDED)) { 1127 iItem=(INT)wineItem->firstChild; 1128 indent++; 1129 x+=infoPtr->uIndent; 1130 if (x>infoPtr->uTotalWidth) 1131 infoPtr->uTotalWidth=x; 1132 } 1133 else { 1134 iItem=(INT)wineItem->sibling; 1135 while ((!iItem) && (indent>0)) { 1136 indent--; 1137 x-=infoPtr->uIndent; 1138 prevItem=wineItem; 1139 wineItem=&infoPtr->items[(INT)wineItem->parent]; 1140 iItem=(INT)wineItem->sibling; 1141 } 1142 } 1143 y +=height; 1144 } /* while */ 1145 1146 /* FIXME: infoPtr->uTotalWidth should also take item label into account */ 1147 /* FIXME: or should query item sizes (ie check CDRF_NEWFONT) */ 1148 1149 infoPtr->uTotalHeight=y; 1150 if (y >= (view.bottom-view.top)) { 1151 if (!(infoPtr->uInternalStatus & TV_VSCROLL)) 1152 ShowScrollBar (hwnd, SB_VERT, TRUE); 1153 infoPtr->uInternalStatus |=TV_VSCROLL; 1154 SetScrollRange (hwnd, SB_VERT, 0, 1155 y - infoPtr->uVisibleHeight, FALSE); 1156 SetScrollPos (hwnd, SB_VERT, infoPtr->cy, TRUE); 1212 //draw items 1213 1214 iItem = (INT)infoPtr->TopRootItem; 1215 indent = 0; 1216 1217 while (iItem) 1218 { 1219 item = &infoPtr->items[iItem]; 1220 /* FIXME: should query item sizes (ie check CDRF_NEWFONT) */ 1221 if (item->visible) 1222 { 1223 if (updateRect && IntersectRect(NULL,&item->rect,updateRect)) TREEVIEW_DrawItem(hwnd,hdc,item); 1224 visIndent = indent; 1225 } else if (visIndent != -1) 1226 { 1227 //draw vertical connections 1228 1229 if (visIndent == 0) break; 1230 1231 if (indent < visIndent) 1232 { 1233 //CB: todo 1234 visIndent = indent; 1157 1235 } 1158 else { 1159 if (infoPtr->uInternalStatus & TV_VSCROLL) 1160 ShowScrollBar (hwnd, SB_VERT, FALSE); 1161 infoPtr->uInternalStatus &= ~TV_VSCROLL; 1236 } 1237 if ((item->firstChild) && (item->state & TVIS_EXPANDED)) 1238 { 1239 iItem = (INT)item->firstChild; 1240 indent++; 1241 } else 1242 { 1243 iItem = (INT)item->sibling; 1244 while ((!iItem) && (indent > 0)) 1245 { 1246 item = &infoPtr->items[(INT)item->parent]; 1247 iItem = (INT)item->sibling; 1248 indent--; 1162 1249 } 1163 1164 1165 if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT) 1166 infoPtr->cdmode=TREEVIEW_SendCustomDrawNotify 1167 (hwnd, CDDS_POSTPAINT, hdc, rect); 1168 1169 //TRACE("done\n"); 1250 } 1251 } 1252 1253 if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT) 1254 infoPtr->cdmode = TREEVIEW_SendCustomDrawNotify(hwnd, CDDS_POSTPAINT, hdc, rect); 1255 } 1256 1257 static LRESULT TREEVIEW_SetRedraw(HWND hwnd,WPARAM wParam,LPARAM lParam) 1258 { 1259 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 1260 1261 if (wParam) 1262 { 1263 if (!(infoPtr->uInternalStatus & TV_NOREDRAW)) return 0; 1264 infoPtr->uInternalStatus &= ~TV_NOREDRAW; 1265 TREEVIEW_CalcItems(hwnd,0,infoPtr); 1266 TREEVIEW_Refresh(hwnd); 1267 } else 1268 { 1269 infoPtr->uInternalStatus |= TV_NOREDRAW; 1270 } 1271 1272 return 0; 1170 1273 } 1171 1274 … … 1179 1282 1180 1283 switch (wParam) { 1284 case TV_REFRESH_TIMER: 1285 KillTimer (hwnd, TV_REFRESH_TIMER); 1286 infoPtr->Timer &= ~TV_REFRESH_TIMER_SET; 1287 TREEVIEW_CalcItems(hwnd,0,infoPtr); 1288 TREEVIEW_Refresh(hwnd); 1289 return 0; 1290 1181 1291 case TV_EDIT_TIMER: 1182 1292 KillTimer (hwnd, TV_EDIT_TIMER); … … 1189 1299 1190 1300 return 1; 1301 } 1302 1303 static void TREEVIEW_QueueRefresh(HWND hwnd) 1304 1305 { 1306 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 1307 1308 if (infoPtr->Timer & TV_REFRESH_TIMER_SET) 1309 KillTimer (hwnd, TV_REFRESH_TIMER); 1310 1311 if (infoPtr->uInternalStatus & TV_NOREDRAW) 1312 { 1313 infoPtr->Timer &= ~TV_REFRESH_TIMER_SET; 1314 1315 return; 1316 } 1317 1318 SetTimer (hwnd, TV_REFRESH_TIMER, TV_REFRESH_DELAY, 0); 1319 infoPtr->Timer |= TV_REFRESH_TIMER_SET; 1320 } 1321 1322 static void TREEVIEW_UnqueueRefresh(HWND hwnd,BOOL calc,BOOL refresh) 1323 { 1324 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 1325 1326 if (infoPtr->Timer & TV_REFRESH_TIMER_SET) 1327 { 1328 KillTimer (hwnd, TV_REFRESH_TIMER); 1329 infoPtr->Timer &= ~TV_REFRESH_TIMER_SET; 1330 if (calc) TREEVIEW_CalcItems(hwnd,0,infoPtr); 1331 if (refresh) TREEVIEW_Refresh(hwnd); 1332 } 1191 1333 } 1192 1334 … … 1275 1417 case TVGN_CARET:retval=(INT)infoPtr->selectedItem; 1276 1418 break; 1277 case TVGN_FIRSTVISIBLE: /* FIXME:we should only recalculate, not redraw */ 1278 //CB: todo: remove 1279 TREEVIEW_Refresh(hwnd); 1280 retval=(INT)infoPtr->firstVisible; 1419 case TVGN_FIRSTVISIBLE: 1420 TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE); 1421 retval = (INT)infoPtr->firstVisible; 1281 1422 break; 1282 1423 case TVGN_DROPHILITE: … … 1914 2055 wineItem->expandBox.right = 0; 1915 2056 wineItem->expandBox.bottom = 0; 2057 wineItem->calculated = FALSE; 1916 2058 1917 2059 if (tvItem->mask & TVIF_IMAGE) … … 1935 2077 } 1936 2078 1937 //CB: todo: calc 1938 TREEVIEW_Refresh(hwnd); 2079 TREEVIEW_QueueRefresh(hwnd); 1939 2080 1940 2081 return (LRESULT) iItem; … … 2012 2153 } 2013 2154 2014 //CB: todo: calc 2015 TREEVIEW_Refresh(hwnd); 2155 TREEVIEW_QueueRefresh(hwnd); 2016 2156 2017 2157 return TRUE; … … 2184 2324 if (wParam == SIZE_RESTORED) 2185 2325 { 2186 infoPtr->uTotalWidth = LOWORD (lParam); 2187 infoPtr->uTotalHeight = HIWORD (lParam); 2188 } else { 2189 // FIXME (treeview,"WM_SIZE flag %x %lx not handled\n", wParam, lParam); 2190 } 2191 2192 //CB: todo: calc 2193 TREEVIEW_Refresh(hwnd); 2326 TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE); 2327 TREEVIEW_CalcItems(hwnd,0,infoPtr); 2328 TREEVIEW_Refresh(hwnd); 2329 } 2330 2194 2331 return 0; 2195 2332 } … … 2199 2336 TREEVIEW_StyleChanged (HWND hwnd, WPARAM wParam, LPARAM lParam) 2200 2337 { 2201 //TRACE("(%x %lx)\n",wParam,lParam); 2202 //CB: todo: calc 2203 TREEVIEW_Refresh (hwnd); 2338 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 2339 2340 //CB: todo: check styles 2341 infoPtr->uInternalStatus |= TV_CALCALL; 2342 TREEVIEW_QueueRefresh(hwnd); 2204 2343 2205 2344 return 0; … … 2340 2479 TREEVIEW_RemoveTree (hwnd); 2341 2480 SetWindowLongA( hwnd, 0, (DWORD)NULL); 2342 2481 if (infoPtr->Timer & TV_REFRESH_TIMER_SET) 2482 KillTimer (hwnd, TV_REFRESH_TIMER); 2343 2483 if (infoPtr->hwndToolTip) 2344 2484 DestroyWindow (infoPtr->hwndToolTip); 2345 2485 2346 2486 COMCTL32_Free (infoPtr); … … 2678 2818 2679 2819 if (wineItem->cChildren==I_CHILDRENCALLBACK) { 2680 //FIXME (treeview,"we don't handle I_CHILDRENCALLBACK yet\n");2820 //FIXME (treeview,"we don't handle I_CHILDRENCALLBACK yet\n"); 2681 2821 return 0; 2682 2822 } … … 2693 2833 { 2694 2834 case TVE_COLLAPSERESET: 2695 // TRACE(treeview, " case TVE_COLLAPSERESET\n");2696 2835 if (!wineItem->state & TVIS_EXPANDED) 2697 2836 return 0; … … 2702 2841 2703 2842 case TVE_COLLAPSE: 2704 // TRACE(treeview, " case TVE_COLLAPSE\n");2705 2843 if (!wineItem->state & TVIS_EXPANDED) 2706 2844 return 0; … … 2710 2848 2711 2849 case TVE_EXPAND: 2712 // TRACE(treeview, " case TVE_EXPAND\n");2713 2850 if (wineItem->state & TVIS_EXPANDED) 2714 2851 return 0; 2715 2852 2716 // TRACE(treeview, " is not expanded...\n");2717 2718 2853 if (!(wineItem->state & TVIS_EXPANDEDONCE)) 2719 2854 { 2720 //TRACE(treeview, " and has never been expanded...\n");2855 //TRACE(treeview, " and has never been expanded...\n"); 2721 2856 wineItem->state |= TVIS_EXPANDED; 2722 2857 … … 2729 2864 (HTREEITEM)expand)) 2730 2865 { 2731 //TRACE(treeview, " TVN_ITEMEXPANDING returned TRUE, exiting...\n");2866 //TRACE(treeview, " TVN_ITEMEXPANDING returned TRUE, exiting...\n"); 2732 2867 return FALSE; 2733 2868 } … … 2744 2879 if (! wineItem) 2745 2880 { 2746 //ERR(treeview,2747 //"Catastropic situation, cannot retreive item #%d\n",2748 //expand);2881 //ERR(treeview, 2882 // "Catastropic situation, cannot retreive item #%d\n", 2883 // expand); 2749 2884 return FALSE; 2750 2885 } 2751 2886 2752 2887 wineItem->state |= TVIS_EXPANDEDONCE; 2753 //TRACE(treeview, " TVN_ITEMEXPANDING sent...\n");2888 //TRACE(treeview, " TVN_ITEMEXPANDING sent...\n"); 2754 2889 2755 2890 TREEVIEW_SendTreeviewNotify ( … … 2760 2895 (HTREEITEM)expand); 2761 2896 2762 //TRACE(treeview, " TVN_ITEMEXPANDED sent...\n");2897 //TRACE(treeview, " TVN_ITEMEXPANDED sent...\n"); 2763 2898 2764 2899 } … … 2771 2906 2772 2907 case TVE_EXPANDPARTIAL: 2773 //TRACE(treeview, " case TVE_EXPANDPARTIAL\n");2774 //FIXME (treeview, "TVE_EXPANDPARTIAL not implemented\n");2908 //TRACE(treeview, " case TVE_EXPANDPARTIAL\n"); 2909 //FIXME (treeview, "TVE_EXPANDPARTIAL not implemented\n"); 2775 2910 wineItem->state ^=TVIS_EXPANDED; 2776 2911 wineItem->state |=TVIS_EXPANDEDONCE; … … 2778 2913 } 2779 2914 2780 // TRACE(treeview, "Exiting, Item %d state is now %d...\n", 2781 // expand, 2782 // wineItem->state); 2783 2784 //CB: todo: replace 2915 //TRACE(treeview, "Exiting, Item %d state is now %d...\n", 2916 // expand, 2917 // wineItem->state); 2918 2919 //CB: todo: optimize! 2920 TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE); 2921 TREEVIEW_CalcItems(hwnd,0,infoPtr); 2785 2922 TREEVIEW_Refresh(hwnd); 2923 2786 2924 return TRUE; 2787 2925 } … … 3225 3363 */ 3226 3364 TREEVIEW_ITEM *parentItem = TREEVIEW_ValidItem (infoPtr, wineItem->parent); 3227 if ( !(parentItem->state & TVIS_EXPANDED)) 3365 3366 if (!(parentItem->state & TVIS_EXPANDED)) 3228 3367 TREEVIEW_Expand (hwnd, TVE_EXPAND, (LPARAM) wineItem->parent); 3229 3368 } … … 3255 3394 infoPtr->selectedItem=(HTREEITEM)newSelect; 3256 3395 3396 TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE); 3257 3397 TREEVIEW_RefreshItem(hwnd,prevItem); 3258 3398 TREEVIEW_RefreshItem(hwnd,wineItem); … … 3278 3418 wineItem->state |=TVIS_DROPHILITED; 3279 3419 3420 TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE); 3280 3421 TREEVIEW_RefreshItem(hwnd,prevItem); 3281 3422 TREEVIEW_RefreshItem(hwnd,wineItem); … … 3317 3458 3318 3459 { 3319 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 3320 TEXTMETRICA tm; 3321 LOGFONTA logFont; 3322 HFONT hFont, hOldFont; 3323 INT height; 3324 HDC hdc; 3325 3326 // TRACE (treeview,"%x %lx\n",wParam, lParam); 3327 3328 infoPtr->hFont = (HFONT)wParam; 3329 3330 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT); 3331 3332 GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont); 3333 logFont.lfWeight=FW_BOLD; 3334 infoPtr->hBoldFont = CreateFontIndirectA (&logFont); 3335 3336 hdc = GetDC (0); 3337 hOldFont = SelectObject (hdc, hFont); 3338 GetTextMetricsA (hdc, &tm); 3339 height= tm.tmHeight + tm.tmExternalLeading; 3340 if (height>infoPtr->uRealItemHeight) 3341 infoPtr->uRealItemHeight=height; 3342 SelectObject (hdc, hOldFont); 3343 ReleaseDC (0, hdc); 3344 3345 //CB: todo: calc 3346 if (lParam) 3347 TREEVIEW_Refresh(hwnd); 3348 3349 return 0; 3350 } 3351 3460 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 3461 TEXTMETRICA tm; 3462 LOGFONTA logFont; 3463 HFONT hFont, hOldFont; 3464 INT height; 3465 HDC hdc; 3466 3467 infoPtr->hFont = (HFONT)wParam; 3468 3469 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT); 3470 3471 GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont); 3472 logFont.lfWeight=FW_BOLD; 3473 infoPtr->hBoldFont = CreateFontIndirectA (&logFont); 3474 3475 hdc = GetDC (0); 3476 hOldFont = SelectObject (hdc, hFont); 3477 GetTextMetricsA (hdc, &tm); 3478 height= tm.tmHeight + tm.tmExternalLeading; 3479 if (height>infoPtr->uRealItemHeight) 3480 infoPtr->uRealItemHeight=height; 3481 SelectObject (hdc, hOldFont); 3482 ReleaseDC (0, hdc); 3483 3484 if (lParam) 3485 { 3486 TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE); 3487 infoPtr->uInternalStatus |= TV_CALCALL; 3488 TREEVIEW_CalcItems(hwnd,0,infoPtr); 3489 TREEVIEW_Refresh(hwnd); 3490 } 3491 3492 return 0; 3493 } 3352 3494 3353 3495 … … 3394 3536 } 3395 3537 3538 TREEVIEW_CalcItems(hwnd,0,infoPtr); 3396 3539 ScrollWindowEx(hwnd,0,lastPos-infoPtr->cy,NULL,NULL,0,NULL,SW_INVALIDATE); 3397 3540 … … 3404 3547 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 3405 3548 int maxWidth; 3549 int lastPos = infoPtr->cx; 3406 3550 3407 3551 // TRACE (treeview,"wp %lx, lp %x\n", lParam, wParam); … … 3440 3584 } 3441 3585 3442 TREEVIEW_Refresh(hwnd); 3443 3444 //CB: todo: use ScrollWindowEx 3586 TREEVIEW_CalcItems(hwnd,0,infoPtr); 3587 ScrollWindowEx(hwnd,lastPos-infoPtr->cx,0,NULL,NULL,0,NULL,SW_INVALIDATE); 3445 3588 3446 3589 return TRUE; … … 3642 3785 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 3643 3786 UINT uOldScrollTime = infoPtr->uScrollTime; 3787 3644 3788 infoPtr->uScrollTime = min (uScrollTime, 100); 3789 3645 3790 return uOldScrollTime; 3646 3791 } … … 3854 3999 3855 4000 /* case WM_SYSCOLORCHANGE: */ 3856 /* case WM_SETREDRAW: */ 4001 4002 case WM_SETREDRAW: 4003 return TREEVIEW_SetRedraw(hwnd,wParam,lParam); 3857 4004 3858 4005 case WM_TIMER: … … 3893 4040 3894 4041 ZeroMemory (&wndClass, sizeof(WNDCLASSA)); 3895 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;4042 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS; 3896 4043 wndClass.lpfnWndProc = (WNDPROC)TREEVIEW_WindowProc; 3897 4044 wndClass.cbClsExtra = 0;
Note:
See TracChangeset
for help on using the changeset viewer.