by roundabout, Sunday, 18 January 2026, 12:37:11 (1768739831), pushed by roundabout, Sunday, 18 January 2026, 12:37:29 (1768739849)
Author identity: vlad <vlad.muntoiu@gmail.com>
030ad92f3bab2ffcb6bb740bd74408d067e0bb2b
main.cc
@@ -76,6 +76,23 @@ std::vector<std::pair<int, int>> parse_size_list(std::string const &sizes) {
return result;
}
std::vector<int> parse_tuple(std::string const &value) {
std::vector<int> result;
std::stringstream str(value);
if(str.get() != '(') {
return result; // which is currently empty
}
while(str.peek() != ')') {
int a;
str >> a;
if(str.peek() == ',') {
str.get();
}
result.push_back(a);
}
return result;
}
class AndroCamera : public Glib::Object {
private:
int camera_id;
@@ -158,6 +175,7 @@ public:
std::unordered_map<std::string, std::string> parameters;
DroidMediaCameraInfo physical_info;
std::vector<std::pair<int, int>> picture_sizes, preview_sizes, video_sizes;
std::vector<int> active_array;
explicit AndroCamera(int camera_id) : Glib::Object(), camera_id(camera_id) {}
@@ -190,6 +208,7 @@ public:
picture_sizes = parse_size_list(parameters.at("picture-size-values"));
video_sizes = parse_size_list(parameters.at("video-size-values"));
preview_sizes = parse_size_list(parameters.at("preview-size-values"));
active_array = parse_tuple(parameters.at("active-array-size"));
}
void disconnect() {
@@ -219,6 +238,7 @@ class PanoramaCamera : public Gtk::Application {
Glib::RefPtr<Gtk::CssProvider> css;
Glib::RefPtr<Gdk::Surface> window_surface;
Glib::RefPtr<Gtk::GestureClick> clicker;
sigc::connection compressed_image_connection, frame_available_connection, accelerometer_connection;
@@ -382,6 +402,7 @@ public:
parameters["sensitivity"] = "100";
parameters["exposure-time"] = "83200";
parameters["flash-mode"] = "off";
parameters["focus-mode"] = "auto";
droid_media_camera_set_parameters(
cam->camera,
@@ -523,6 +544,34 @@ public:
droid_media_camera_take_picture(cam->camera, 0);
});
box->append(*capture_button);
clicker = Gtk::GestureClick::create();
clicker->signal_released().connect([this](int n_presses, double x, double y) {
// TODO: handle differing aspect ratios
int actual_orientation = (cam->physical_info.orientation + device_rotation_degrees) % 360;
int focus_x, focus_y;
if(actual_orientation == 0) {
focus_x = x / drawing->get_width() * (cam->active_array.at(2) - cam->active_array.at(0)) + cam->active_array.at(0);
focus_y = y / drawing->get_height() * (cam->active_array.at(3) - cam->active_array.at(1)) + cam->active_array.at(1);
} else if(actual_orientation == 90) {
focus_x = y / drawing->get_height() * (cam->active_array.at(2) - cam->active_array.at(0)) + cam->active_array.at(0);
focus_y = (1 - x / drawing->get_width()) * (cam->active_array.at(3) - cam->active_array.at(1)) + cam->active_array.at(1);
} else if(actual_orientation == 180) {
focus_x = (1 - x / drawing->get_width()) * (cam->active_array.at(2) - cam->active_array.at(0)) + cam->active_array.at(0);
focus_y = (1 - y / drawing->get_height()) * (cam->active_array.at(3) - cam->active_array.at(1)) + cam->active_array.at(1);
} else if(actual_orientation == 270) {
focus_x = (1 - y / drawing->get_height()) * (cam->active_array.at(2) - cam->active_array.at(0)) + cam->active_array.at(0);
focus_y = x / drawing->get_width() * (cam->active_array.at(3) - cam->active_array.at(1)) + cam->active_array.at(1);
}
int focus_area_size = (cam->active_array.at(3) - cam->active_array.at(1) + cam->active_array.at(2) - cam->active_array.at(0)) / 128;
std::ostringstream str;
str.imbue(std::locale::classic());
str << '(' << focus_x - focus_area_size << ',' << focus_y - focus_area_size << ',' << focus_x + focus_area_size << ',' << focus_y + focus_area_size << ',' << 1000 << ')';
std::cout << "focus is " << str.str() << '\n';
parameters["focus-areas"] = str.str();
droid_media_camera_set_parameters(cam->camera, write_parameters(parameters).c_str());
std::cout << "AF result: " << droid_media_camera_start_auto_focus(cam->camera) << '\n';
});
drawing->add_controller(clicker);
drawing->set_hexpand(true);
drawing->set_vexpand(true);
window->set_child(*box);