📄 bar.c
字号:
/****************************** Module Header *******************************
* Module Name: BAR.C
*
* This module contains functions for bar window
* graphically showing two lists of sections and showing
* colored vertical bars for the sections of text,
* with linking lines for the sections that are the same.
*
* Functions:
*
* BarWndProc()
* BarPaint()
* DrawSection()
* DrawLink()
* BarClick()
* InitBarClass()
* BarDrawPosition()
*
* Comments:
*
****************************************************************************/
#include <windows.h>
#include <commdlg.h>
#include "gutils.h"
#include "table.h"
#include "state.h"
#include "wdiffrc.h"
#include "windiff.h"
#include "list.h"
#include "line.h"
#include "scandir.h"
#include "file.h"
#include "section.h"
#include "compitem.h"
#include "complist.h"
#include "view.h"
long APIENTRY BarWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam);
void BarPaint(HWND hwnd);
void DrawSection(HDC hdc, int cx, int cy, int lines, SECTION sec, int sidecode);
void DrawLink(HDC hdc, int cx, int cy, int lines, SECTION sec);
void BarClick(HWND hwnd, int x, int y);
HPEN hpenSame, hpenLeft, hpenRight;
HBRUSH hbrSame, hbrLeft, hbrRight;
HBRUSH hbrSideBar;
/***************************************************************************
* Function: InitBarClass
*
* Purpose:
*
* Create bar window class
*/
BOOL
InitBarClass(HINSTANCE hInstance)
{
WNDCLASS wc;
BOOL resp;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = BarWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszClassName = "BarClass";
wc.lpszMenuName = NULL;
resp = RegisterClass(&wc);
return(resp);
}
/***************************************************************************
* Function: BarWndProc
*
* Purpose:
*
* Window procedure supporting bar window
*
*/
long APIENTRY
BarWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam)
{
switch(message) {
case WM_CREATE:
hpenSame = CreatePen(PS_SOLID, 1, RGB(0,0,0));
hbrSame = CreateSolidBrush(RGB(255,255,255));
hpenLeft = CreatePen(PS_SOLID, 1, rgb_barleft);
hbrLeft = CreateSolidBrush(rgb_barleft);
hpenRight = CreatePen(PS_SOLID, 1, rgb_barright);
hbrRight = CreateSolidBrush(rgb_barright);
hbrSideBar = CreateSolidBrush(rgb_barcurrent);
break;
case WM_DESTROY:
DeleteObject(hpenSame);
DeleteObject(hpenLeft);
DeleteObject(hpenRight);
DeleteObject(hbrSame);
DeleteObject(hbrLeft);
DeleteObject(hbrRight);
DeleteObject(hbrSideBar);
break;
case WM_PAINT:
BarPaint(hWnd);
break;
case WM_LBUTTONDOWN:
BarClick(hWnd, LOWORD(lParam), HIWORD(lParam));
break;
default:
return(DefWindowProc(hWnd, message, wParam, lParam));
}
return 0;
}
/***************************************************************************
* Function: BarDrawPosition
*
* Purpose:
*
* Draw the current position as side-bars down the bar window,
* showing which lines from each file are currently in view. HDC can be
* NULL (we get one ourselves if so). If bErase is true, we clear
* the previous side-bars first.
*
* This is called from BarPaint when we paint the whole window, and
* from TableServer() whenever it receives a TQ_SCROLL notification that
* the table window has been scrolled.
*/
void
BarDrawPosition(HWND hwndBar, HDC hdcIn, BOOL bErase)
{
HDC hdc;
int total_lines, cy, cx;
RECT rc, rcLeft, rcRight;
VIEW view;
COMPITEM item;
LIST listleft, listright;
long toprow, endrow, i;
int left_first, left_last, right_first, right_last, linenr;
/* get a hdc if we weren't given one */
if (hdcIn == NULL) {
hdc = GetDC(hwndBar);
} else {
hdc = hdcIn;
}
/* set horz position of bars */
GetClientRect(hwndBar, &rc);
cx = (int)(rc.right - rc.left);
cy = (int)(rc.bottom - rc.top);
/* layout constants are defined as percentages of window width */
rcLeft.left = cx * L_POS_START / 100;
rcRight.left = cx * R_POS_START / 100;
rcLeft.right = rcLeft.left + (cx * L_POS_WIDTH / 100);
rcRight.right = rcRight.left + (cx * R_POS_WIDTH / 100);
/* erase the whole marker section if requested */
if (bErase) {
rcLeft.top = rc.top;
rcLeft.bottom = rc.bottom;
rcRight.top = rc.top;
rcRight.bottom = rc.bottom;
FillRect(hdc, &rcLeft, GetStockObject(WHITE_BRUSH));
FillRect(hdc, &rcRight, GetStockObject(WHITE_BRUSH));
}
/*
* calculate the vertical scaling - depends on the
* total number of lines shown
*/
/* 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) {
/* get rid of the dc if we made it ourselves */
if (hdcIn == NULL) {
ReleaseDC(hwndBar, hdc);
}
return;
}
item = view_getitem(view, 0);
listleft = compitem_getleftsections(item);
listright = compitem_getrightsections(item);
/* if there is only one list of sections, draw nothing. The
* picture for a single file is not very exciting.
*/
if ((listleft == NULL) || (listright == NULL)) {
/* get rid of the dc if we made it ourselves */
if (hdcIn == NULL) {
ReleaseDC(hwndBar, hdc);
}
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 = line_getlinenr(section_getlastline(List_Last(listleft)));
total_lines = max(total_lines,
(int) line_getlinenr(section_getlastline(List_Last(listright))));
/* get the current top row and nr of rows visible */
toprow = SendMessage(hwndRCD, TM_TOPROW, FALSE, 0);
endrow = SendMessage(hwndRCD, TM_ENDROW, FALSE, 0);
endrow = min(endrow, view_getrowcount(view)-1);
/*
* find the first and last line nrs from each file currently visible.
*
*/
left_first = left_last = right_first = right_last = 0;
for (i = toprow; i <= endrow; i++) {
linenr = view_getlinenr_left(view, i);
if (linenr > 0) {
if (left_first == 0) {
left_first = linenr;
}
left_first = min(left_first, linenr);
left_last = max(left_last, linenr);
}
linenr = view_getlinenr_right(view, i);
if (linenr > 0) {
if (right_first == 0) {
right_first = linenr;
}
right_first = min(right_first, linenr);
right_last = max(right_last, linenr);
}
}
/* draw the two markers as thick bars -> elongated rectangles */
rcLeft.top = MulDiv(left_first-1, cy, total_lines);
rcLeft.bottom = MulDiv(left_last, cy, total_lines);
FillRect(hdc, &rcLeft, hbrSideBar);
rcRight.top = MulDiv(right_first-1, cy, total_lines);
rcRight.bottom = MulDiv(right_last, cy, total_lines);
FillRect(hdc, &rcRight, hbrSideBar);
/* get rid of the dc if we made it ourselves */
if (hdcIn == NULL) {
ReleaseDC(hwndBar, hdc);
}
}
/***************************************************************************
* Function: BarPaint
*
* Purpose:
*
* Paint the bar window
*/
void
BarPaint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc;
VIEW view;
COMPITEM item;
LIST listleft, listright;
SECTION sec;
int total_lines, cx, cy;
RECT rc;
hdc = BeginPaint(hwnd, &ps);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -