summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/win/disasmwininfo.cpp
blob: 7e8b7b564fb8c9aeddddafaa989b0f99484f2e31 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// license:BSD-3-Clause
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
//  disasmwininfo.c - Win32 debug window handling
//
//============================================================

#include "emu.h"
#include "disasmwininfo.h"

#include "debugviewinfo.h"
#include "disasmviewinfo.h"
#include "uimetrics.h"

#include "util/xmlfile.h"

#include "winutf8.h"


disasmwin_info::disasmwin_info(debugger_windows_interface &debugger) :
	disasmbasewin_info(debugger, false, "Disassembly", nullptr),
	m_combownd(nullptr)
{
	if ((window() == nullptr) || (m_views[0] == nullptr))
		return;

	// set up the view to track the initial expression
	set_edit_defstr("curpc");
	set_editwnd_text("curpc");
	editwnd_select_all();

	// create a combo box
	m_combownd = m_views[0]->create_source_combobox(window(), (LONG_PTR)this);

	// set the caption
	update_caption();

	// recompute the children once to get the maxwidth
	disasmwin_info::recompute_children();

	// position the window and recompute children again
	SetWindowPos(window(), HWND_TOP, 100, 100, maxwidth(), 200, SWP_SHOWWINDOW);
	disasmwin_info::recompute_children();

	// mark the edit box as the default focus and set it
	editwin_info::set_default_focus();
}


disasmwin_info::~disasmwin_info()
{
}


void disasmwin_info::recompute_children()
{
	// compute a client rect
	RECT bounds;
	bounds.top = bounds.left = 0;
	bounds.right = m_views[0]->prefwidth() + (2 * EDGE_WIDTH);
	bounds.bottom = 200;
	AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);

	// clamp the min/max size
	set_maxwidth(bounds.right - bounds.left);

	// get the parent's dimensions
	RECT parent;
	GetClientRect(window(), &parent);

	// edit box gets half of the width
	RECT editrect;
	editrect.top = parent.top + EDGE_WIDTH;
	editrect.bottom = editrect.top + metrics().debug_font_height() + 4;
	editrect.left = parent.left + EDGE_WIDTH;
	editrect.right = parent.left + ((parent.right - parent.left) / 2) - EDGE_WIDTH;

	// combo box gets the other half of the width
	RECT comborect;
	comborect.top = editrect.top;
	comborect.bottom = editrect.bottom;
	comborect.left = editrect.right + (2 * EDGE_WIDTH);
	comborect.right = parent.right - EDGE_WIDTH;

	// disasm view gets the rest
	RECT dasmrect;
	dasmrect.top = editrect.bottom + (2 * EDGE_WIDTH);
	dasmrect.bottom = parent.bottom - EDGE_WIDTH;
	dasmrect.left = parent.left + EDGE_WIDTH;
	dasmrect.right = parent.right - EDGE_WIDTH;

	// set the bounds of things
	m_views[0]->set_bounds(dasmrect);
	set_editwnd_bounds(editrect);
	smart_set_window_bounds(m_combownd, window(), comborect);
}


bool disasmwin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
	switch (HIWORD(wparam))
	{
	// combo box selection changed
	case CBN_SELCHANGE:
		{
			int const sel = SendMessage((HWND)lparam, CB_GETCURSEL, 0, 0);
			if (sel != CB_ERR)
			{
				m_views[0]->set_source_index(sel);
				update_caption();

				// reset the focus
				set_default_focus();
				return true;
			}
			break;
		}
	}
	return disasmbasewin_info::handle_command(wparam, lparam);
}


void disasmwin_info::draw_contents(HDC dc)
{
	disasmbasewin_info::draw_contents(dc);
	if (m_combownd)
		draw_border(dc, m_combownd);
}


void disasmwin_info::process_string(const std::string &string)
{
	// set the string to the disasm view
	downcast<disasmview_info *>(m_views[0].get())->set_expression(string);

	// select everything in the edit text box
	editwnd_select_all();

	// update the default string to match
	set_edit_defstr(string);
}


void disasmwin_info::update_caption()
{
	win_set_window_text_utf8(window(), std::string("Disassembly: ").append(m_views[0]->source_name()).c_str());
}


void disasmwin_info::restore_configuration_from_node(util::xml::data_node const &node)
{
	m_views[0]->set_source_index(node.get_attribute_int(osd::debugger::ATTR_WINDOW_DISASSEMBLY_CPU, m_views[0]->source_index()));
	int const cursource = m_views[0]->source_index();
	if (0 <= cursource)
		SendMessage(m_combownd, CB_SETCURSEL, cursource, 0);
	update_caption();

	util::xml::data_node const *const expr = node.get_child(osd::debugger::NODE_WINDOW_EXPRESSION);
	if (expr && expr->get_value())
	{
		set_editwnd_text(expr->get_value());
		process_string(expr->get_value());
	}

	disasmbasewin_info::restore_configuration_from_node(node);
}


void disasmwin_info::save_configuration_to_node(util::xml::data_node &node)
{
	disasmbasewin_info::save_configuration_to_node(node);

	node.set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_DISASSEMBLY_VIEWER);
	node.set_attribute_int(osd::debugger::ATTR_WINDOW_DISASSEMBLY_CPU, m_views[0]->source_index());
	node.add_child(osd::debugger::NODE_WINDOW_EXPRESSION, downcast<disasmview_info *>(m_views[0].get())->expression());
}