📄 bar.c
字号:
/* draw a separator line at the very edge of the window */
GetClientRect(hwnd, &rc);
MoveToEx(hdc, (int)(rc.right-1), rc.top, NULL);
LineTo(hdc, (int)(rc.right-1), rc.bottom);
/* first gather information about what is to be displayed */
/* find the total lines (for horz. scaling) */
/* get the handles to the two lists of sections */
view = (VIEW) SendMessage(hwndClient, TM_CURRENTVIEW, 0, 0);
/* make sure we are in expand mode */
if (view_isexpanded(view) == FALSE) {
return;
}
item = view_getitem(view, 0);
listleft = compitem_getleftsections(item);
listright = compitem_getrightsections(item);
/*
* don't bother if there is only one list - not very interesting
*/
if ((listleft == NULL) || (listright == NULL)) {
EndPaint(hwnd, &ps);
return;
}
/* take the longest of the two files and use this
* for vertical scaling. the scale is such that the longest file
* *just fits*.
*/
total_lines = (int) line_getlinenr(section_getlastline(List_Last(listleft)));
total_lines = max(total_lines,
(int) line_getlinenr(section_getlastline(List_Last(listright))));
/* horizontal spacing:
*
* there are two columns, for the left and right files, and a gap
* between them criss-crossed by lines marking the links.
*
* Each of the columns then has three sections, for the
* position marker, the different sections
* and the linked sections. The width and positions of these items
* are defined (in windiff.h) as percentages of the window width.
*/
cx = (int)(rc.right - rc.left);
cy = (int)(rc.bottom - rc.top);
/* draw all the left sections and links */
List_TRAVERSE(listleft, sec) {
DrawSection(hdc, cx, cy, total_lines, sec, STATE_LEFTONLY);
if (section_getlink(sec) != NULL) {
DrawLink(hdc, cx, cy, total_lines, sec);
}
}
/* draw all the right sections */
List_TRAVERSE(listright, sec) {
DrawSection(hdc, cx, cy, total_lines, sec, STATE_RIGHTONLY);
}
/* now draw current position markers */
BarDrawPosition(hwnd, hdc, FALSE);
EndPaint(hwnd, &ps);
}
/***************************************************************************
* Function: DrawSection
*
* Purpose:
*
* Paint a single section
*/
void
DrawSection(HDC hdc, int cx, int cy, int lines, SECTION sec, int sidecode)
{
int x1, y1, x2, y2;
HPEN hpenOld;
HBRUSH hbrOld;
/* calculate the vertical position from the scaling. the scaling
* is such that the longest file just fits
*/
y1 = MulDiv(line_getlinenr(section_getfirstline(sec))- 1, cy, lines);
y2 = MulDiv(line_getlinenr(section_getlastline(sec)), cy, lines);
/* left or right - set bar position and width*/
if (sidecode == STATE_LEFTONLY) {
if (section_getlink(sec) != NULL) {
x1 = L_MATCH_START;
x2 = L_MATCH_WIDTH;
} else {
x1 = L_UNMATCH_START;
x2 = L_UNMATCH_WIDTH;
}
} else {
if (section_getlink(sec) != NULL) {
x1 = R_MATCH_START;
x2 = R_MATCH_WIDTH;
} else {
x1 = R_UNMATCH_START;
x2 = R_UNMATCH_WIDTH;
}
}
/* bar position defines are in percentages of the win width (cx) */
x1 = cx * x1 / 100;
x2 = (cx * x2 / 100) + x1;
/* select pens and brushes */
if (section_getlink(sec) != NULL) {
hpenOld = SelectObject(hdc, hpenSame);
hbrOld = SelectObject(hdc, hbrSame);
} else if (sidecode == STATE_LEFTONLY) {
hpenOld = SelectObject(hdc, hpenLeft);
hbrOld = SelectObject(hdc, hbrLeft);
} else {
hpenOld = SelectObject(hdc, hpenRight);
hbrOld = SelectObject(hdc, hbrRight);
}
/* draw the section as a coloured elongated rectangle */
Rectangle(hdc, x1, y1, x2, y2);
/* de-select the pen and brush in favour of the default */
SelectObject(hdc, hpenOld);
SelectObject(hdc, hbrOld);
}
/***************************************************************************
* Function: DrawLink
*
* Purpose:
*
* Draw a line linking two sections. Indicates a section from each
* file that match each other. psec points to the section in the
* left file.
*/
void
DrawLink(HDC hdc, int cx, int cy, int lines, SECTION sec)
{
int x1, y1, x2, y2;
int ybase, yrange;
SECTION other;
other = section_getlink(sec);
/* position the link line halfway down the section
* - allow for the case where
* the section is one line (ie halve the co-ords, not the line nr)
*/
ybase = MulDiv(line_getlinenr(section_getfirstline(sec)) - 1, cy, lines);
yrange = MulDiv(line_getlinenr(section_getlastline(sec)), cy, lines);
y1 = ((yrange - ybase) / 2) + ybase;
ybase = MulDiv(line_getlinenr(section_getfirstline(other)) - 1, cy, lines);
yrange = MulDiv(line_getlinenr(section_getlastline(other)), cy, lines);
y2 = ((yrange - ybase) / 2) + ybase;
/* horizontal layout constants are defined as percentages of the
* window width
*/
x1 = cx * (L_MATCH_START + L_MATCH_WIDTH) / 100;
x2 = cx * R_UNMATCH_START / 100;
MoveToEx(hdc, x1, y1, NULL);
LineTo(hdc, x2, y2);
}
/***************************************************************************
* Function: BarClick
*
* Purpose:
*
* The user has clicked on the bar window. Translate the clicked position into
* a line in one of the files if possible, and scroll the table window to
* show that line.
*/
void
BarClick(HWND hwnd, int x, int y)
{
RECT rc;
int xleft, xright;
int linenr, i, this;
BOOL bIsLeft;
int tot_left, tot_right, total_lines;
LIST listleft, listright;
VIEW view;
COMPITEM item;
TableSelection select;
/* find size of the window to get horz scaling, and see
* where click was
*/
GetClientRect(hwnd, &rc);
/* was it near either of the bars ? */
/* horz positioning is in percentages of window width */
xleft = max(L_UNMATCH_START + L_UNMATCH_WIDTH,
L_MATCH_START + L_MATCH_WIDTH);
xright = min(R_UNMATCH_START, R_MATCH_START);
xleft = xleft * (rc.right - rc.left) / 100;
xright = xright * (rc.right - rc.left) / 100;
if (x < xleft) {
bIsLeft = TRUE;
} else if (x > xright) {
bIsLeft = FALSE;
} else {
/* click was between the two bars - ignore it */
return;
}
/* calculate the vertical scaling (based on total lines displayed)
* so that we can convert the y position into a line nr
*/
/* get the handles to the two lists of sections */
view = (VIEW) SendMessage(hwndClient, TM_CURRENTVIEW, 0, 0);
/* make sure we are in expand mode */
if (view_isexpanded(view) == FALSE) {
return;
}
item = view_getitem(view, 0);
listleft = compitem_getleftsections(item);
listright = compitem_getrightsections(item);
/* ignore the click if only one list of sections, since in
* this case there is nothing drawn for him to click on.
*/
if ((listleft == NULL) || (listright == NULL)) {
return;
}
/* take the longest of the two files and use this
* for vertical scaling. the scale is such that the longest file
* *just fits*.
*/
tot_left = line_getlinenr(section_getlastline(List_Last(listleft)));
tot_right = line_getlinenr(section_getlastline(List_Last(listright)));
total_lines = max(tot_left, tot_right);
/* convert vertical position into a line nr. The vertical scaling
* can be calculated from knowing that the longest list of
* lines just fits in the window.
*/
linenr = (int) (((long) total_lines * y) / (rc.bottom - rc.top)) + 1;
/* check that the line is valid */
if (bIsLeft) {
if (linenr > tot_left) {
return;
}
} else {
if (linenr > tot_right) {
return;
}
}
/* search the current view, looking for a row with this
* line nr on the correct side
*/
for (i = 0; i < view_getrowcount(view); i++) {
if (bIsLeft) {
this = view_getlinenr_left(view,i);
} else {
this = view_getlinenr_right(view,i);
}
if (linenr == this) {
/* found the matching line- select it in the
* table window
*/
select.startrow = i;
select.startcell = 0;
select.nrows = 1;
select.ncells = 1;
SendMessage(hwndRCD, TM_SELECT, 0, (long) (LPSTR)&select);
return;
}
}
windiff_UI(TRUE);
MessageBox(hwndClient, LoadRcString(IDS_LINE_NOT_VISIBLE),
"WinDiff", MB_ICONSTOP|MB_OK);
windiff_UI(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -