Salome HOME
spns #34338: post build script is not embedded in archive
[tools/sat.git] / src / colorama / winterm.py
1 # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
2 from . import win32
3
4
5 # from wincon.h
6 class WinColor(object):
7     BLACK   = 0
8     BLUE    = 1
9     GREEN   = 2
10     CYAN    = 3
11     RED     = 4
12     MAGENTA = 5
13     YELLOW  = 6
14     GREY    = 7
15
16 # from wincon.h
17 class WinStyle(object):
18     NORMAL              = 0x00 # dim text, dim background
19     BRIGHT              = 0x08 # bright text, dim background
20     BRIGHT_BACKGROUND   = 0x80 # dim text, bright background
21
22 class WinTerm(object):
23
24     def __init__(self):
25         self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes
26         self.set_attrs(self._default)
27         self._default_fore = self._fore
28         self._default_back = self._back
29         self._default_style = self._style
30         # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style.
31         # So that LIGHT_EX colors and BRIGHT style do not clobber each other,
32         # we track them separately, since LIGHT_EX is overwritten by Fore/Back
33         # and BRIGHT is overwritten by Style codes.
34         self._light = 0
35
36     def get_attrs(self):
37         return self._fore + self._back * 16 + (self._style | self._light)
38
39     def set_attrs(self, value):
40         self._fore = value & 7
41         self._back = (value >> 4) & 7
42         self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND)
43
44     def reset_all(self, on_stderr=None):
45         self.set_attrs(self._default)
46         self.set_console(attrs=self._default)
47
48     def fore(self, fore=None, light=False, on_stderr=False):
49         if fore is None:
50             fore = self._default_fore
51         self._fore = fore
52         # Emulate LIGHT_EX with BRIGHT Style
53         if light:
54             self._light |= WinStyle.BRIGHT
55         else:
56             self._light &= ~WinStyle.BRIGHT
57         self.set_console(on_stderr=on_stderr)
58
59     def back(self, back=None, light=False, on_stderr=False):
60         if back is None:
61             back = self._default_back
62         self._back = back
63         # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style
64         if light:
65             self._light |= WinStyle.BRIGHT_BACKGROUND
66         else:
67             self._light &= ~WinStyle.BRIGHT_BACKGROUND
68         self.set_console(on_stderr=on_stderr)
69
70     def style(self, style=None, on_stderr=False):
71         if style is None:
72             style = self._default_style
73         self._style = style
74         self.set_console(on_stderr=on_stderr)
75
76     def set_console(self, attrs=None, on_stderr=False):
77         if attrs is None:
78             attrs = self.get_attrs()
79         handle = win32.STDOUT
80         if on_stderr:
81             handle = win32.STDERR
82         win32.SetConsoleTextAttribute(handle, attrs)
83
84     def get_position(self, handle):
85         position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition
86         # Because Windows coordinates are 0-based,
87         # and win32.SetConsoleCursorPosition expects 1-based.
88         position.X += 1
89         position.Y += 1
90         return position
91
92     def set_cursor_position(self, position=None, on_stderr=False):
93         if position is None:
94             # I'm not currently tracking the position, so there is no default.
95             # position = self.get_position()
96             return
97         handle = win32.STDOUT
98         if on_stderr:
99             handle = win32.STDERR
100         win32.SetConsoleCursorPosition(handle, position)
101
102     def cursor_adjust(self, x, y, on_stderr=False):
103         handle = win32.STDOUT
104         if on_stderr:
105             handle = win32.STDERR
106         position = self.get_position(handle)
107         adjusted_position = (position.Y + y, position.X + x)
108         win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False)
109
110     def erase_screen(self, mode=0, on_stderr=False):
111         # 0 should clear from the cursor to the end of the screen.
112         # 1 should clear from the cursor to the beginning of the screen.
113         # 2 should clear the entire screen, and move cursor to (1,1)
114         handle = win32.STDOUT
115         if on_stderr:
116             handle = win32.STDERR
117         csbi = win32.GetConsoleScreenBufferInfo(handle)
118         # get the number of character cells in the current buffer
119         cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y
120         # get number of character cells before current cursor position
121         cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X
122         if mode == 0:
123             from_coord = csbi.dwCursorPosition
124             cells_to_erase = cells_in_screen - cells_before_cursor
125         if mode == 1:
126             from_coord = win32.COORD(0, 0)
127             cells_to_erase = cells_before_cursor
128         elif mode == 2:
129             from_coord = win32.COORD(0, 0)
130             cells_to_erase = cells_in_screen
131         # fill the entire screen with blanks
132         win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
133         # now set the buffer's attributes accordingly
134         win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord)
135         if mode == 2:
136             # put the cursor where needed
137             win32.SetConsoleCursorPosition(handle, (1, 1))
138
139     def erase_line(self, mode=0, on_stderr=False):
140         # 0 should clear from the cursor to the end of the line.
141         # 1 should clear from the cursor to the beginning of the line.
142         # 2 should clear the entire line.
143         handle = win32.STDOUT
144         if on_stderr:
145             handle = win32.STDERR
146         csbi = win32.GetConsoleScreenBufferInfo(handle)
147         if mode == 0:
148             from_coord = csbi.dwCursorPosition
149             cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X
150         if mode == 1:
151             from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
152             cells_to_erase = csbi.dwCursorPosition.X
153         elif mode == 2:
154             from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
155             cells_to_erase = csbi.dwSize.X
156         # fill the entire screen with blanks
157         win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
158         # now set the buffer's attributes accordingly
159         win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord)
160
161     def set_title(self, title):
162         win32.SetConsoleTitle(title)